3 ms·
Fully agree, the default should be strict, jQuery based code requires every developer to be aware of every selector used in the project and remember to update i
by tored 2y ago
Fully agree, the default should be strict, jQuery based code requires every developer to be aware of every selector used in the project and remember to update it when the DOM changes. That is of course impossible.
I think it is possible to replace the jQuery init function with your own implementation that enforces length.
- tored 2y agoEnjoy! <html> <head> <script src="https://code.jquery.com/jquery-4.0.0-beta.2.js"></script> </head> <body> <ul id="list"> <li>foo</li> <li>bar</li> <li>gnord</li> </ul> <script> (function ($) { "use strict"; if ("development") { // jQuery strict mode, logs errors on empty selectors if not opting out const getStackTrace = function (error) { const stack = error.stack || ''; return stack .split('\n') .map(function (line) { return line.trim(); }) .filter(function (line) { return !!line; }); }; // by calling try() we silence selectors that returns empty // problem is that this function runs after the selector $.fn.try = function () { this.__store.try = true; return this; }; // thus we use the GC to check when the jQuery object is destroyed const registry = new FinalizationRegistry((store) => { if (!store.try) { console.error( 'Empty result for selector "' + store.selector + '"', getStackTrace(store.error) ); } }); // override the init method const jQueryInit = $.fn.init; $.fn.init = function (selector, context) { const result = new jQueryInit(selector, context); if (selector && result.length === 0) { const store = {selector: selector, try: false, error: new Error()}; result.__store = store; registry.register(result, store); } return result; }; } else { $.fn.try = function () { return this; }; } })(jQuery); // normal usage, have result, no error $("#list li").each(function (i, el) { console.log(el); }); // empty result, triggers error log $("#nolist li").each(function (i, el) { console.log(el); }); // empty result but with try, no error $("#trylist li").try().each(function (i, el) { console.log(el); }); </script> </body> </html>
- niutech 2y agoDon't put 3rd-party blocking scripts in <head>!