Pull to refresh

Притча об автоматическом менеджменте виджетов

Reading time8 min
Views681
— Здравствуй…
— А-а-а! Памагите! Убивают! \(0_0)/
— Дружок, спокойно, я свой :-\
— Свои незаметно сзади не подкрадываются! \(@_@)/
— А я динамически добавился В-]
— Э-э-э \(~_~)/
— Ясно, не знаешь, как реагировать на такие ситуации? XD
— Ну… как бы… есть мысли… \(=_=)/
— Покажи-ка свой исходник %-)
— Я… эта… стесняюсь… \(._.)/
— Давай, не боись, я же свой ;-)
— Лаааадно \(-_-)/
<body><br>    <script><br>        $(function(){<br>            $('.c-example').wrapInner( '<span class="wrapper" />' )<br>        })<br>    </script><br>    <div class="c-example">epic</div><br></body>

— Лаконичненько :^D
— Доооо \(*^*)/
— А что ты скажешь на это? }:-]
<body><br>    <script><br>        $(function(){<br>            $('.c-example').wrapInner( '<span class="wrapper" />' )<br>        })<br>        $(function(){<br>            $('body').html( '<div class="c-example">fail</div>' )<br>        })<br>    </script><br>    <div class="c-example">epic</div><br></body>

— Ничего \(%_%)/ Я не заметил как всё поменялось…
— То-то же… а теперь смотри :-P
<body xmlns:c="urn:component"><br>    <script><br>        CComponent({ tag: 'c:example', factory: function( el ){<br>            $(el).wrapInner( '<span class="wrapper" />' )<br>        }})<br>        $(function(){<br>            $('body').html( '<c:example>win</c:example>' )<br>        })<br>    </script><br>    <c:example>epic</c:example><br></body>

— Как? Как оно работает? \(*o*)/
— Оно в реальном времени отслеживает появление определённых элементов и привязывает к ним, создаваемые с помощью фабрики, виджеты, которые атоматически разрушаются (метод destroy) при удалении элемента из дома B^]
— Ухты, здорово! \($_$)/
— Да… ладно, кури библиотеку :-]

var CComponent= new function(){<br><br>Version: 2<br>Description: 'attach widget constructor to DOM as live component'<br>License: 'public domain'<br> <br>Implementation:<br><br>var latencyDefault= 50<br><br>var CComponent= function( arg ){<br>    if(!( this instanceof CComponent )) return new CComponent( arg )<br><br>    var elements= [], widgets= []<br>    var timerTracking, timerCleaning<br><br>    var latencyTracking= arg.latencyTracking || latencyDefault<br>    var latencyCleaning= arg.latencyCleaning || latencyDefault<br>    var field= 'CComponent:' + new Date + Math.random()<br><br>    var tag= arg.tag<br>    var factory= arg.factory<br><br>    var attach= function( el ){<br>        var widget= new factory( el ) || null<br>        el[ field ]= widget<br>        if( !widget ) return<br>        elements.push( el )<br>        widgets.push( widget )<br>    }<br><br>    var attachIfLoaded= function( el ){<br>        var cur= el<br>        do {<br>            if( !cur.nextSibling ) continue<br>            attach( el )<br>            break<br>        } while( cur= cur.parentNode )<br>    }<br><br>    var tracking= function( ){<br>        var nodes= CComponent.tags( tag )<br>        for( var i= 0, len= nodes.length; i < len; ++i ){<br>            var el= nodes[ i ]<br>            var widget= el[ field ]<br>            if( typeof widget === 'object' ) continue<br>            attachIfLoaded( el )<br>        }<br>        timerTracking= setTimeout( tracking, latencyTracking )<br>    }<br><br>    var cleaning= function( ){<br>        var doc= document.documentElement<br>        checking: for( var i= elements.length; i--; ){<br>            var el= elements[ i ]<br>            var cur= el<br>            do {<br>                if( cur === doc ) continue checking<br>            } while( cur= cur.parentNode )<br>            var widget= el[ field ]<br>            if( widget.destroy ) widget.destroy()<br>            el[ field ]= void 0<br>            elements.splice( i, 1 )<br>            widgets.splice( i, 1 )<br>        }<br>        timerCleaning= setTimeout( cleaning, latencyCleaning )<br>    }<br><br>    var revive= function( ){<br>        tracking()<br>        cleaning()<br>    }<br>    var freeze= function( ){<br>        timerTracking= clearTimeout( timerTracking )<br>        timerCleaning= clearTimeout( timerCleaning )<br>    }<br><br>    var destroy= function( ){<br>        freeze()<br>        for( var i= elements.length; i--; ){<br>            var widget= widgets[ i ]<br>            if( widget.destroy ) widget.destroy()<br>        }<br>        elements= []<br>        widgets= []<br>    }<br>    <br>    var onload= function( ){ attachIfLoaded= attach }<br>    // replace with DOMContentLoaded from your framework<br>    window.addEventListener<br>    ? window.addEventListener( 'load', onload, false )<br>    : window.attachEvent( 'onload', onload )<br>    <br>    this.tag= function( ){ return tag }<br>    this.field= function( ){ return field }<br>    this.factory= function( ){ return factory }<br>    this.latencyTracking= function( ){ return latencyTracking }<br>    this.latencyCleaning= function( ){ return latencyCleaning }<br>    this.elements= function( ){ return elements.slice( 0 ) }<br>    this.widgets= function( ){ return widgets.slice( 0 ) }<br>    this.revive= revive<br>    this.freeze= freeze<br>    this.destroy= destroy<br><br>    revive()<br>}<br><br>var cacheTags= {}<br><br>CComponent.tags= function( name ){<br>    var nodes= cacheTags[ name ]<br>    if( !nodes ){<br>        var isIE= /*@cc_on!@*/ false<br>        var chunks= /(?:(\w+):)?([-\w]+)/.exec( name )<br>        var scope= isIE && chunks[1] || ''<br>        var tag= isIE && chunks[2]|| name<br>        nodes= cacheTags[ name ]= document.getElementsByTagName( tag )<br>        nodes.scopeName= scope<br>    }<br>    var res= [], scope= nodes.scopeName<br>    if( scope ){<br>        for( var i= 0, len= nodes.length; i < len; ++i ){<br>            var node= nodes[ i ]<br>            if( node.scopeName !== scope ) continue<br>            res.push( node )<br>        }<br>    } else     {<br>        for( var i= 0, len= nodes.length; i < len; ++i )<br>            res.push( nodes[ i ] )<br>    };<br>    return res<br>}<br><br>Export: return CComponent<br><br>Usage:<br><br>CComponent(<br>{  tag: 'c:example'<br>,  factory: function( el ){<br>        this.el= el<br>        alert( 'FOUND ' + this.el.innerHTML )<br>        this.destroy= function(){<br>            alert( 'LOST ' + this.el.innerHTML )<br>            delete this.el<br>        }<br>    }<br>} )<br><br>}
Tags:
Hubs:
-10
Comments26

Articles