Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

динамические библиотеки в JavaScript (Архип)
Author Message
Архип
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sat Jun 27, 2009 8:52 pm (написано за 3 минуты 21 секунду)
   Post subject: динамические библиотеки в JavaScript
Reply with quote

Давайте пообсуждаем целесообразность и скорость как ни странно?
Увидел следующий код:
Code (html): скопировать код в буфер обмена
<HTML> (december.com/html/4/element/html.html)
<SCRIPT (december.com/html/4/element/script.html) language="JavaScript"> (december.com/html/4/element/.html)
var library = "Exporter";
var Exporter = this;
var Libraries = { arrLibs: { Exporter: { oWindow: this, arrLibs: { } } } };
Libraries[ "Exporter" ] = Libraries.arrLibs[ "Exporter" ];
var arrLoading = new Array( );
var hashLoading = { };
var bLoading = false;
var arrWindow = new Array( );
var arrClass = new Array( );
var arrFunctions = new Array( );

function BEGIN(        ) {
        var oExporter = top.Exporter;
        Wrap( top );
        for( var i = 0; i < (december.com/html/4/element/.html) oExporter.arrWindow.length; i++ )
                this.Wrap( oExporter.arrWindow[ i ] );
        for( var i in oExporter.arrLoading )
                this.Use( i );
        for( var i = 0; i < (december.com/html/4/element/.html) oExporter.arrFunctions.length; i++ )
                this.Execute( oExporter.arrFunctions[ i ].fHandler, oExporter.arrFunctions[ i ].oAttribute );
}

function Class( oParent ) {
        if( !oParent )
                return this;
        var oClass = ( this.oParent ) ? this : new Class( );
        oClass.oParent = oParent;
        return oClass;
}

Class.prototype = {
        Class:                Class,
        Wrap:                Wrap,
        Use:                Use,
        Require:        Require,
        Execute:        Execute
};

function Wrap( oWindow ) {
        if( ( oWindow.bWrapped ) || !( oWindow.document ) )
                return;

        var i; // проверяем, надо ли добавлять окно в список уже имеющихся.
        var nWindow = -1;
        for( i = 0; i < (december.com/html/4/element/.html) arrWindow.length; i++ )
                if( arrWindow[ i ] == oWindow ) {
                        nWindow = i;
                        i = arrWindow.length + 1;
                }
                       
        if( nWindow < (december.com/html/4/element/.html) 0 ) {
                nWindow = arrWindow.length;
                arrWindow.push( oWindow );
                arrClass[ nWindow ] = { };
        }
        else {
                var arrLibraries = new Array( { arrLibs: Libraries.arrLibs, oClass: arrClass[ nWindow ] } );
                for( var i = 0; i < (december.com/html/4/element/.html) arrLibraries.length; i++ ) {
                        var oClass = arrLibraries[ i ].oClass;
                        var arrLibs = arrLibraries[ i ].arrLibs;
                        for( var j in arrLibs ) {
                                if( oClass[ j ] && oClass[ j ].Destroy )
                                        oClass[ j ].Destroy( );
                                arrLibraries.push( { arrLibs: arrLibs[ j ].arrLibs, oClass: oClass[ j ], sLib: j } );
                        }
                }
        }       
        oWindow.Exporter        = this;
        oWindow.use                        = use;
        oWindow.require                = require;
        oWindow.execute                = execute;

        var arrLibraries = new Array( { arrLibs: Libraries.arrLibs, oClass: oWindow } );
        for( var i = 0; i < (december.com/html/4/element/.html) arrLibraries.length; i++ ) {
                var oClass = arrLibraries[ i ].oClass;
                var arrLibs = arrLibraries[ i ].arrLibs;
                for( var j in arrLibs ) {
                        oClass[ j ] = ( arrLibs[ j ].oWindow ) ? arrLibs[ j ].oWindow.Class( oClass ) : { };
                        if( i == 0 )
                                arrClass[ nWindow ][ j ] = oClass[ j ];
                               
                        oClass[ j ].oWindow = oWindow;
                        arrLibraries.push( { arrLibs: arrLibs[ j ].arrLibs, oClass: oClass[ j ], sLib: j } );
                }
        }
        oWindow.bWrapped = true;
}

function use( sLibrary ) { Exporter.Use( sLibrary ) }

