For those wondering what this is for, I've written a document with guidelines in building scalable non-SPA apps leveraging this: http://ricostacruz.com/rsjs
Is it just me or do these approaches seem hacky? If you were using something like Angular or React wouldn't you plug into lifcycle events that are exposed by the library like Abgular's OnInit?
if you were using something like Angular or React to manage your full page, then by all means run with it! RSJS is an alternative to that that's more suited for "traditional" sites rendered on the server (eg, traditional Rails and Rails-like setups).
How does it accomplish it in 680 bytes? I tried reading the code but don't understand it.. there is a lot of stuff about css and keyframes that i don't get.
It adds a stylesheet to accept new stylerules. For every element set (CSS selector) you want to watch it adds a new stylerule that makes a no-op animation happen (transform:none -> transform:none). Every time such a node that matches your selector is added to the document, this animation is triggered. When this happens, Sentinel publishes an event to whatever handlers you ask it to, by listening to the 'AnimationStart' event emitted when an animation happens. Pretty clever, but simple, and I think this is not the first source to suggest this approach for watching DOM modification. Note, the unminified dist/sentinel.js is not 682 bytes!
Wow that is just super clever and I'm guessing super fast also since it is triggered by the browser. I was thinking more on the lines of comparing nodes using setInterval which would of course never work because it would be slow and CPU intensive!
The DOM element arrival detection is based on animation events in Sentinel. Sentinel adds global style rules that cause newly born elements to start animation and so generate "animationstart" event that the library catches.
That appears if not hacky then a bit heavyweight - 2 passes of layout needed at least.
But I do understand the need for this. In sciter I've added special CSS property aspect that takes name of the function to execute when element gets mounted into the DOM and before any layout on it:
What's the difference between SentinelJS and DOM Mutation Observers?
I glanced at the source code, it seems this lib is using some kind of hack based on CSS animations. Why not just use Mutation Observers, which are the standard approved API to get the job done?
Mutation observers are very, very bad for performance. They're still useful for some things as they give you a lot of detail about what happened, but if you're just looking for a change on a specific set of elements this library seems like a better bet.
> Mutation observers are very, very bad for performance.
No, they are not. Mutation events are tragic for performance and are deprecated (Chrome will make that pretty obvious in the console). The Mutation Observer was designed to have reasonable performance characteristics. It's still a very active listener, but rarely is it a bottleneck.
I would have thought MOs were implemented in C and thus pretty fast. Either way, even if they're slow compared to this technique at present, I haven't found performance to be an issue when using them now, and no doubt they'll be optimsied further.
I might be missing a very obvious use-case here (3rd party scripts, perhaps?) but surely if a new DOM node is inserted, you most likely actioned it yourself - so why not set the innerHTML at that point?
I'd actually completely forgotten about mutation observers too - they'd got mentally filed away under "browser vendors are why we can't have nice things".
For fengari-web[1] we want to watch for <script type="text/lua"> tags inserted into the document.
At the moment we use a MutationObserver[2], but I should compare the speed of things. I've created a new issue to track[3]
Yes. SentinelJS will trigger a watch for elements present when DOMContentLoaded fires and for elements added dynamically afterwards. In the Quickstart example, there's an element that is part of the initial HTML payload and a button to add more dynamically:
https://jsfiddle.net/muicss/rbqLbjzf/
Thanks for the response and sorry. Maybe I was not quite clear. I was attempting ask if it would trigger the event handler before DOMContentLoaded (relevant on big document where DOMContentLoaded takes 10 seconds to fire)
Example on a timeline:
0. Browser starts parsing the document
1. Sentiel.js loads (ie. by blocking script tag)
2. Handler is set for .my-component (ie. by inline script tag)
3. Browser parses <div class="my-component" />
4. Handler is fired for .my-component
5. Browser parses rest of document
6. DOMContentLoaded is fired.
Will the .my-component handler will always fire after DOMContentLoaded or have you experienced that it might happen before? I guess it reduces to the question if key-frame-handlers will fire before the document is fully loaded/rendered.
Yes, it comes down to when animation events fire which I believe is after DOMContentLoaded.
In MUI we detect all elements present in the DOM when DOMContentLoaded fires using document.querySelectorAll() and then use SentinelJS to detect elements added after.
on() and off() are the names that every JavaScript library uses for event handlers; I don't think bikeshedding individual libraries is going to help much.
For those wondering what this is for, I've written a document with guidelines in building scalable non-SPA apps leveraging this: http://ricostacruz.com/rsjs