Is there a plugin for jQuery that can write out when a selector returns 0 items for troubleshooting?
I am aware of using .length
- i'm looking from a observational/analysis/diagnostic level, not on the code level. I don't want to put .length
all over my code.
To put in code, say I have some complex selector
$('#someComplex selectorHere')...
in another part of the code, I would like to know that JQuery returns 0 for that selector.
function onFailedSelector(selectorString) {
console.log("Failed to select "+selectorString);
}
In context: We just had a ton of bugs introduced thanks to ASP.NET's naming convention and it would have been helpful t开发者_运维技巧o know which ones broke.
Try some AOP magic
I have a working example on jsfiddle if you want to try it out.
jQuery.aop.around({target: window, method: '$'},
function(invocation) {
var result = invocation.proceed();
if (result.length == 0) {
console.log('0 Result selector' + invocation.arguments[0]);
}
return result;
}
);
I am not sure what all you want to log off of the invocation, but this should get you started. The AOP plugin website has more information in references.
This should wrap any invocations to $("selector") and when you are done debugging, just remove the aop plugin & your around snippet.
That's a very simple plugin to write:
(function ($) {
$.fn.test = function () {
var t = $(this);
if (t.length == 0) {
console.log("Failed to select " + t.selector);
}
};
})(jQuery);
// Usage
$('div').test();
JSFiddle Example
If you want to do some proper nasty code you can change the jQuery source file to do this (line 25 of v1.6.2):
var jQuery = function (selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
var result = new jQuery.fn.init(selector, context, rootjQuery);
if (!result.length && selector && console) {
console.log("Selector not found: " + selector);
}
return result;
},
Probably not the best idea and definitely something you'd only use for quickly finding these problems you're having.
Dirty, mostly working solution:
function $(arg) {
if ( jQuery(arg).length == 0) {
console.log(arg+" fails");
}
return jQuery(arg)
}
Almost working because it will not alert you about a selector when only part of it fails, $("#existing_elem, #not_existing_elem)
will not log anything.
Also it will log a selector more than once, when you chain commands.
This is quick and dirty method, so possibly has other drawbacks:)
Demo
try this:
var devjQuery = function(){
var ret = jQuery.apply(this, arguments);
if (ret.length === 0 && typeof window.console != "undefined") {
console.log("No Elements Selected.",arguments);
}
return ret;
}
devjQuery("div");
devjQuery("a");
now you just use devjQuery instead of $ or jQuery. I guess you could also use noConflict then actually use jQuery and $ so that your code doesn't have to change.
Edit:
However this only works on $(), for it to work on the other dom traversal methods, you would have to override them in the same way or override something that all of them use(such as jQuery.pushStack).
You could put a debugging statement in your jQuery file and remove it when done. I'm not sure if a plugin has enough power. Edit the jQuery function to count the number of results before returning the created object.
var jQuery = function( selector, context ) {
var ret= new jQuery.fn.init( selector, context, rootjQuery );
if(ret.length == 0 && arguments.length != 0 ) {
console.log(ret.selector + " returned zero elements!");
}
return ret;
},
JSFiddle: http://jsfiddle.net/HQC5V/2/
http://sandbox.phpcode.eu/g/20c9c/1
<div><div></div></div>
<script>
alert($("div").length);
</script>
if it returns 0, it means there are no divs
http://sandbox.phpcode.eu/g/20c9c/2
精彩评论