`onload` not fired on blocked scripts
jeanfredrik opened this issue · 3 comments
The load
event doesn’t seem to fire on blocked script tags created with document.createElement
in Chrome.
Reproduction:
<!DOCTYPE html>
<html>
<head>
<script>
window.YETT_BLACKLIST = [/jquery/];
</script>
<script src="https://unpkg.com/yett"></script>
<script>
let scriptEl = document.createElement('script');
scriptEl.src = 'https://code.jquery.com/jquery-3.5.1.slim.min.js';
scriptEl.onload = function () {
console.log('Loaded');
console.log(window.jQuery);
};
document.head.appendChild(scriptEl);
</script>
</head>
<body>
<button onclick="window.yett.unblock();">Unblock</button>
</body>
</html>
I expect "Loaded"
and the value of window.jQuery
to show in the console, but nothing happens. Preferably it should fire after the script has been loaded and executed.
Ok, so the problem is that the script element node is cloned before it’s added to the backup list. cloneNode
won’t clone event listeners, and from what I can tell there’s no way to clone with event listeners in JS. Is it necessary to store a clone of the element since it’s also removed from the DOM?
https://github.com/snipsco/yett/blob/c65c516dfcd3f1d61a8b883848e40073b1f658a4/src/observer.js#L17
Hi @jeanfredrik, thanks for reporting this!
Is it necessary to store a clone of the element since it’s also removed from the DOM?
Yes, for multiple reasons:
- First, we are mutating the original DOM node by changing the
type
and adding a firefox-specific event listener. - Then, Firefox will not download an HTMLScriptElement that has been inserted more than once inside a document.
So it won't be possible to remove the cloneNode()
function, but keeping the event listeners is just a matter of copying the right object properties to the new node.
I just released yett v0.1.13
containing the fix 📦 .
Thanks for the quick fix! Works great!