【问题标题】:How to check if some element has attribute "name" starts with something, not "value"如何检查某个元素是否具有属性“名称”以某些东西开头,而不是“值”
【发布时间】:2016-08-29 13:11:34
【问题描述】:

我将使用以"data-mo-" 开头的各种数据属性名称。

假设我有这些元素:

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

我知道如何处理数据属性值start的元素有一些值,但是如何处理数据属性names呢?

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

如果您只想查找给定节点是否具有以特定字符串开头的属性,则一种方法如下:

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

在上面所有元素都有一个以data-mo 开头的属性,为了更具体地显示它的工作原理,试试:

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.

这应该只匹配具有以字符串data-mo-b 开头的属性的元素,仅设置第二个&lt;span&gt; 元素的样式。

参考资料:

【讨论】:

  • array.some(f) 应该比array.filter(f).length &gt; 0 更有效。另外,string.startsWith("something") 而不是string.indexOf("something") === 0。 (如果可行,甚至可能是 [].some.call(node.attributes, f);未测试。)
【解决方案2】:

使用 ES6 的一种简洁方法是选择文档中的所有元素,然后通过 .some 的属性名称是否以您要查找的字符串开头来选择 .filter

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>

或者,如果你想避免用spread构造中间数组,你可以.call元素/属性集合上的数组方法来代替:

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

如果我做对了,你想检查 data-mo,所以我尝试了一些方法来完成这项工作;

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-18
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    相关资源
    最近更新 更多