Skip to content Skip to sidebar Skip to footer

How To Check If Some Element Has Attribute "name" Starts With Something, Not "value"

I'm going to use various data attributes names start with for example 'data-mo-'. Assume I have these elements: Title 1<

Solution 1:

If all you wish to do is find whether a given node has an attribute beginning with a specific string, then one approach is the following:

// node: a single HTMLELement node,// attr: the string to test against the attribute names:functionhasAttributeStartingWith(node, attr) {

  // here we return the result, using Array.from() to turn// the node-map of attributes into an Array, and then// Array.prototype.filter() to remove any attributes that// do not return a true/truthy result against the supplied// assessment:returnArray.from(node.attributes).filter(function(attributeNode) {
    // attributeNode: a reference to the current attribute-node// of the array of attribute-nodes over which we're iterating.// here we test to see if the nodeName (the attribute-name)// of the attribute-node begins with  the supplied string// (held in the 'attr' variable):return attributeNode.nodeName.indexOf(attr) === 0;

  // if the filtered array is greater than zero then// there are some attributes beginning with the// supplied string:
  }).length > 0;
}

// here we convert the nodeList returned from document.querySelectorAll()// into an Array, using Array.from(), and iterate over those elements// using Array.prototype.forEach():Array.from(document.querySelectorAll('span')).forEach(function(span) {
  // 'span': a reference to the current <span> element of the// array of <span> elements over which we're iterating.// using the function within the 'if' assessment, since it// returns a Boolean true/false:if (hasAttributeStartingWith(span, 'data-mo')) {

    // using the Element.classList API to add// the 'hasAttributeStartingWith' class to// the current <span> if the function returns// true:
    span.classList.add('hasAttributeStartingWith');
  }

});

functionhasAttributeStartingWith(node, attr) {
  returnArray.from(node.attributes).filter(function(attributeNode) {
    return attributeNode.nodeName.indexOf(attr) === 0;
  }).length > 0;
}

Array.from(document.querySelectorAll('span')).forEach(function(span) {
  if (hasAttributeStartingWith(span, 'data-mo')) {
    span.classList.add('hasAttributeStartingWith');
  }
});
.hasAttributeStartingWith {
  display: inline-block;
  font-size: 1.5em;
  color: limegreen;
}
<spandata-mo-top-fade-duration="600">Title 1</span><spandata-mo-bottom-fade-duration="600">Title 2</span><spandata-mo-right-fade-duration="600">Title 3</span><spandata-mo-left-fade-duration="600">Title 4</span>

JS Fiddle demo.

In the above all elements have an attribute starting with data-mo, to show it working more specifically, try:

Array.from(document.querySelectorAll('span')).forEach(function(span) {
  if (hasAttributeStartingWith(span, 'data-mo-b')) {
    span.classList.add('hasAttributeStartingWith');
  }
});

functionhasAttributeStartingWith(node, attr) {
  returnArray.from(node.attributes).filter(function(attributeNode) {
    return attributeNode.nodeName.indexOf(attr) === 0;
  }).length > 0;
}

Array.from(document.querySelectorAll('span')).forEach(function(span) {
  if (hasAttributeStartingWith(span, 'data-mo-b')) {
    span.classList.add('hasAttributeStartingWith');
  }
});
.hasAttributeStartingWith {
  display: inline-block;
  font-size: 1.5em;
  color: limegreen;
}
<spandata-mo-top-fade-duration="600">Title 1</span><spandata-mo-bottom-fade-duration="600">Title 2</span><spandata-mo-right-fade-duration="600">Title 3</span><spandata-mo-left-fade-duration="600">Title 4</span>

JS Fiddle demo.

This should match only the element which has an attribute starting with the string data-mo-b, styling only the second <span> element.

References:

Solution 2:

A concise approach using ES6 is to select all elements in the document, then .filter by whether .some of the attribute names start with the string you're looking for:

const moElements = [...document.querySelectorAll('*')]
  .filter(elm => [...elm.attributes].some(
    ({ name }) => name.startsWith('data-mo-')
  ));
console.log(moElements);
<spandata-mo-top-fade-duration="600">Title 1</span><spandata-mo-bottom-fade-duration="600">Title 2</span><spandata-mo-right-fade-duration="600">Title 3</span><spandata-mo-left-fade-duration="600">Title 4</span><span>somethingElse</span>

Or, if you want to avoid constructing the intermediate arrays with spread, you can .call the array methods on the element / attribute collections instead:

const moElements = Array.prototype.filter.call(
  document.querySelectorAll('*'),
  elm =>Array.prototype.some.call(
    elm.attributes,
    ({ name }) => name.startsWith('data-mo-')
  )
);
console.log(moElements);
<spandata-mo-top-fade-duration="600">Title 1</span><spandata-mo-bottom-fade-duration="600">Title 2</span><spandata-mo-right-fade-duration="600">Title 3</span><spandata-mo-left-fade-duration="600">Title 4</span><span>somethingElse</span>

Solution 3:

If I get it right you want to check for data-mo so I have tried something to make this work;

functiongetData(index){
	if(index[0].indexOf("mo") !== -1)
    	returntruereturnfalse
}

$.each($("span"), function(i,index){
	var objectKey = Object.keys($(this).data());
	if(getData(objectKey)){
    	$(this).addClass("valid")
    } else {
    	$(this).addClass("not-valid")
    }
    	
})
.valid {
    color: green
}
.not-valid {
    font-weight: bold;
    color: red;
    text-decoration: line-through
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><spandata-mo-top-fade-duration="600">Title 1</span><spandata-mo-bottom-fade-duration="600">Title 2</span><spandata-mo-right-fade-duration="600">Title 3</span><spandata-mo-left-fade-duration="600">Title 4</span><spandata-not-valid-one-left-fade-duration="600">Title 5</span>

Post a Comment for "How To Check If Some Element Has Attribute "name" Starts With Something, Not "value""