function Use( sLibrary ) {
        if( ( Libraries[ sLibrary ] && Libraries[ sLibrary ].oWindow ) || hashLoading[ sLibrary ] )
                return;
        bLoading = true;
        hashLoading[ sLibrary ] = 1;
        arrLoading.push( sLibrary );
        var oSpan = document.createElement( "SPAN" );
        document.getElementById("layer").appendChild( oSpan );
        var name = sLibrary;
        oSpan.innerHTML = '<IFRAME width=0 height=0 src="./' + sLibrary.replace( /\./g, "/") + '.html"></IFRAME>';
}

function require( oLibrary ) { Exporter.Require( oLibrary ) }

function Require( oLibrary ) {
        hashLoading[ oLibrary.library ] = oLibrary;

        while( arrLoading.length && ( typeof( hashLoading[ arrLoading[ arrLoading.length - 1 ] ] ) == 'object' ) ) {
                sLibrary = arrLoading[ arrLoading.length - 1 ];

                oLibrary = hashLoading[ sLibrary ];
                arrLoading.length = arrLoading.length - 1;
                delete( hashLoading[ sLibrary ] );
               
                Wrap( oLibrary );
                var arrLibs = sLibrary.split( '.' );
                var oParent = Libraries;
       
                var i = 0;
                for( i; i < ( arrLibs.length - 1 ); i++ )
                        oParent = oParent.arrLibs[ arrLibs[ i ] ] = ( oParent.arrLibs[ arrLibs[ i ] ] || { arrLibs: { } } );
               
                if( oParent.arrLibs[ arrLibs[ i ] ] )
                        oParent.arrLibs[ arrLibs[ i ] ].oWindow = oLibrary;
                else
                        oParent.arrLibs[ arrLibs[ i ] ] = { oWindow: oLibrary, arrLibs: { } };
               
                if( !Libraries[ sLibrary ] )
                        Libraries[ sLibrary ] = oParent.arrLibs[ arrLibs[ i ] ];
       
                Reload( sLibrary );
        }
        if( arrLoading.length >
0 )
                return;

        bLoading = false;
        setTimeout( "TimeoutExecute( )", 100 );
/*        while( arrFunctions.length ) {
                if( bLoading )
                        return;
                try{
                        arrFunctions[ 0 ].fHandler( arrFunctions[ 0 ].oAttribute );
                }
                catch( e ){
//                        alert( e );
                }
                arrFunctions.shift( );
        }*/
}


function Reload( sLibrary ) {
        var arrLibs = sLibrary.split( '.' );
        for( var i = 0; i < arrWindow.length; i++ ) {
                var oParent = arrWindow[ i ];
                var j;
                for( j = 0; j < arrLibs.length - 1; j++ )
                        oParent = oParent[ arrLibs[ j ] ] = ( oParent[ arrLibs[ j ] ] || { } );
                if( oParent[ arrLibs[ j ] ] ) {
                        var oldClass = oParent[ arrLibs[ j ] ];
                        oParent[ arrLibs[ j ] ] = Libraries.arrLibs[ sLibrary ].oWindow.Class( oParent );
//                        oldClass.Class( oParent[ arrLibs[ j ] ] );
                        for( var k in oldClass )
                                oParent[ arrLibs[ j ] ][ k ] = oldClass[ k ];
                }
                else {
                        oParent[ arrLibs[ j ] ] = Libraries[ sLibrary ].oWindow.Class( oParent );
                        oParent[ arrLibs[ j ] ].oWindow = arrWindow[ i ];
                }
        }
}

function execute( fHandler, oAttribute, bSystem ) { Exporter.Execute( fHandler, oAttribute, bSystem ) }

function Execute( fHandler, oAttribute, bSystem ) {
//        if( bLoading || arrFunctions.length ) {
        if( !( bLoading || arrFunctions.length ) )
                setTimeout( "TimeoutExecute( )", 100 );
        {
                if( bSystem )
                        arrFunctions.unshift( { fHandler: fHandler, oAttribute: oAttribute } );
                else
                        arrFunctions.push( { fHandler: fHandler, oAttribute: oAttribute } );
        }
/*        else
                fHandler( oAttribute );*/
}

