Javascript getElement by href?

JavascriptHrefGetelementsbytagname

Javascript Problem Overview


I've got the script below

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');
}

However this searches through the page and takes about 20 seconds to do it as there are LOTS of links.

However I only need to target the a's that have a specific href, for eg. "http://domain.com/"

So ideally I'd like to be able to do this in a similar fashion to jQuery, but without using a framework. So something like

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

How would I go about doing this so it only searches the objects with that matching href?

Javascript Solutions


Solution 1 - Javascript

2016 update

It's been over 4 years since this question was posted and things progressed quite a bit.

You can't use:

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

but what you can use is:

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

(Note: see below for browser support)

which would make the code from your question work exactly as you expect:

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

You can even use selectors like a[href^='http://domain.com'] if you want all links that start with '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');
}

See: DEMO

Browser support

The browser support according to Can I use as of June 2016 looks pretty good:

caniuse.com/queryselector (See: http://caniuse.com/queryselector for up to date info)

There is no support in IE6 and IE7 but IE6 is already dead and IE7 soon will be with its 0.68% market share.

IE8 is over 7 years old and it partially supports querySelectorAll - by "partially" I mean that you can use CSS 2.1 selectors like [attr], [attr="val"], [attr~="val"], [attr|="bar"] and a small subset of CSS 3 selectors which luckily include: [attr^=val], [attr$=val], and [attr*=val] so it seems that IE8 is fine with my examples above.

IE9, IE10 and IE11 all support querySelectorAll with no problems, as do Chrome, Firefox, Safari, Opera and all other major browser - both desktop and mobile.

In other words, it seems that we can safely start to use querySelectorAll in production.

More info

For more info, see:

See also this answer for the difference between querySelectorAll, querySelector, queryAll and query and when they were removed from the DOM specification.

Solution 2 - Javascript

Reading and writing the innerHTML property on every element is probably quite expensive and hence causing your slowdown - it forces the browser to "serialize" the element, which you then run through a regexp, and then "deserialize" again. Even worse, you're doing it for every a element, even if it doesn't match.

Instead, try looking directly at the properties of the a element:

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 on modern browsers with much greater W3C conformance you can now use document.querySelectorAll() to more efficiently obtain just the links you want:

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 = '#';
}

This is however not so flexible if there are multiple domain names that you wish to match, or for example if you want to match both http: and https: at the same time.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionowenmelbzView Question on Stackoverflow
Solution 1 - JavascriptrspView Answer on Stackoverflow
Solution 2 - JavascriptAlnitakView Answer on Stackoverflow