1

这是一个小的 jQuery 插件,我用于在查询没有返回选择器时获取 console.warn

(function($, w, c){
if(!w.jQuery || !c) return;
c.w = c.warn || c.log; // safely use either warn or log
// jQuery and console.warn/log are available, we're good to go

var _find = $.find,
    _attr = $.fn.attr;

// 'duck punch' jQuery.find - Replace with a wrapper function with our warning which returns the original result
$.find = function(){
    var result = _find.apply(this, arguments);
    if(!result.length) c.w('jQuery Selector "' + result.selector + '" returned no matches');
    return result;
};

$.fn.attr = function(attr){
    if(arguments.length === 1) {
        var result = _attr.call(this, attr);
        if(result === void 0) {
            c.w('jQuery Attribute Getter for "' + attr + '" returned undefined for selector "' + $(this).selector + '"');
        }
        return result;
    } else {
        _attr.apply(this, arguments);
        return this;
    }
};

w.jQuery = w.$;

}(jQuery, window, console));

当有一个空选择器时,我在控制台中得到的是:

Uncaught TypeError: Object function (){
    var result = _find.apply(this, arguments);
    if(!result.length) c.w('jQuery Selector "' + result.selector + '" returned no matches');
    return result;
} has no method 'matchesSelector'

我不明白它是什么matchesSelector以及它来自哪里

4

1 回答 1

8

您正在覆盖$.find但没有替换 jQuery 所依赖的属性。$.find有许多属性,例如matchesSelector,matches等,因为它们没有分配给您的函数而丢失。

你不应该覆盖$.find

您可以将它们附加回来,但我有一种不好的感觉,仍然遗漏了一些其他问题:

var _find = $.find,
    empty = function() {};

$.find = function() {};

for (var key in _find) {
                                      //ignore standard function properties
    if (_find.hasOwnProperty(key) && !empty.hasOwnProperty(key)) {
        $.find[key] = _find[key];
    }
}

在整个 jQuery 源代码中都有对属性的硬编码引用$.find,例如:

 jQuery.find.matchesSelector(cur, selectors) ) {

用这些填充普通对象的结果:

var myObj = {}, empty = function(){};

for (var key in $.find) {
    if ($.find.hasOwnProperty(key) && !empty.hasOwnProperty(key)) {
        myObj[key] = $.find[key];
    }
}

myObj
Object
attr: function (a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}}
contains: function (a,b){return a!==b&&(a.contains?a.contains(b):!0)}
error: function (a){throw new Error("Syntax error, unrecognized expression: "+a)}
filter: function (a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s}
find: function (a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}}
getText: function (a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e}
isXML: function (a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1}
matches: function (a,b){return m(a,null,null,b)}
matchesSelector: function (a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}
selectors: Object
uniqueSort: function (a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a}
于 2012-11-29T14:08:02.070 回答