📜 ⬆️ ⬇️

Parable about automatic widget management

- Hello…
- Aaaa! Pamagite! Kill! \ (0_0) /
- Pal, calm, I am my own: - \
- They do not sneak up behind their heads! \ (@ _ @) /
- I dynamically added B-]
- Uh-uh (~ _ ~) /
- Clearly, you do not know how to respond to such situations? XD
- Well ... how would ... have thoughts ... \ (= _ =) /
- Show me your source code% -)
- I ... this ... I hesitate ... \ (._.) /
- Come on, don't be afraid, I'm your own ;-)
- Laaaadno \ (-_-) /
< body > <br> < script > <br> $( function (){<br> $( '.c-example' ).wrapInner( '<span class="wrapper" />' )<br> })<br> </ script > <br> < div class ="c-example" > epic </ div > <br> </ body >

- Laconic: ^ D
- Doooo \ (* ^ *) /
- What do you say to that? }: -]
< 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 >

- Nothing \ (% _%) / I did not notice how everything changed ...
- That's the same ... and now look :-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 >

- How? How does it work? \ (* o *) /
- It tracks the appearance of certain elements in real time and binds to them, created using the factory, widgets that are automatically destroyed (destroy method) when the element is removed from the house B ^]
- Wow, great! \ ($ _ $) /
- Yeah ... well, smoke the library: -]

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>}

')

Source: https://habr.com/ru/post/91003/


All Articles