Home > other >  jQuery to match one element containing ALL classes
jQuery to match one element containing ALL classes

Time:09-28

I have the following layout:

<p type="data" class="element section">
   <span class="element content start">Start</span>
   <span class="element content stop">Stop</span>
   <span class="element content text">Some text</span>
</p>

I am trying to write a function to return a reference to the span which the user can call be specifying a string, for example (bad pseudocode):

callMe = function(str) {
    return $node.find(str);  // $node is a reference to `p`
}

so I would like the user to call callMe('element content stop') and be returned a reference to the stop span. find uses an OR condition but I need this to operate as an AND on all classes.

CodePudding user response:

You need to put . for use selector class like:

$node = $('p');
let callMe = function(str) {    
    return $node.find(str);  // $node is a reference to `p`
}
const span = callMe('.stop');
console.log(span[0], span[0].innerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p type="data" class="element section">
   <span class="element content start">Start</span>
   <span class="element content stop">Stop</span>
   <span class="element content text">Some text</span>
</p>

CodePudding user response:

You can try to filter

const node = document.querySelector(".element.section");
const callMe = str => {
  const classes = str.split(/\s /);
  return [...node.querySelectorAll("span")]
    .filter(span => classes
      .filter(className => span.classList.contains(className)).length === classes.length)
}

console.log(
  callMe("element content stop")
)  
<p type="data" class="element section">
   <span class="element content start">Start</span>
   <span class="element content stop">Stop</span>
   <span class="element content text">Some text</span>
</p>

CodePudding user response:

I would split the string into an array on the space character, then loop through the array to build your selector.

callMe = function(str) {
  const classes = str.split(' ');
  let classSelector;

  for (let i = 0; i < classes.length; i  ) {
    classSelector = '.'   classes[i];
  }

  document.querySelector(classSelector).classList.add('highlight');
  // or $(classSelector).addClass('highlight')
  // but we're weaning ourselves from jQuery, right? :)
}

callMe('element content stop');
.highlight {
  color: red;
}
<p type="data" class="element section">
  <span class="element content start">Start</span>
  <span class="element content stop">Stop</span>
  <span class="element content text">Some text</span>
</p>

CodePudding user response:

You just need to transform element content stop to .element.content.stop. jQuery takes care of rest:

var callMe = function(str) {
  var $node = $("p.element.section");
  var selector = str.split(/\s /).map(s => "."   s).join("");
  return $node.find(selector);
}
callMe("stop element content").css("background-color", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p type="data" class="element section">
  <span class="element content start">Start</span>
  <span class="element content stop">Stop</span>
  <span class="element content text">Some text</span>
</p>

CodePudding user response:

  1. Pass in a jQuery object for the node, and a selector string. Note: this method allows you to pass in a selector string representing n classes.

  2. Create a classes variable by splitting the string on the spaces, mapping over the array and returning a new class string for each element, and then joining that mapped array back up, and use that string as the find selector.

function callMe(node, selector) {

  const classes = selector
    .split(' ')
    .map(el => `.${el}`)
    .join('')
  
  return find = $(node).find(classes);

}

const spans = callMe($('p'), 'element content');
const start = callMe($('p'), 'start');
const stop = callMe($('p'), 'element content stop');

spans.each((i, v) => {
  console.log($(v).text());
});

console.log($(start).text());
console.log($(stop).text());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p type="data" class="element section">
  <span class="element content start">Start</span>
  <span class="element content stop">Stop</span>
  <span class="element content text">Some text</span>
</p>

  • Related