我正在使用jQuery在网站上工作,但我不再尝试使用它了。在jQuery中,您可以在网站上没有创建的元素上添加偶数监听器,或者尚未创建且没有问题。当你登录时我有只在DOM上的元素,我只有一个JS文件用于整个网站。
问题是,例如,当您登录时,您无法看到"登录"按钮,它甚至不在DOM中,但它仍然在代码中有事件监听器,控制台上没有错误,脚本运行良好。
$("#logInButton").on("click", somefunction);
但是,使用document.querySelector("#logInButton").onclick = somefunction
并且已经登录,它会抛出错误,因为document.querySelector("#logInButton")
为空。
我可以这样做:
let logInButton = document.querySelector("#logInButton");
logInButton ? logInButton.onclick = somefunction : "";
它运作良好,但我知道这不是一个好习惯。任何解决方法或改进,而不是使用jQuery?
答案 0 :(得分:2)
它运作良好,但我知道这不是一个好习惯。
如果页面上有#logInButton
是可选的,那么这是非常好的做法 - 除了使用onclick
而不是addEventListener
(但这可能是一种风格问题)。当然,您可以在文档的 end 链接的脚本中使用此代码,就在</body>
标记之前(或通过DOMContentLoaded
回调触发它)。
但是如果你想要相当于jQuery,你需要考虑jQuery的“基于集合”的思维模式并使用querySelectorAll
:
// Not very efficient
document.querySelectorAll("#logInButton").forEach(function() {
// Set up the handler here using `this`
});
除了jQuery使用#id
格式优化查询到getElementById
调用(显着更快),然后使用if
(和你的一样)来用一个元素或零构建集合。
也许在你不使用jQuery的过程中,你可能会给自己一些辅助函数来代替它,因为DOM API非常详细。如果您喜欢jQuery基于集合的特性,您甚至可以将它们设置为基于集合:
function MyQuery(selector) {
if (!selector) {
this.data = [];
} else if (typeof selector === "string") {
// (jQuery takes it further than this, search in an unminified version for `rquickExpr`)
var id = /#([\w-]+)/.match(selector);
if (id) {
var e = document.getElementById(id[0]);
this.data = e ? [e] : [];
} else {
this.data = Array.from(document.querySelector(selector));
}
} else {
/* ...handle other things, such as DOM elements or arrays of them...? */
this.data = /*...*/;
}
}
MyQuery.prototype = {
constructor: MyQuery,
on: function(eventName, handler) {
this.data.forEach(function(element) {
element.addEventListener(eventName, handler);
});
return this;
}
// ...etc...
};
function qset(selector) {
return new MyQuery(selector);
}
然后
qset("#logInButton").on("click", /*...*/);
当然,您可能会发现自己基本上正在重新创建jQuery。但如果你保持精益......
附注:在forEach
的返回值上使用querySelectorAll
需要最新的浏览器,或者您需要填充它:
if (typeof NodeList !== "undefined" &&
NodeList.prototype &&
!NodeList.prototype.forEach) {
Object.defineProperty(NodeList.prototype, "forEach", {
value: Array.prototype.forEach
});
}
对于真正过时的浏览器(如IE8),您必须先填充Array.prototype.forEach
。
答案 1 :(得分:0)
你可以像jQuery一样使用事件冒泡来完成它。
document.addEventListener('click', function (ev) {
if (ev.target.id === 'someIdHere') {
console.log('click');
}
});