Search code examples
javascripthtmluserscripts

Get Elements By Partial Attribute Value


I've been fiddling with this for several hours and I'm utterly stumped by its behavior. On JSFiddle, it seems to only be returning the values of the href attribute when I want the entire elements, but I can still use getAttribute(attribute) as if it's an element. In the userscript that this is for, it seems to completely break everything after calling the function(hence turning to JSFiddle and having no result to show here).

Why is this happening? How can I accomplish the stated goal?

HTML:

<a name="edit-a" href="http://example.com/edit1">foo</a>
<a name="moo" href="http://example.com/edit2">roo</a>
<a name="edit-b" href="http://example.com/boo">bar</a>

JavaScript function:

function getElementsByPartialValue(searchtext, searchattr, searchtag)
{
  var searchreturn = [];
  var searchreturni = 0;
  var tagmatches = document.getElementsByTagName(searchtag);
  for (var tagmatchesi = 0; tagmatchesi < document.getElementsByTagName(searchtag).length; tagmatchesi++)
  {
    if (tagmatches[tagmatchesi].getAttribute(searchattr).indexOf(searchtext) > -1)
    {
      searchreturn[searchreturni] = tagmatches[tagmatchesi];
      searchreturni++;
    }
  }
  return searchreturn;
}

Checking the result:

alert(getElementsByPartialValue('edit', 'name', 'a')[0]);

Result(https://jsfiddle.net/81s4g42a/3/):

http://example.com/edit1

Accessing other attributes(https://jsfiddle.net/81s4g42a/4/):

alert(getElementsByPartialValue('edit', 'name', 'a')[0].getAttribute('name'));

Result:

edit-a

Solution

  • Use Attribute-Contains Selector like this:

    var tagmatches = document.querySelectorAll(searchtag + "[" + searchattr + " *= '" + searchtext + "']");
    

    function getElementsByPartialValue(searchtext, searchattr, searchtag)
    {
      return document.querySelectorAll(searchtag + "[" + searchattr + " *= '" + searchtext + "']");
    }
    
    var elems = getElementsByPartialValue("edit", "name", "a");
    for(var i = 0; i < elems.length; i++) {
      elems[i].style.background = "red";
    }
    <a name="edit-a" href="http://example.com/edit1">foo</a>
    <a name="moo" href="http://example.com/edit2">roo</a>
    <a name="edit-b" href="http://example.com/boo">bar</a>