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