Javascript getElement by href?

Posted

技术标签:

【中文标题】Javascript getElement by href?【英文标题】:Javascript getElement by href? 【发布时间】:2012-05-21 07:29:16 【问题描述】:

我有下面的脚本

var els = document.getElementsByTagName("a");
for(var i = 0, l = els.length; i < l; i++) 
  var el = els[i];
  el.innerhtml = el.innerHTML.replace(/link1/gi, 'dead link');

但是,这会搜索整个页面,并且需要大约 20 秒才能完成,因为有很多链接。

但是我只需要定位具有特定hrefa,例如。 "http://domain.com/"

所以理想情况下,我希望能够以与 jQuery 类似的方式执行此操作,但不使用框架。所以像

var els = document.getElementsByTagName("a[href='http://domain.com']");

我该怎么做才能只搜索与href匹配的对象?

【问题讨论】:

您想支持哪些浏览器?您可以尝试document.querySelectorAll 看看它是否有所作为,但此方法在 IE7 及更早版本中不可用。另一种可能性是使用 CSS3 来更改外观和/或添加一些额外的文本。 @FelixKling querySelectorAll 能有这么大的不同吗?看来 OP 的代码已经很简单了.. 除非没有显示所有代码:) 我只想编写一个函数来处理所有链接的 onclick。然后,一旦有人单击该链接,您就可以根据需要进行更改。 @Jack:我不知道querySelectorAll 在内部是如何工作的。但这就是 OP 应该尝试测试它的原因。 @Jack 代码是裸露的,但它使用的属性计算成本很高。 【参考方案1】:

2016 年更新

这个问题发布已经 4 年多了,事情有了很大进展。

不能使用:

var els = document.getElementsByTagName("a[href='http://domain.com']");

但您可以使用的是:

var els = document.querySelectorAll("a[href='http://domain.com']");

注意:浏览器支持见下文)

这将使您问题中的代码完全按照您的预期工作

for (var i = 0, l = els.length; i < l; i++) 
  var el = els[i];
  el.innerHTML = el.innerHTML.replace(/link1/gi, 'dead link');

如果你想要所有'http://domain.com'开始的链接,你甚至可以使用a[href^='http://domain.com']之类的选择器:

var els = document.querySelectorAll("a[href^='http://domain.com']");

for (var i = 0, l = els.length; i < l; i++) 
  var el = els[i];
  el.innerHTML = el.innerHTML.replace(/link/gi, 'dead link');

见:DEMO

浏览器支持

截至 2016 年 6 月,根据Can I use 的浏览器支持 看起来不错:

(请参阅:http://caniuse.com/queryselector 了解最新信息)

IE6IE7不支持,但是 IE6 is already dead IE7 很快就会使用它的0.68% market share。

IE8 已超过 7 年,它部分支持 querySelectorAll - “部分”是指您可以使用 CSS 2.1 selectors,如 [attr][attr="val"][attr~="val"][attr|="bar"] 和 CSS 3 selectors 的一小部分,幸运的是包括: [attr^=val][attr$=val][attr*=val] 所以 IE8 似乎适合我上面的示例。

IE9IE10IE11支持 querySelectorAll 没有问题,Chrome、FirefoxSafariOperaall 其他主要浏览器 - 桌面和移动

换句话说,我们似乎可以安全地开始在生产环境中使用querySelectorAll

更多信息

有关详细信息,请参阅:

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector http://caniuse.com/queryselector

另请参阅 this answer,了解 querySelectorAllquerySelectorqueryAllquery 之间的区别以及它们被从 DOM 规范中删除的时间

【讨论】:

@OwenMelbourne 这可能是一种更有效的选择链接的方法,但是像这样使用.innerHTML.replace 仍然是替换内容的错误方法 @Alnitak 以及如何在不使用替换的情况下将“链接”一词替换为“死链接”?带子串和拼接? 原始问题中的正则表达式 /link1/ 的 AFAICS 只是一个占位符,而不是 OP 期望替换的文字内容。 @Alnitak 我知道这是一个占位符,但如果它是任何其他正则表达式会有所不同吗?我的目标基本上是表明仅将getElementsByTagName 更改为querySelectorAll 将使其余代码按预期工作而无需更改。见我的demo。【参考方案2】:

在每个元素上读取和写入innerHTML 属性可能非常昂贵,因此会导致您的速度变慢 - 它会迫使浏览器“序列化”元素,然后您通过正则表达式运行该元素,然后再次“反序列化”。更糟糕的是,您正在为 每个 a 元素执行此操作,即使它不匹配。

请尝试直接查看a 元素的属性:

var els = document.getElementsByTagName("a");
for (var i = 0, l = els.length; i < l; i++) 
    var el = els[i];
    if (el.href === 'http://www.example.com/') 
        el.innerHTML = "dead link";
        el.href = "#";
    

EDIT 在具有更高 W3C 一致性的现代浏览器上,您现在可以使用 document.querySelectorAll() 更有效地获取您想要的链接:

var els = document.querySelectorAll('a[href^=http://www.example.com/]');
for (var i = 0, l = els.length; i < l; i++) 
    els[i].textContent = 'dead link';
    els[i].href = '#';

但是,如果您希望匹配多个域名,或者例如,如果您想同时匹配 http:https:,则此方法就不那么灵活了。

【讨论】:

当我使用“.textContent || .innerText”结构时,我得到了更好的性能; blogger.ziesemer.com/2007/10/innerhtml-and-innertext-slow.html 确实更快,但是在大约 1500 次循环后它变慢了! +1 优化 for 循环只在开始时检查一次长度,我从来没有想过像这样直接将它放入循环中! el.href === 'http://www.example.com/myfile.html' 在主要浏览器的 Mac OS 下工作,但由于某种原因不能在任何主要浏览器的 Ubuntu 或 Windows 环境下工作。我改用el.href.indexOf("myfile.html") 解决了这个问题。干杯。 @Sorry-Im-a-N00b 是的,你真的是个 n00b。正如已经写过的,els.length 的评估只进行一次,而不是每次迭代。你的编辑是错误的,批准你的编辑的人也应该知道更多。

以上是关于Javascript getElement by href?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:验证文件上载

6.6

WebDriver中执行JavaScript

无法访问全局变量(Javascript)

javascript5

javascript函数大全