getAttribute by TagName - JS

1.7k views Asked by At

My specific situation is that I'm trying to remove/make inactive a link element from the DOM (I have no control over it being generated). The way that I plan to do this is through replacing the 'href' attribute with a nonsense value - the reason I've chosen to do it this way rather than simply using disable = true is so that the function can be reused on other occasions to change other attributes.

The problem I'm having is with .getAttribute where it returns the error "TypeError: elemArr.hasAttribute is not a function".

function removeLink(elem, att, value, replacement) {
    var elemArr = document.getElementsByTagName(elem);
    for (var i = 0; i < elemArr.length; i++) {
        var workingAtt = elemArr.hasAttribute(att);
        if (workingAtt.value === filePath) {
            elemArr[i].setAttribute(att, replacement);
        }
    }
}
removeLink("link", "href", "filePath", "#");

Any help with why this error is getting thrown is greatly appreciated.

3

There are 3 answers

2
Carlos Vergara On BEST ANSWER

What's going on in there is that elemArr is an array, and arrays don't have a hasAttribute method. Rewrite your code as

function removeLink(elem, att, value, replacement) {
  var elemArr = document.getElementsByTagName(elem);
  for (var i = 0; i < elemArr.length; i++) {
    //this line here wasn't referring to a specific node but the array
    var workingAtt = elemArr[i].hasAttribute(att);
    if (workingAtt && elemArr[i].getAttribute(att) === value) {
      elemArr[i].setAttribute(att, replacement);
    }
  }
}
removeLink("link", "href", "filePath", "#");

And it will work.

A more succint approach would be something like this:

function removeLink(elem, att, value, replacement){
  var selector = elem + '['+ att +'="'+ value +'"]';
  [].forEach.call(document.querySelectorAll(selector), function(node){
    node.setAttribute(att, replacement);
  });
}

It does basically the same thing, but is quite a bit shorter and more explicit.

0
Josh Beam On

.hasAttribute() returns a boolean true or false. Therefore, workingAtt will either equal true or false. Boolean values are not HTMLElements, therefore they do not have value attributes. That's why there's an error.

It looks like you're trying to do something like select elements where there is a href attribute.

If so, you can just filter them:

var myElements = [];

[].filter.call(elemArr, function(el) {
    if(el.hasAttribute(att)) {
        myElements.push(el);
    }
});

// then, do something with myElements
0
zlumer On

You have several errors in your code:

  1. elemArr.hasAttribute instead of elemArr[i].hasAttribute.
  2. var workingAtt = elemArr.hasAttribute(att); — here, workingAtt will be a boolean value, workingAtt.value is non-existent. You should use elemArr[i].getAttribute(att) and later use workingAtt, NOT workingAtt.value (it will be non-existent again!).
  3. if (workingAtt.value === filePath) you're comparing to filePath while you should most definitely compare to value that you pass in the function.