Max*_*ich 73 javascript jquery jquery-selectors
最近使用了一些代码
$("#divMenuContainer:visible").hide("explode");
Run Code Online (Sandbox Code Playgroud)
然而,经过一段时间试图让它工作,我意识到我的选择器引用了一个不存在的div.
查询的结果只是它没有执行.
显然这是设计,任何人都可以解释为什么这个设计选择的逻辑,而不是提出某种例外?
不试图批评只是试图理解.
Mat*_*man 56
把它想象成一个查询,它就是这样.您要求所有符合条件的"记录"(DOM元素).结果是一组零记录.
然后循环遍历零记录并将操作应用于它们.:)
如果你对SQL或数组做了同样的事情,它在大多数语言中的行为方式都是一样的.零记录的集合不是错误状态.
var things = $("invalid selector");
$("p").text("The object is valid: " + things + " but has " + things.length + " elements.")
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
Run Code Online (Sandbox Code Playgroud)
Nic*_*ver 53
这里有一些很好的理由,"可链接性"是主要的驱动器,通过链接编写非常简洁的代码的能力必须毫无错误地无法工作,例如:
$("#divMenuContainer:visible").hide("explode").add("#another").fadeIn();
Run Code Online (Sandbox Code Playgroud)
链中的每个对象,即使它没有引用DOM元素,也可能在以后添加更多,或者让我们再举一个例子:
$("#divMenuContainer:visible").live("click", function() { ... });
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们不关心选择器找到的任何元素,我们关心选择器本身.这是另一个:
$("#divMenuContainer:visible").find(".child").hide("explode").end().fadeOut();
Run Code Online (Sandbox Code Playgroud)
即使没有孩子,我们也可能希望之后再回到链中,继续使用.prevObject
引用来回到链上.
像这样的许多不同的案例表明了图书馆的好处.至于为什么,通过对jQuery的创建者John Resig的采访,他说这就是它的成功方式.他的代码就像他能得到的那样简洁,而且链式模型就是出类拔萃的,它恰好也有很多好处,上面的例子只是其中的一小部分.
要明确的是,我并不是说链接的每个属性都是好的,它只有许多优点.
我们以此页面为例,如果我们有这样的话:
$(".comment").click(replyToFunction);
Run Code Online (Sandbox Code Playgroud)
如果失败,因为还没有任何评论?嗯,不,不是真的,那是预期的,我不希望这里出现错误......如果元素存在,那么就去做,如果不是的话.我的观点是,至少在我的经验中,由于缺少元素而不抛出错误比投掷错误更有用.
你的问题中的#ID
选择器,选择器是一个非常特殊的情况,你只期望一个元素,所以也许你可能会认为它应该在那里失败...但那时与其他选择器不一致,你想要一个库要保持一致.
对于几乎任何其他选择器,你期望0多元素,所以当你没有找到任何元素时失败在大多数情况下会非常不理想,在.live()
上面的情况下更是如此.
这是一个灵活性问题.我自己也喜欢你要求的保护,你可以自己做.使用:
jQuery.fn.single = function() {
if (this.length != 1) {
throw new Error("Expected 1 matching element, found " + this.length);
}
return this;
};
Run Code Online (Sandbox Code Playgroud)
现在使用$("input:checked").single()确保它返回单个项目或给你一个错误.
jQuery()将始终返回一个jQuery对象,以防止错误,但更重要的是:
所以你可以编写响应代码.
do X if Y is present
Run Code Online (Sandbox Code Playgroud)
如果Y不存在,则X不计算.
这意味着你可以拥有一个全局init交叉页面,只需要初始化插件,而不管它们是否找到了什么.
$(function(){
// does nothing if the page contains no element with className 'accordion'
$('.accordion').implementAccordion();
// usually on a single page, but we can add it to a global js file nontheless.
$('.validate-form').implementFormValidator();
});
Run Code Online (Sandbox Code Playgroud)
虽然当然,一些插件写得很差,但会引发错误.
这是关于图书馆的jQuerys(实际上是John Resigs)的一部分.
它试图对你和你的客户"善意",反过来意味着它很少抛出异常
(很少)
但是像往常一样,你可以轻松扩展它:
(function(_jQuery){
jQuery = function(){
var ret = _jQuery.apply(this, arguments);
if(!ret.length) throw new Error('empty selector');
return ret;
};
}(jQuery));
Run Code Online (Sandbox Code Playgroud)
但就像Nick
评论中所说,大多数情况下这不是一种理想的行为.如果你想出于某种原因想要它,那么像上面这样的代码片段应该这样做.