How to check if some element has attribute “name” starts with something, not “value”

后端 未结 3 923
刺人心
刺人心 2021-01-26 08:39

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

Assume I have these elements:



        
相关标签:
3条回答
  • 2021-01-26 09:04

    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>

    0 讨论(0)
  • 2021-01-26 09:16

    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:

    • Array.from().
    • Array.prototype.filter().
    • Array.prototype.forEach().
    • document.querySelectorAll().
    • Element.attributes.
    • Element.classList API.
    • Node.nodeName.
    • String.prototype.indexOf().
    0 讨论(0)
  • 2021-01-26 09:23

    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>

    0 讨论(0)
提交回复
热议问题