How to check if some element has attribute “name”

2020-05-06 13:51发布

I'm going to use various data attributes names start with for example "data-mo-".

Assume I have these elements:

<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>

I know how to handle elements whose data attribute values start with some value, but how can it be done for the data attribute names?

3条回答
戒情不戒烟
2楼-- · 2020-05-06 14:34

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>

查看更多
该账号已被封号
3楼-- · 2020-05-06 14:36

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:

查看更多
唯我独甜
4楼-- · 2020-05-06 14:52

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>

查看更多
登录 后发表回答