[英]What is the usual approach to escape an element which is non existing (like jQuery does)
If I'm having 如果我有
var btn = document.getElementsByClassName('top_button')[0];
btn.addEventListener('click', function() { /* some here */ }));
and the class undefined I'm getting a TypeError
. 和类未定义,我得到一个
TypeError
。 I'm wondering what is the usual approach to escape this. 我想知道避免这种情况的通常方法是什么。 Would it be
可不可能是
var btn = document.getElementsByClassName('top_button')[0] || {};
or should I do this different? 还是我应该做不同的事情? How is jQuery doing this, because when I'm using
$('.top_button')
and the element is not there, it just returns an object. jQuery如何做到这一点,因为当我使用
$('.top_button')
而元素不存在时,它只是返回一个对象。
Thanks 谢谢
You can use a simple if
: 您可以使用简单的
if
:
var btn = document.getElementsByClassName('top_button');
if (btn.length > 0) {
btn = btn[0];
btn.addEventListener('click', function() { /* some here */ }));
}
Or you can also check for typeof
to be "undefined"
. 或者,您也可以检查
typeof
是否为"undefined"
。
If you really want just the first one, then I agree with Praveen that an if
is the clearest, simplest solution, though I usually do it in a different place: 如果您真的只想要第一个,那么我同意Praveen的观点,
if
是最清晰,最简单的解决方案,尽管我通常在其他地方这样做:
var btn = document.getElementsByClassName('top_button')[0];
if (btn) {
btn.addEventListener('click', function() { /* some here */ }));
}
The collection returned by getElementsByClassName
reliably, cross-browser, gives you undefined
if there's no element at the index you asked for (just like JavaScript arrays). 跨浏览器可靠地由
getElementsByClassName
返回的集合,如果您要求的索引中没有元素(就像JavaScript数组一样),则会使您undefined
。
But I would use querySelector
rather than getElementsByClassName
, since you only want the first and there's no need to build a list, and querySelector
is on all modern browsers, and also IE8 (whereas IE8 lacks getElementsByClassName
). 但我会用
querySelector
而非getElementsByClassName
,因为你只需要第一,有没有必要建立一个列表,并querySelector
是所有现代浏览器,并且还IE8(而IE8没有getElementsByClassName
)。
var btn = document.querySelector('.top_button');
if (btn) {
btn.addEventListener('click', function() { /* some here */ }));
}
querySelector
accepts any CSS selector (including complex ones) and returns the first matching element, or null
. querySelector
接受任何CSS选择器(包括复杂的选择器)并返回第一个匹配的元素,或者为null
。 Its cousin querySelectorAll
returns a list (which can be empty if none match). 它的表亲
querySelectorAll
返回一个列表(如果不匹配,则可以为空)。
If you want to hook the event on all matching elements, Quentin has you covered . 如果您想将事件挂接到所有匹配的元素上, Quentin可以满足您的要求 。
How is jQuery doing this, because when I'm using $('.top_button') and the element is not there, it just returns an object.
jQuery如何做到这一点,因为当我使用$('。top_button')而元素不存在时,它只是返回一个对象。
jQuery objects are wrappers around sets of DOM elements (usually, they can be wrappers around other things, but in typical use they're DOM elements). jQuery对象是DOM元素集的包装器(通常,它们可以是其他东西的包装器,但是在典型的用法中,它们是DOM元素)。 So when you do
$('.top_button')
, you get a jQuery object which is a wrapper around a set with nothing in it. 因此,当您执行
$('.top_button')
,您将得到一个jQuery对象,该对象是对没有任何内容的集合的包装。 You can make calls on that jQuery object, like .on
, and they don't fail (because the jQuery object exists), but they don't do anything, either (because there are no elements in the set for it to do anything with). 您可以在该jQuery对象上进行调用,例如
.on
,它们不会失败(因为jQuery对象存在),但它们也不会执行任何操作(因为该集合中没有任何元素可以执行任何操作)与)。
I'm not suggesting it, but you could do the same thing yourself with querySelectorAll
. 我不建议这样做,但是您可以使用
querySelectorAll
自己做同样的事情。 (jQuery predates querySelectorAll
by some years, originally John Resig built an entire selector engine for it. Modern browsers make that unnecessary in a jQuery-like thing, unless you want to add your own CSS selector stuff like jQuery's :has
.) (jQuery比
querySelectorAll
,最初是John Resig为此构建了一个完整的选择器引擎。现代的浏览器使类似jQuery的东西变得不必要,除非您想添加自己的CSS选择器,例如jQuery的:has
。)
Just by way of illustrating what jQuery is doing (purely conceptually): 仅通过说明jQuery在做什么(从概念上来说):
function DomQuery(selector) {
// Get the matching elements, as an array (the `slice` thing turns
// the collection returned by `querySelectorAll` into an array)
this.elements = Array.prototype.slice.call(document.querySelector(selector));
}
DomQuery.prototype.on = function(eventName, handler) {
this.elements.forEach(function(element) {
element.addEventListener(eventName, handler, false);
});
return this;
};
Usage: 用法:
new DomQuery(".top_button").on("click", function() {
// do something
});
We can make that more jQuery-like by making new
optional: 我们可以通过使
new
成为可选的来使它更像jQuery:
function domQuery(selector) {
// If not called via `new`, do that
if (!(this instanceof domQuery)) {
return new domQuery(selector);
}
// Get the matching elements, as an array (the `slice` thing turns
// the collection returned by `querySelectorAll` into an array)
this.elements = Array.prototype.slice.call(document.querySelector(selector));
}
domQuery.prototype.on = function(eventName, handler) {
this.elements.forEach(function(element) {
element.addEventListener(eventName, handler, false);
});
return this;
};
Usage: 用法:
domQuery(".top_button").on("click", function() {
// do something
});
As answered by @PraveenKumar, you can check for the length but you can also check if a variable is undefined by 正如@PraveenKumar回答的那样,您可以检查长度,但也可以检查变量是否未定义
if (typeof btn === "undefined") {
//do stuff here.
}
jQuery stores all the results in an array. jQuery将所有结果存储在数组中。 When you call
on
, it loops over that array and applies the event handler to each item in it. 当您调用
on
,它将遍历该数组并将事件处理程序应用于其中的每个项目。 If there are zero items, a standard for loop will stop immediately. 如果零项,则标准for循环将立即停止。
var btn = document.getElementsByClassName('top_button');
for (var i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', function() { /* some here */ }));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.