web-dev-qa-db-fra.com

Javascript récupère Element par href?

J'ai le script ci-dessous

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

Cependant, cela parcourt la page et prend environ 20 secondes pour le faire car il y a BEAUCOUP de liens.

Cependant, je n'ai besoin que de cibler les a qui ont un href spécifique, par exemple. "http://domain.com/"

Donc, idéalement, j'aimerais pouvoir faire cela d'une manière similaire à jQuery, mais sans utiliser de framework. Donc quelque chose comme

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

Comment pourrais-je procéder pour qu'il ne recherche que les objets avec ce href correspondant?

37
Owen

Mise à jour 2016

Cela fait plus de 4 ans que cette question a été publiée et les choses ont beaucoup progressé.

Vous ne pouvez pas utiliser:

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

mais ce que vous pouvez utiliser est:

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

( Remarque: voir ci-dessous pour la prise en charge du navigateur)

ce qui ferait fonctionner le code de votre question exactement comme vous l'attendez :

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

Vous pouvez même utiliser des sélecteurs comme a[href^='http://domain.com'] si vous voulez que tous les liens qui commencent par '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');
}

Voir: [~ # ~] démo [~ # ~]

Prise en charge du navigateur

Le support du navigateur selon Puis-je utiliser à partir de juin 2016 semble assez bon:

caniuse.com/queryselector (Voir: http://caniuse.com/queryselector pour des informations à jour)

Il n'y a pas de support dans IE6 et IE7 mais IE6 est déjà mort et IE7 sera bientôt avec son ,68% de part de marché .

IE8 a plus de 7 ans et partiellement prend en charge querySelectorAll - par " partiellement "je veux dire que vous pouvez utiliser sélecteurs CSS 2.1 comme [attr], [attr="val"], [attr~="val"], [attr|="bar"] et un petit sous-ensemble de sélecteurs CSS qui heureusement comprennent: [attr^=val], [attr$=val], et [attr*=val] donc il semble que IE8 soit bien avec mes exemples ci-dessus.

IE9 , IE10 et IE11 tous supportent querySelectorAll sans problème, tout comme Chrome , Firefox , Safari , Opera et tous les autres principaux navigateurs - les deux ordinateurs de bureau et mobile .

En d'autres termes, il semble que nous pouvons commencer en toute sécurité à utiliser querySelectorAll en production.

Plus d'informations

Pour plus d'informations, voir:

Voir aussi cette réponse pour la différence entre querySelectorAll, querySelector, queryAll et query et quand ils l'étaient supprimé de la spécification DOM .

68
rsp

La lecture et l'écriture de la propriété innerHTML sur chaque élément est probablement assez coûteuse et provoque donc votre ralentissement - cela oblige le navigateur à "sérialiser" l'élément, que vous exécutez ensuite via une expression régulière, puis "désérialisez" à nouveau. Pire encore, vous le faites pour chaque élément a, même s'il ne correspond pas.

Essayez plutôt de regarder directement les propriétés de l'élément 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 = "#";
    }
}

MODIFIER sur les navigateurs modernes avec une conformité W3C beaucoup plus grande, vous pouvez maintenant utiliser document.querySelectorAll() pour obtenir plus efficacement uniquement les liens que vous souhaitez:

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

Ce n'est cependant pas si flexible s'il y a plusieurs noms de domaine que vous souhaitez faire correspondre, ou par exemple si vous voulez faire correspondre à la fois http: Et https: En même temps.

20
Alnitak