jQuery 选择器和JS getElementById 二者返回值的一点区别

时间:2024-11-18 09:40:33

今天学习AJAX的过程中,有两段示例代码,其中一段如下(另一段类似):

  1. <div id="navigation">
  2.               <a id="beginners" title="beginners" href="#">Beginners</a>
  3.               <a id="intermediate" title="intermediate" href="#">Intermediate</a>
  4.               <a id="advanced" title="advanced" href="#">Advanced</a>
  5.          </div>
 

两段代码均做类似处理:

  1. var buttons = document.getElementById("navigation").getElementsByTagName("a");
  2.    for (const i in buttons) {
  3.        var currentBtn = buttons[i];
  4.        currentBtn.onclick = showTab;
  5.        currentBtn.onmouseover = buttonOver;
  6.        currentBtn.onmouseout = buttonOut;
  7.   }

因为刚刚学习了jQuery所以我想用jQuery对其进行处理,所以我改为了如下代码:

  1. var buttons = $("#navigation a");
  2. for (const i in buttons) {
  3. var currentBtn = buttons[i];
  4. // = showHint;
  5. // = hideHint;
  6. // = showTab;
  7. // = buttonOver;
  8. // = buttonOut;
  9. $(currentBtn).mouseover(showHint);
  10. $(currentBtn).mouseout(hideHint);
  11. $(currentBtn).click(showTab);
  12. $(currentBtn).mouseover(buttonOver);
  13. $(currentBtn).mouseout(buttonOut);
  14. }

 

当两段代码都用jQuery替换时,运行界面会出现如下错误:

 

无奈,只能照抄书上,全部按JS写法,运行正常,于是我想着到底是怎么回事呢?

众所周知,()会获取DOM中第一个符合id的标签,而getElementsByTagName()则会返回符合标签名的所有标签,返回值是一个数组,对其所有处理必须使用下标;而jQuery的返回值则是一个jQuery元素,不能使用JS的方法,为了更直观的展现,我将两段代码一个用JS获取,一个用jQuery获取,并打印出来给大家看:

其中init是我的页面初始化函数,上面的是采用jQuery获取元素的返回值,下面的是JS获取的返回值,二者代码如下:

  1. var tabs = $("#tabs a");
  2. var buttons = document.getElementById("navigation").getElementsByTagName("a");

如果只是想把jQuery的获取对象使用JS的方法,只需要对其取下标[0]即可或者使用.get[0],比如$(currentTab)[0].onmouseover = showHint;等价于$(currentTab).mouseover(showHint);

而DOM对象转换为jQuery对象只需要加$即可:$(DOM)

但是对于我的代码而言,如果第一段出错,即toJSON错误,那么第一段功能正常,第二段无论使用jQuery还是JS都会失效,如果第二段是用jQuery出现toJSON错误,那么第一段第二段都正常(出现错误的那一段代码可以正常运行),这个原因我还没有查明,如果有大佬知道可以和我联系,谢谢!

—————————————————————手动分割线——————————————————————————————

 

后续来了,找了个学长问了下,确实是循环那里的问题,当时我debug的时候有想到,但是第一次修改后出现了其他bug,所以没有在意,以为循环没有问题,但现在重新debug后证实了确实是循环的问题:

Javascript 大忌之不要用for in语句对数组进行遍历

for in语句对一个数组进行遍历,如果原生Array类被其他脚本库扩展过,比如我遇到的toJOSN属性,那么会多循环一次,这将会是代码的逻辑发生错误,所以对于数组来说一定要用基本循环for(var i = 0; i < length; i++)

此处也引用一位大佬的博客,看了后受益匪浅https://m./article/?tdsourcetag=s_pctim_aiomsg

  1. var x=[1];
  2. for(var s in x){
  3. alert(s);
  4. };

按常理,如果Array是原生js类,上面语句应该只执行一次alert方法,且s为数组的索引0。但是,如果Array类被扩展了,多了一个toJSON方法,那么上面的语句将执行两次alert,第一次s为索引0,第二次s为方法名'toJSON'。

如果你设计的代码的逻辑以原生Array类为基准,在某一天你的同事在页面里面引用了一个第三方的JS库,这个库又恰好扩展了Array类,结果将难以想象,很有可能原来的代码逻辑将不再成立。