对不存在的元素进行转义的常用方法是什么(如jQuery)

What is the usual approach to escape an element which is non existing (like jQuery does)

本文关键字:是什么 jQuery 方法 转义 元素 不存在 常用      更新时间:2023-09-26

如果我有

var btn = document.getElementsByClassName('top_button')[0];
btn.addEventListener('click', function() { /* some here */ }));

未定义我得到一个CCD_ 1。我想知道逃避这种情况的通常方法是什么。会是吗

var btn = document.getElementsByClassName('top_button')[0] || {};

还是我应该采取不同的做法?jQuery是如何做到这一点的,因为当我使用$('.top_button')时,元素不在那里,它只返回一个对象。

感谢

如果你真的只想要第一个,那么我同意Praveen的观点,if是最清晰、最简单的解决方案,尽管我通常在不同的地方做:

var btn = document.getElementsByClassName('top_button')[0];
if (btn) {
  btn.addEventListener('click', function() { /* some here */ }));
}

如果您要求的索引中没有元素(就像JavaScript数组一样),那么getElementsByClassName可靠地跨浏览器返回的集合将为您提供undefined

但我会使用querySelector而不是getElementsByClassName,因为你只想要第一个,不需要构建列表,而且querySelector在所有现代浏览器上都有,IE8也有(而IE8缺少getElementsByClassName)。

var btn = document.querySelector('.top_button');
if (btn) {
  btn.addEventListener('click', function() { /* some here */ }));
}

TypeError0接受任何CSS选择器(包括复杂的选择器)并返回第一个匹配元素或null。它的表亲querySelectorAll返回一个列表(如果没有匹配,则可以为空)。

如果您想将事件挂在所有匹配元素上,Quentin会为您提供服务。


jQuery是如何做到这一点的,因为当我使用$('.top_button')时,元素不在那里,它只返回一个对象。

jQuery对象是DOM元素集的包装器(通常,它们可以是其他东西的包装器,但在典型的使用中,它们是DOM元素)。因此,当你执行$('.top_button')时,你会得到一个jQuery对象,它是一个集合的包装器,里面什么都没有。你可以对这个jQuery对象进行调用,比如.on,它们不会失败(因为jQuery对象存在),但它们也不做任何事情(因为集合中没有元素可供它做任何事情)。

我不是建议这样做,但你也可以用querySelectorAll自己做同样的事情。(jQuery比querySelectorAll早了几年,最初John Resig为它构建了一个完整的选择器引擎。现代浏览器在类似jQuery的东西中没有必要这样做,除非你想添加自己的CSS选择器,比如jQuery的:has。)

只是为了说明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;
};

用法:

new DomQuery(".top_button").on("click", function() {
    // do something
});

我们可以通过使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;
};

用法:

domQuery(".top_button").on("click", function() {
    // do something
});

您可以使用一个简单的if:

var btn = document.getElementsByClassName('top_button');
if (btn.length > 0) {
  btn = btn[0];
  btn.addEventListener('click', function() { /* some here */ }));
}

或者您也可以检查typeof是否为"undefined"

正如@PraveenKumar的回答,您可以检查长度,但也可以检查是否未定义变量

if (typeof btn === "undefined") {
    //do stuff here.
}
jQuery将所有结果存储在一个数组中。当您调用on时,它会在该数组上循环,并将事件处理程序应用于其中的每个项。如果没有项,则标准的for循环将立即停止。
var btn = document.getElementsByClassName('top_button');
for (var i = 0; i < btn.length; i++) {
  btn[i].addEventListener('click', function() { /* some here */ }));
}