论坛首页 Web前端技术论坛

Pro JavaScript Techniques一处错误的代码

浏览 2168 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-03-31   最后修改:2011-04-01

Pro JavaScript Techniques中文版256页的例子代码有误, 原版给出的例子就已经错误了
Listing A-30. Converting a Set of Links Into Plain URLs

// Convert all links to visible URLs (good for printing
// Find all <a> links in the document
var a = document.getElementsByTagName("a");
//首先这边循环不能用while, while ( a.length )只是判断a是否包含length属性, 在这边只要存在<a>元素,
//那么
document.getElementsByTagName("a") 返回一个NodeList, 即a, 同时这个NodeList包含length属性,
//这样将陷入死循环

while ( a.length ) {
  // Create a <strong> element
  var s = document.createElement("strong");
  // Make the contents equal to the <a> link URL
  // 因为用的while循环, 这边的i未定义
  s.appendChild( document.createTextNode( a[i].href ) );
  // Replace the original <a> with the new <strong> element
  // 这边的错误是replaceChild, 先不管i, 假设a[i]引用某个<a>元素
  // 那么这边的代码也应该是这么写的
a[i].parentNode.replaceChild( s, a[i] );
  a[i].replaceChild( s, a[i] );
}

以下是demo
<html>
<head>
</head>
<body>
<a href=" www.163.com ">163</a>
<a href=" www.sina.com ">新浪</a>
<script type="text/javascript">

  var a = document.getElementsByTagName( 'a');
  // 这是我修改后的代码
  for(var i=a.length-1;i>=0;i--){
      var s = document.createElement(' strong');
      s.appendChild(document. createTextNode(a[i].href))
      a[i].parentNode.replaceChild( s, a[i]);
  }
 
  /**
  var a = document.getElementsByTagName("a");
while ( a.length ) {
  // Create a <strong> element
  var s = document.createElement("strong");
  // Make the contents equal to the <a> link URL
  s.appendChild( document.createTextNode( a[i].href ) );
  // Replace the original <a> with the new <strong> element
  a[i].replaceChild( s, a[i] );
}*/
</script>
</body>
</html>

   发表时间:2011-04-14  
总结的不错,受益非浅啊,谢谢LZ的分享
0 请登录后投票
   发表时间:2011-04-14  
真的吗?getElementsByTagName('a')返回的NodeList称为LiveNodeList,即会根据DOM当前的状态有所变化
在循环中,有把a使用strong替换的逻辑,即这个a元素会消失,一但a元素从DOM中移除,那么他在这个NodeList中也会消失,导致list.length减1
最后这个length会变成0,因此我认为这个代码没有错误
0 请登录后投票
   发表时间:2011-04-14  
同时我认为你的代码才是有问题的,会导致某些a元素没有被转成strong
不知你有没有试过这段代码
当然书中的代码确实有错误:
1、循环体里应该始终是a[0]而不是a[i],这里根本没有i
2、最后是a[0].parentNode.replaceChild,而不是直接对a[0]调用replaceChild

只不过错误不是你说的while的问题
0 请登录后投票
   发表时间:2011-04-14  
好吧,你是从后到前的逆循环,那确实你的代码也没问题……
0 请登录后投票
   发表时间:2011-04-15   最后修改:2011-04-15

getElementsByTagName返回的确实是一个live NodeList, 注意不是LiveNodeList, 没有这个对象的, 所谓的live NodeList我的理解是这个NodeList会随着文档中DOM的变化而实时地得到更新.
就像我的例子, getElementsByTagName("a")返回一个包含<a>元素的的NodeList, 然后将里面的<a>元素替换成<strong>, 这时候这个NodeList就不断的缩小, 当全部<a>元素被替换成<strong>元素时, a.length也就等于0了, 因为javascript是弱类型的, 所以此时while(a.length) == while(0) == while(false), 即跳出循环.
这个问题我确实没有考虑到, 大牛毕竟是大牛

 

<html>
<head>
<title>W3C DOM tests - NodeList</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<a href=" www.163.com ">163</a>
<a href=" www.sina.com ">新浪</a>
<script type="text/javascript" >
var a = document.getElementsByTagName("a");
alert('a.length before replace: '+a.length);
while ( a.length ) {
  var s = document.createElement("strong");
  s.appendChild( document.createTextNode( a[0].href ) );
  //看看替换的元素也是a元素时这个NodeList会不会缩减
  //var s = document.createElement('a');
  //a.href = a[0].href;
  a[0].parentNode.replaceChild( s, a[0] );
  alert('a.length after replace: '+a.length);
}
alert(a.length == false); 
</script>
</body>
</html>
 

再给出一个例子, 下面的代码会陷入无限循环:

 

var divs = document.getElementsByTagName("div");
for (var i=0; i < divs.length; i++){
  var div = document.createElement(“div”);
  document.body.appendChild(div);
}

 divs会随着document.body.appendChild(div)而得到更新

0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics