hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
阅读:1268回复:4

【已解决】为什么不能一次过清掉全部链接呢[脚本]?

楼主#
更多 发布于:2015-01-19 10:48
我突发奇想,想对360的链接眼不见为干净……
function fixlnk() {  
    var Links = document.body.getElementsByTagName('a'); 
    if (!Links[0]) return;
    for(_i = 0; _i < Links.length; _i++) {
        if (Links[_i].href && Links[_i].href.match(/^http:\/\/.*\.qihoo\.com/i)) {
        Links[_i].parentNode.removeChild(Links[_i]); //console.log(_i+":"+Links[_i].href);
        }
    }
}
这是目标网页:http://paper.nandu.com/nis/201407/25/248116_5.html

这是网页右侧栏原始的效果:

图片:aa0.png



然后我使用延时语句启用上述函数:
setTimeout(fixlnk, 1000);
结果变成这样:

图片:aa1.png



检查过输出,链接在数组的次序是连续的,在DOM的结构中其上层结构是连续的,不存在链接嵌套的情况。出现这种清理不全的问题很奇怪。。。
既然是一次不全,再来一次:
setTimeout(fixlnk, 1000);
setTimeout(fixlnk, 500);
可惜并没有如愿以偿:

图片:aa2.png



好吧:
setTimeout(fixlnk, 1000);
setTimeout(fixlnk, 500);
setTimeout(fixlnk, 500);

图片:aa3.png





那么问题来了,为什么会出现这种情况?这种链接遍历的写法我在别的地方也用也没出现这样隔一个链接的情况啊。还是说DOM结构的问题?但是我没看出来啊。
喵拉布丁
火狐狸
火狐狸
  • UID47116
  • 注册日期2014-08-25
  • 最后登录2022-05-03
  • 发帖数109
  • 经验125枚
  • 威望0点
  • 贡献值18点
  • 好评度11点
  • 社区居民
  • 忠实会员
1楼#
发布于:2015-01-19 17:36

function fixlnk() { 
    var Links = document.body.getElementsByTagName('a');
    if (!Links[0]) return;
    for(var _i = Links.length-1; _i >=0; _i--) {
        if (Links[_i].href && Links[_i].href.match(/^http:\/\/.*\.qihoo\.com/i)) {
        Links[_i].parentNode.removeChild(Links[_i]); //console.log(_i+":"+Links[_i].href);
        }
    }
}
你每次removeChild的时候,Links数组都在变化,所以应该反过来移除
你要吃布丁吗?
aaaa007cn
千年狐狸
千年狐狸
  • UID23968
  • 注册日期2008-05-03
  • 最后登录2022-03-07
  • 发帖数1924
  • 经验1138枚
  • 威望1点
  • 贡献值232点
  • 好评度164点
2楼#
发布于:2015-01-19 20:01
补文档
https://developer.mozilla.org/en-US/docs/Web/API/element.getElementsByTagName
The returned list is live, meaning that it updates itself with the DOM tree automatically.


你被 console.log(_i+":"+Links[_i].href); 坑了
因为这里所有匹配的输出全部都是同一个 href
所以没法注意到 Links 本身的变化
如果这里 href 不同的话你肯定马上就能发现问题的

观察到移除节点后总是会跳过一个
debug 时应该考虑连 Links.length 一起输出
console.log(_i+"/"+Links.length+":"+Links[_i].href);

话说为什么不直接设置 display:none?
直接插条 css 就好了呀
a[href^="http://sh.qihoo.com/"] {
display:none;
}
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
3楼#
发布于:2015-01-20 09:20
谢  喵拉布丁  和  aaaa007cn ,将循环语句从加变成减反过来操作就可以了。
想不到元素数组居然是 live 的……

至于为什么不用CSS,我就是想将其完全移除,这样连复制的时候也不会带上了
taoww
非常火狐
非常火狐
  • UID39284
  • 注册日期2013-03-18
  • 最后登录2024-04-25
  • 发帖数627
  • 经验573枚
  • 威望0点
  • 贡献值110点
  • 好评度99点
4楼#
发布于:2015-01-20 11:49
准确地说,getElementsByTagName返回的是HTMLCollection(webkit系的document.getElementsByTagName返回的是NodeList),并非Array。

从DOM中搞来的HTMLCollection总是live的,NodeList在部分情况下(包含getElementsByTagName的返回值)是live的。

要用静态的NodeList,可以用document.querySelectorAll("a")

参考资料:
https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByTagName
https://developer.mozilla.org/en-US/docs/Web/API/Element.getElementsByTagName
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
https://developer.mozilla.org/en-US/docs/Web/API/NodeList#A_sometimes-live_collection
游客

返回顶部