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:
function hasAttributeStartingWith(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:
  return Array.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');
  }

});

function hasAttributeStartingWith(node, attr) {
  return Array.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;
}
<span data-mo-top-fade-duration="600">Title 1</span>
<span data-mo-bottom-fade-duration="600">Title 2</span>
<span data-mo-right-fade-duration="600">Title 3</span>
<span data-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');
  }
});

function hasAttributeStartingWith(node, attr) {
  return Array.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;
}
<span data-mo-top-fade-duration="600">Title 1</span>
<span data-mo-bottom-fade-duration="600">Title 2</span>
<span data-mo-right-fade-duration="600">Title 3</span>
<span data-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);
<span data-mo-top-fade-duration="600">Title 1</span>
<span data-mo-bottom-fade-duration="600">Title 2</span>
<span data-mo-right-fade-duration="600">Title 3</span>
<span data-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);
<span data-mo-top-fade-duration="600">Title 1</span>
<span data-mo-bottom-fade-duration="600">Title 2</span>
<span data-mo-right-fade-duration="600">Title 3</span>
<span data-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;

function getData(index){
	if(index[0].indexOf("mo") !== -1)
    	return true
        
    return false
}

$.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
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span data-mo-top-fade-duration="600">Title 1</span>
    <span data-mo-bottom-fade-duration="600">Title 2</span>
    <span data-mo-right-fade-duration="600">Title 3</span>
    <span data-mo-left-fade-duration="600">Title 4</span>
    <span data-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""