JavaScript方法undefined/null原因探究及闭包简单实现

昨天一个刚写前端不久的同学发消息问这个问题(如下图):

HTML代码为(省略部分代码):

1 <head>
2 <script src="test.js"></script>
3 </head>
4 <body>
5     <div id="output">0</div>
6     <button id="plus">+1</button>
7     <button id="minus">-1</button>  
8 </body>

 test.js最初代码为:

1 var plus=document.getElementById(‘plus‘);
2 var minus=document.getElementById(‘minus‘);
3 var output=document.getElementById(‘output‘);
4 plus.addEventListener(‘click‘,function(){
5     console.log(‘+1‘);
6 },false);

结果就为控制台报出了“Uncaught TypeError: Cannot read property ‘addEventListener‘ of null”的错误,究其原因,是因为在HTML的DOM结构未加载完成时,就已经加载好js文件,并对DOM元素进行绑定事件操作,因此不能会报出null的错误,有时也可能会出现undefined的错误。

解决这个问题的方法,可以从以下两种方式就行考虑:

一、在HTML文件中将<script>放在DOM最后加载,即:

1 <body>
2     <div id="output">0</div>
3     <button id="plus">+1</button>
4     <button id="minus">-1</button>
5     <script src="test.js"></script>  
6 </body>

二、在js代码块放到window.onload事件中,待基本文档结构加载完成后再执行事件绑定:

1 window.onload = function() {
2     var plus = document.getElementById(‘plus‘);
3     var minus = document.getElementById(‘minus‘);
4     var output = document.getElementById(‘output‘);
5     plus.addEventListener(‘click‘, function() {
6     console.log(‘+1‘);
7     }, false);
8 }

当然了,这个也可以用jQuery的ready函数做,原理类似。PS:前些天面试时遇到了这样一个问题:说一说DOMContentLoaded事件、onload事件和jq的ready事件,实际上是有所区别的,一篇博文就说说这个问题,先留个坑。

然后这个问题就解决掉了,下面就是完成功能了,要求按“+1”按钮时,数字+1;按“-1”按钮时,数字-1;

当然了,这个问题比较容易,了解下作用域和闭包就能写出来了,也给同学做了出来。HTML代码还是如上,下面是完整的JavaScript代码:

 1 window.onload = function() {
 2     var plus = document.getElementById(‘plus‘);
 3     var minus = document.getElementById(‘minus‘);
 4     var output = document.getElementById(‘output‘);
 5     var num=output.innerText;
 6     var count = function(event){
 7         var target=event.target;
 8          switch(target.id){
 9             case ‘plus‘:
10           num++;
11           output.innerText=num;
12             break;
13 
14             case ‘minus‘:
15           num--;
16           output.innerText=num;
17             break;
18         }
19     };
20     document.addEventListener(‘click‘,count,false);
21 }

最终运行效果如下:

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。