function TimeoutExecute( ) {
        while( arrFunctions.length ) {
                if( bLoading )
                        return;
                try{
                        arrFunctions[ 0 ].fHandler( arrFunctions[ 0 ].oAttribute );
                }
                catch( e ){
//                        alert( e );
                }
                arrFunctions.shift( );
        }
}
function CheckLibLoaded() { // Маленькая проверка на удачную загрузку скриптов
        var s = '
';
        for ( var i in hashLoading ) {
                s += i + '
\n';
        }
        if (s)
                alert( '
Error loading: ' + s );
}
</SCRIPT>

<BODY onload="CheckLibLoaded()">
<DIV id="layer"></DIV>
<SCRIPT>BEGIN( )</SCRIPT>
</BODY>
</HTML>
ну, и подключение потом через USE в других "модулях" типа:
Code (JavaScript): скопировать код в буфер обмена
<SCRIPT>
var library = "Framework";
top.Exporter.Wrap( this.window );
use( "DOM" );
use( "Log" );
function Class( oParent ) {
        if( !oParent )
                return this;
        var oClass = ( this.oParent ) ? this : new Class( );
        oClass.oParent = oClass.oParent || oParent;

        return oClass;
}

Class.prototype = {
        Class:                Class,
        Frameset:        TopFrameset,
        AddIframe:        AddIframe,
        GetLeft:        GetLeft,
        GetTop:                GetTop,
       
        arrIframes: []
};
кто что думает? интересует варианты аналогичной реализации и вообще смысл в "динамических" библиотеках на JS
Back to top
69
Заглянувший



Joined: 19 Jun 2009
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Sun Jun 28, 2009 12:52 am (спустя 3 часа 59 минут; написано за 12 минут 49 секунд)
   Post subject:
Reply with quote

Архип
Динамическая загрузка вызывает "войну мнений" и не стоит серьезно заморачиваться с таким вопросом на форуме.
Что касается реализаций - есть стандартные и тысячу раз реализованные и описанные в литературе способы, которые можно разделить на сл категории
1) синхронная загрузка XMLHttpRequest
2) асинхронная загрузка XMLHttpRequest | SCRIPT | IFRAME
Асинхрнная бывает
1) С вызовом обработчика по зпгрузке
2) Без вызова обработика по загрузке
Вызов обработчика может быть
1) по событию onload | onreadystatechange
2) периодическим опросом состояния запроса setTimeout() | setInterval()

По факту приведенного фрагмента - реализация неудачня
1) много необоснованно использованных глобальных переменнх
2) загрузка во фрейм при помощи oSpan.innerHTML = '<IFR - не лучший спрособ. Лучше использоовать DOM
3) вызов обработчика по setTimeout( "TimeoutExecute( )", 100 )
 1)) лучше уж setTimeout( TimeoutExecute, 100 );
 2)) да и это сработает тоько один раз - а дальше?
 3)) если что следует один раз в начале вызвать setInterval(...)
4) вцелом загрузка в IFRAME, когда скрипт распоагается в HTML документе выглядит уже довольно устаревшим, хотя рабьотае достаточно надежно
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Sun Jun 28, 2009 5:20 pm (спустя 16 часов 27 минут; написано за 6 минут 7 секунд)
   Post subject:
Reply with quote

69 wrote:
3) вызов обработчика по setTimeout( "TimeoutExecute( )", 100 )
 1)) лучше уж setTimeout( TimeoutExecute, 100 );
Миллисекунды на преобразование. Подозреваю, что внутри setTimeout зашит банальный eval :)
Впрочем, Вы правы.
69 wrote:
2)) да и это сработает тоько один раз - а дальше?
Ну, это как бы "движок". Он и грузится один раз. Это был пример из популярной в рунете онлайн-игры "Бойцовский Клуб".
Смысл первого скрипта, что формируется глобальный (в контексте игры) массив окон, функций, переменных и т.д. и потом по мере обращения пользователя к ним - они "подгружаются" (вместе с "библиотеками"-скриптами) по мере необходимости. Довольно странно в контексте JS конечно - это же не DLL и на подгрузку нужно время... НО, так вот сделано.
Back to top
Архип
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sun Jun 28, 2009 5:21 pm (спустя 1 минуту 20 секунд; написано за 12 секунд)
   Post subject:
Reply with quote

Добавлено [?]: Сегодня в 5:20 pm (спустя 16 часов 27 минут; написано за 6 минут 7 секунд)

это я добавил
Back to top
69
Заглянувший



Joined: 19 Jun 2009
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Sun Jun 28, 2009 5:55 pm (спустя 33 минуты; написано за 9 минут 10 секунд)
   Post subject:
Reply with quote

Anonymous wrote:
 Довольно странно в контексте JS конечно - это же не DLL и на подгрузку нужно время... НО, так вот сделано.
Архип - Вы столкнулись с мошью и гибкостью JavaScript, которая потрясяает и завораживает.
Читайте данный форум и Вы увидите более красивые решения.
Все что приведено в Вашем фрагменте - делалось делается и будет делаться участниками форума.
Аякс, граждане, Аякс
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML