我必须为项目使用vanilla JavaScript。我有一些功能,其中一个是打开菜单的按钮。它适用于目标ID存在的页面,但会导致id不存在的页面出错。在那些函数找不到id的页面上,我收到一个“无法读取属性'addEventListener'的null”错误,我的其他函数都没有工作。
以下是打开菜单的按钮的代码。
function swapper() {
toggleClass(document.getElementById('overlay'), 'open');
}
var el = document.getElementById('overlayBtn');
el.addEventListener('click', swapper, false);
var text = document.getElementById('overlayBtn');
text.onclick = function(){
this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
return false;
};
我该如何处理?我可能需要将所有代码包装在另一个函数中或使用if / else语句,以便它只搜索特定页面上的id,但不确定。
答案 0 :(得分:139)
我认为最简单的方法是在添加事件监听器之前检查el
是否为空:
var el = document.getElementById('overlayBtn');
if(el){
el.addEventListener('click', swapper, false);
}
答案 1 :(得分:80)
似乎document.getElementById('overlayBtn');
正在返回null
,因为它在DOM完全加载之前执行。
如果你把这行代码放在
下面window.onload=function(){
-- put your code here
}
然后它会毫无问题地运行。
示例:
window.onload=function(){
var mb = document.getElementById("b");
mb.addEventListener("click", handler);
mb.addEventListener("click", handler2);
}
function handler() {
$("p").html("<br>" + $("p").text() + "<br>You clicked me-1!<br>");
}
function handler2() {
$("p").html("<br>" + $("p").text() + "<br>You clicked me-2!<br>");
}
答案 2 :(得分:16)
我遇到了类似的情况。这可能是因为脚本在页面加载之前执行。通过将脚本放在页面底部,我绕过了问题。
答案 3 :(得分:12)
我收到同样的错误,但执行空检查似乎没有帮助。
我找到的解决方案是将我的函数包装在整个文档的事件监听器中,以检查DOM何时完成加载。
document.addEventListener('DOMContentLoaded', function () {
el.addEventListener('click', swapper, false);
});
我认为这是因为我使用的是一个动态更改我的HTML类和ID的框架(Angular)。
答案 4 :(得分:9)
将脚本放在body标签的末尾。
<html>
<body>
.........
<script src="main.js"></script>
</body>
</html>
答案 5 :(得分:8)
脚本在正文之前加载,脚本在内容之后
答案 6 :(得分:4)
只是因为您的JS在HTML部分之前被加载,所以找不到该元素。只需将整个JS代码放在一个函数中,该函数将在加载窗口时调用。
您还可以将Javascript代码放在html下方。
答案 7 :(得分:3)
感谢@Rob M.的帮助。这就是最后一段代码的样子:
function swapper() {
toggleClass(document.getElementById('overlay'), 'open');
}
var el = document.getElementById('overlayBtn');
if (el){
el.addEventListener('click', swapper, false);
var text = document.getElementById('overlayBtn');
text.onclick = function(){
this.innerHTML = (this.innerHTML === "Menu") ? "Close" : "Menu";
return false;
};
}
答案 8 :(得分:3)
如果您的 js 代码是外部文件,请使用这种方式:
<script src="filename.js" defer></script>
如果您的代码是内部文件,请使用 DOMContentLoaded
以上两种方式可以确保DOM在执行js代码之前完全加载!
答案 9 :(得分:2)
我遇到了同样的问题,并检查是否为null,但没有帮助。因为脚本是在页面加载之前加载的。因此,只需将脚本放在end body标签之前即可解决该问题。
答案 10 :(得分:1)
我只是将'async'添加到我的脚本标记中,这似乎解决了这个问题。我不知道为什么,如果有人可以解释,但它对我有用。我的猜测是页面没有等待加载脚本,所以页面与JavaScript同时加载。
Async / Await使我们能够以同步方式编写异步代码。它只是使用生成器和yield语句来“暂停”执行的语法糖,使我们能够将它分配给变量!
这是参考链接 - https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da
答案 11 :(得分:1)
这个问题已经有了答案,但我喜欢为那些简单的条件做的是使用逻辑 AND (&&) 运算符:
var el = document.getElementById('overlayBtn');
el && el.addEventListener('click', swapper, false);
我认为更具可读性和简洁性。
答案 12 :(得分:0)
谢谢大家, 在您使用的特定页面上加载脚本,而不是在所有页面上加载脚本,有时使用swiper.js或其他库可能会导致此错误消息,这是解决此问题的唯一方法,是在存在ID的特定页面上加载JS库并防止在所有页面中加载相同的库。
希望这对您有所帮助。
答案 13 :(得分:0)
我遇到了同样的问题,但是我的身份证已经出现。所以我尝试添加“ window.onload = init;”然后,我用一个init函数包装了原始的JS代码(称其为您想要的)。这行得通,因此至少就我而言,我在加载文档之前添加了一个事件侦听器。这也可能是您正在经历的事情。
答案 14 :(得分:0)
我有一系列引号和名字。我使用更新按钮更新与特定名称关联的最后一个引用,但是在单击更新按钮时它没有更新。我包括下面的代码,用于server.js文件和外部js文件(main.js)。
var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {
fetch('quotes', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'name': 'Muskan',
'quote': 'I find your lack of faith disturbing.'
})
})var update = document.getElementById('update');
if (update){
update.addEventListener('click', function () {
fetch('quotes', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'name': 'Muskan',
'quote': 'I find your lack of faith disturbing.'
})
})
.then(res =>{
if(res.ok) return res.json()
})
.then(data =>{
console.log(data);
window.location.reload(true);
})
})
}
app.put('/quotes', (req, res) => {
db.collection('quotations').findOneAndUpdate({name: 'Vikas'},{
$set:{
name: req.body.name,
quote: req.body.quote
}
},{
sort: {_id: -1},
upsert: true
},(err, result) =>{
if (err) return res.send(err);
res.send(result);
})
})
答案 15 :(得分:0)
正如其他人所说的问题是脚本是在页面(特别是目标元素)加载之前执行的。
但我不喜欢重新排序内容的解决方案。
首选解决方案是在页面onload事件上放置一个事件处理程序,并在其中设置Listener。这将确保在执行赋值之前加载页面和目标元素。例如
<script>
function onLoadFunct(){
// set Listener here, also using suggested test for null
}
....
</script>
<body onload="onLoadFunct()" ....>
.....
答案 16 :(得分:0)
您的脚本可能位于 HTML 的 head 标记中,并且在 DOM 加载之前加载。对此可以有两种解决方案:
</body>
) 之前。async
关键字添加到您的脚本标记中。脚本异步src="script.js">
注意:出于安全原因,Stackoverflow 不允许在此处添加脚本标记代码。在上面的代码中添加左括号和右括号。
使用 async
,文件被异步下载,然后在下载后立即执行。
我更喜欢第二个选项。详细了解异步和延迟 here
答案 17 :(得分:-1)
这是因为在执行bundle js时尚未加载元素。
我将<script src="sample.js" type="text/javascript"></script>
移到index.html
文件的最底部。这样,您可以确保在解析和呈现所有html元素之后执行脚本。
答案 18 :(得分:-3)
在窗口加载时添加所有事件侦听器。无论您在何处放置脚本标记,都会像魅力一样。
window.addEventListener("load", startup);
function startup() {
document.getElementById("el").addEventListener("click", myFunc);
document.getElementById("el2").addEventListener("input", myFunc);
}
myFunc(){}