当jQuery选择器未找到时会发生什么?

7
如果我将一个选择器作为参数传递给一个函数。
// selector is an object
function(selector) {

  selector.trigger('eventHere');
}

显然,如果传入的选择器中没有这个事件,那么该事件永远不会触发,但我应该在触发事件之前进行一些条件检查吗?我的意思是:
// selector is an object
if(selector === 'matched'){
  // then fire the event
}
else{
  // do nothing
}

或者就让它保持不变...?

jQuery选择器是普通的字符串(例如"div.main h2"),所以我猜你给另一个概念起了这个名字。你能澄清一下吗? - Álvaro González
5个回答

7
jQuery的好处在于,如果选择器没有匹配到任何元素,它不会抛出异常或引发错误。因此您无需采取任何额外措施,这是一项安全操作:
// selector **must** be a jQuery object
// the assumption here is that you've already done 
// var selector = $('selectorString'); elsewhere
// and have invoked this function with selector
function(selector){
  selector.trigger('eventHere');
}

请注意,您必须确保selector是一个jQuery对象!否则,您可能会收到一个错误,表明trigger 不是一个函数。
编辑
亚当·特尔森在评论中说:“在执行针对它的函数之前,测试jquery对象是否为空或长度为0可能是值得的。仅仅因为它不会抛出一个错误,并不意味着通过首次执行它不能获得性能提升(jQuery仍试图)。”
还有一个jsperf测试表明,每种技术的操作/秒数有明显的差异(这不是时间!一开始让我困惑了)——在调用函数之前检查null/0长度的jQuery对象与简单地调用函数。

1
作为对您出色建议的补充,值得测试一下 jQuery 对象是否为空或长度为 0,在执行函数之前。仅仅因为它不会抛出错误,并不意味着在第一次执行时不能通过不执行来提高性能(jQuery 仍然会尝试执行)。 - Adam Terlson
@NoGood - 相对于一些性能问题,影响是相对小的,但值得做。这里有一个jsperf测试来证明它:http://jsperf.com/jquery-check-for-null-selector-or-just-perform-method2 我在Chrome中通过先测试结果看到了19%的改进。 - Adam Terlson
@Adam 感谢你展示这个 - 绝对值得记住。你认为是错误处理开销导致了减速吗? - no.good.at.coding
关于您的编辑,公平地说,我并没有创建jsperf测试,只是挖掘了它。至于为什么,简单来说,jQuery会执行很多操作,而不管长度。以jsperf的remove()示例为例,查看http://code.jquery.com/jquery-1.5.2.js并搜索`remove: function`以找到定义。您会看到它正在测试各种类型、集合、执行事件解绑定等。这不是由于错误处理 - 实际上,只有在极少数情况下,jQuery才需要使用try/catch块。 - Adam Terlson
1
很快你就需要一个新的用户名。 - Adam Terlson
显示剩余2条评论

5

jQuery总是返回一个元素数组,即使选择器没有返回任何元素,它也将包含一个空数组。

您仍然可以在该空数组上执行任何函数,而无需jQuery抛出错误,因此无需检查返回的元素是否存在。

如果元素没有此类事件可触发,但您尝试触发它,则不会发生任何事情,也不会抛出异常;再次强调,无需检查。

请注意,如果您坚持将选择器传递给对象,则仍然需要使用选择器获取对象,然后才能对其进行任何操作。

function myTriggerFunction(selector)
{
  var elements = $(selector);
  elements.trigger('eventHere');
}

myTriggerFunction('.WeWillBeTriggered');

1
如果创建jQuery对象时没有匹配任何元素,它仍然是一个jQuery对象,但里面没有任何元素。对于在jQuery对象上执行的大多数方法都可以处理任意数量的元素,包括零个,因此,如果您只想什么也不做,那就不需要进行任何检查。
只有当你想要在集合为空时执行特殊操作时,才需要检查它,并通过检查 length 属性来实现:
function(selection){
  if (selection.length > 0) {
    selection.trigger('eventHere');
  } else {
    // do something else because the selection was empty
  }
}

请注意,“选择器”是您用于指定要放入jQuery对象中的元素的字符串,例如代码$('#main')中的字符串#main,因此将jQuery对象称为“选择器”可能会令人困惑。

1

只需触发事件即可。

但是 selector 变量实际上应该是一个 jQuery 对象(使用你所用的语法)。


0

如果您想确保事件仅针对特定元素类型触发,可以在触发事件之前进行检查。

if (selector.is("type of element")) {
   //then fire event
}

或者,如果您想通过标签名称进行检查
if (selector.get(0).tagName=="tag name") {
   //then fire event
}

整个 jQuery 选择器的重点不就是您事先已经知道了吗? - Timothy Groote
根据 OP 的说法,假设该函数将被调用,即使对于不支持已注册事件的选择器(元素)也是如此。 - Sang Suantak
在你的例子中,selector.is("type of element")将始终返回false,因此应该进行迭代。 - Timothy Groote

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接