最近研究了下原生js,发现其中的地雷很多。以前的时候每次写js只用借助于jquery这种js框架来写,所以每次写完之后都觉得很方便,而且很快,不用考虑过多的兼容性处理问题。但是最近觉得还是得研究下原生js,就用原生js写了两个小游戏,收获颇多。(下面会将两个游戏的代码放上去:贪吃蛇和扫雷)
原生js在获取dom元素时,除了document.getElementById()外,其他的方式都会得到一个数组。然后用for循环遍历这个数组的时候,如果对数组里面的元素进行的操作是查找时候的条件或者是删除了这个dom元素,那么这个元素会从数组里面自动移除掉。(用jquery是一定不会存在这个问题的)
例如:有一组class='area'的div,这时我们需要修改其className。
一般写法为(方法一):
var _divArr = document.getElementsByClassName('area');
var divLength;
for(var i=0;0<divLength;i++){
_divArr[i].className = 'othersName';
}
但是这种情况下产生的效果却不是我们想要的,会发现每次是间隔一个div变化一次,而且会报‘Cannot set property 'className' of undefined’这种错误。这是什么原因呢?!
主要是由于每次操作这个dom元素的时候,原生js会自动再通过原来的查找条件再来查找一次,这里是通过document.getElementsByClassName('area')进行查找的,但是此时刚刚修改了classname的dom元素类名已经修改了,这样_divArr数组就发生了变化,其leng也减小了,这样就导致每次修改的都是隔行数据,而且最后还会报js错误。
其解决方案为(方法二):
var _divArr = document.getElementsByClassName('area');
var divLength;
for(var i=0;0<divLength;i++){
_divArr[0].className = 'othersName'; //0 与 i的区别
}
原生JS总结1(操作遍历的dom元素):
1、如果查找dom的时候用document.getElementsByClassName(),操作时是修改className,那么一定要用方法二,方法一会报上述的错误。
2、但是如果这里将_divArr通过document.getElementsByTagName('div')来查找的话,再修改每个dom元素的className的时候用第一种方法即可。用第二种方法只会修改第一个dom元素。
3、如果在操作的时候也就是for循环里面是需要删除掉这些div,那么不管_divArr是通过哪种方式来查找的,都只能通过方法二来处理,因为这里没删除一个,js自动在查找一次,变换_divArr的长度,也就是将刚刚删除掉的dom元素从数组中移除掉。(removeChild)