【问题标题】:addEventListener is not working if put it in head section rather then body如果将 addEventListener 放在 head 部分而不是 body 中,则 addEventListener 不起作用
【发布时间】:2017-11-30 19:51:41
【问题描述】:

我真的不知道为什么这不起作用。在我的 HTML 中,如果我将脚本放在 head 部分,我会在控制台中收到以下错误:

Uncaught TypeError: Cannot read property 'addEventListener' of null

如果我将脚本放在正文的底部,它就可以正常工作。

HTML:

<head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <script type="text/javascript" src="script.js"> </script>
</head>

<body>
    <ul>
        <li><a href="#" data-img="img1" id="img1"> Shahin </a></li>
        <li><a href="#" data-img="img2" id="img2"> Lina   </a></li>
        <li><a href="#" data-img="img3" id="img3"> Adrita </a></li>
    </ul>
    <img src="./img/1.jpg" class="hidden">
    <img src="./img/2.png" class="hidden">
    <img src="./img/3.jpg" class="hidden">
</body>

JavaScript:

var shahin = document.getElementById('img1');
var lina = document.getElementById('img2');
var adrita = document.getElementById("img3");

shahin.addEventListener('click',picShow);
lina.addEventListener('click',picShow);
adrita.addEventListener('click',picShow);

function picShow() {
    console.log(this);
}

谁能告诉我我做错了什么以及放置脚本标签的正确位置在哪里?另外,我应该做些什么改变来从头部分运行我的脚本?我会很高兴你的回答。提前致谢

【问题讨论】:

  • 必须加载 DOM 才能获取元素并附加侦听器。如果您的代码在头部,则在脚本运行之前 DOM 尚未加载。将您的代码包装在 onload 或准备好的包装器中,或者将您的代码移动到 HTML 下
  • 如果它在头部,你需要把它放在$(document).ready()中,因为当你添加处理程序时你的身体还没有被渲染
  • @jdubjdub,只适用于 jQuery。
  • 无论你想使用什么就绪状态的东西都可以 - 只是在 DOM 加载后运行的东西

标签: javascript html


【解决方案1】:

您的脚本在正文 HTML 的其余部分之前加载和执行,所以很自然,document.getElementById 将返回 null。

您应该在document.ready 事件上或之后运行您的事件侦听器订阅代码。

将您发布的代码包装成一个 JS 函数,然后将该函数设置为要在 document.ready 上执行的回调:

document.addEventListener('load', initFn);

【讨论】:

  • DOMContentLoaded 会工作。不太确定onload。
  • w3schools 网站不再准确了吗? w3schools.com/jsref/event_onload.asp
  • 我尝试使用此代码,但它没有在控制台上显示任何内容...但也没有错误document.addEventListener('onload',function abc() { var shahin = document.getElementById('img1'); var lina = document.getElementById('img2'); var adrita = document.getElementById("img3"); shahin.addEventListener('click',picShow); lina.addEventListener('click',picShow); adrita.addEventListener('click',picShow); function picShow() { console.log(this); } });
  • 我编辑了我的答案——尝试使用“load”而不是“onload”作为事件的名称
【解决方案2】:
<script type="text/javascript" defer src="script.js"> </script>

添加关键字defer,脚本在所有DOM元素加载完成后运行

【讨论】:

    【解决方案3】:

    如果你把你的&lt;script&gt; 放在&lt;head&gt; javascript 加载从上到下。
    所以加载时它返回未定义的事件监听器。
    因此,请尝试在 &lt;/body&gt; 标签结束之前使用该脚本,它会起作用。
    像这样:

    <script type="text/javascript" src="script.js"> </script>
    </body>
    

    【讨论】:

    • 谁能告诉我我应该做些什么改变才能从头开始处理脚本?我尝试使用 document.addEventListener('onload',function abc() { 并将整个代码包装在其中...仍然无法正常工作...
    【解决方案4】:

    Josh E 的进一步回答:

    您应该在 document.ready 事件上或之后运行您的事件监听器订阅代码

    如果您想在元素可用时立即执行代码,可以在页面加载期间使用requestAnimationFrame 扫描 DOM,而不是等待整个页面加载:

    function doSomethingWithElement(myElement) {
        myElement.addEventListener('click', function() {
            // Do stuff here
        });
    }
    
    function searchForElement() {
        const el = document.getElementById('img1');
        if (el) {
           return doSomethingWithEl(el); 
        }
        window.searchID = window.requestAnimationFrame(searchForElement);
    }
    
    // Store the request ID so it can be cancelled later
    // Otherwise it'll run forever!
    window.searchID = window.requestAnimationFrame(searchForElement);
    window.addEventListener('load', function() {
        window.cancelAnimationFrame(window.searchID);
    });
    

    这可能有点矫枉过正,但当您想尽快操作或向 DOM 元素添加侦听器时,它非常有用。

    【讨论】:

      猜你喜欢
      • 2020-06-15
      • 2012-04-03
      • 2013-04-04
      • 1970-01-01
      • 2021-04-19
      • 2013-03-16
      • 2018-05-15
      • 2015-06-12
      • 1970-01-01
      相关资源
      最近更新 更多