Is there a better way to detect if nextUntil stopped regularly? - javascript

I wonder if there is a well performing way to find out if .nextUntil() stopped without matching the specified selector.
.nextUntil() returns the same result as .nextAll() if the selector didn't match any element.
So it is possible to find out using:
if ($("#id").nextUntil(".someclass").length === $("#id").nextAll().length) {
//do some stuff if there was no match
}
But is there a better solution?

If it stops without a match, it means that you have a last child inside your object. You can use the following:
if (!$("#id").nextUntil(".someclass").is(':last-child'))
Test it here

Related

Selectors-based search through an array of elements

Is it possible to implement a search like document.querySelectorAll(selectors), but against an array of Node objects, rather than the entire document?
I have a pre-selected list of Node objects, and I want a function that could take the same selectors parameter, but search inside the array.
Basically, it is a question of whether or not it is possible to do a node.match(selectors) check, to verify if the node matches the selector, and then I could simply iterate through my list of nodes. But I haven't been able to find if such match-check is possible.
So I want something like this:
function querySelectorInArray(nodeArray, selectors) {
return nodeArray.filter(function(node) {
return node.match(selectors); // this line is what I want, but dunno how
});
}
Afterthought
Will it be a good idea though? I'm thinking, querySelectorAll is parsing selectors only once, but I would be doing it once for each element in the array. Will it be bad for performance? Or is there a way to avoid it, like maybe to pre-parse selectors and pass in an known object instead?
You can use Element#matches for that:
function querySelectorInArray(nodeArray, selectors) {
return nodeArray.filter(function(node) {
return node.matches(selectors);
});
}
You could simply add every node to a DocumentFragment and then use querySelector:
Documentation

jQuery .filter() elements that do not have variable

How can I turn this:
activeSelector = '.active,.selected,.current';
$menuChildren.filter(activeSelector).find('.each-project-content-container').remove();
into a filter that is not activeSelector?
Some ideas that didn't work so you get the idea:
$menuChildren.filter(!activeSelector).find('.each-project-content-container').remove();
$menuChildren.filter(!=activeSelector).find('.each-project-content-container').remove();
$menuChildren.not(filter(activeSelector)).find('.each-project-content-container').remove();
You could use not():
$menuChildren.not(activeSelector)
Try this:
$menuChildren.filter(function(index) {
return $(this).not(activeSelector).find('.each-project-content-container').remove();
});
This will do a check on each element that gets passed through the filter and look for an element that doesn't have the activeSelector string. If it finds a matching element, then it'll remove the .each-project-content-container child elements.
EDIT:
Actually, you don't even need the filter() call here. You can simply select all of the non-active elements, find their children of the specified class, and remove:
$menuChildren.not(activeSelector).find('.each-project-content-container').remove();
That functions the same as above, and is still a one-liner.

javascript alternative for jquery element addressing

What is Javascript alternative for this:
$('#clientDetailModal #heightValue')
I need it because in my code this works:
document.getElementById('heightValue').checkValidity()
but this doesn't:
$('#clientDetailModal #heightValue').checkValidity()
And I need to select only heightValue within clientDetailModal div.
Try $('#clientDetailModal #heightValue')[0].checkValidity()
The reason you need to do the [0] is, (as per the jquery id selector documentation)
Calling jQuery() (or $()) with an id selector as its argument will
return a jQuery object containing a collection of either zero or one
DOM element
Since you'll get a collection with 1 DOM element (assuming you don't have multiple ids), you need to then explicitly "select" that element using the [0].
You could use get to get the DOM element :
$('#clientDetailModal #heightValue').get(0).checkValidity()
Just to be sure, as your question might be a little ambiguous : only one element can have a given ID in HTML. So if your element is either absent or inside #clientDetailModal, then you could as well use
$('#heightValue').get(0).checkValidity()
It would also be faster. But in that case, there would be nothing wrong in using document.getElementById.
Since document.getElementById('heightValue').checkValidity() works, it means your function checkValidity() is attached on native DOM elements. This means, you can do:
$('#clientDetailModal #heightValue')[0].checkValidity()
Plus: If your HTML is valid with no duplicate IDs, you can simply do
$('#heightValue')[0].checkValidity()
Since the OP asked for a JavaScript alternative. On modern browsers,
document.querySelector ('#clientDetailModal #heightValue')
will return the element you are asking for.
The direct equivalent would be
document.querySelectorAll ('#clientDetailModal #heightValue')
which returns an array of elements matching the selector requested, do yrou will need to add the [0] as per the other answers.
I presume this is what you're looking for :
document.getElementById('clientDetailModal').getElementById('heightValue').checkValidity();

Strange ie behaviour with jquery inArray

Hello this seems to be working on IE8 :
var clsName = link.parents("div.fixed_column").attr("class").split(" ");
if($.inArray("column_one", clsName)
While this one reports error (Object expected errror in jquery).
var clsName = link.parents("div.fixed_column").attr("class");
What is the right way to do this? I thought purpose of inArray was that jquery will handle cross browser issues.
Unfortunately, this is indirectly answering your question, but... You seem to be looking to detect if an element has a class, and since you're already using jQuery, just use the hasClass method - http://api.jquery.com/hasClass/
For your specific code, try:
if (link.parents("div.fixed_column").hasClass("column_one")) {
// It has the "column_one" class
}
The more immediate answer to your question is that link.parents("div.fixed_column").attr("class") returns a single string. When the jQuery selector (div.fixed_column) returns multiple elements, which is very possible when using classes, using jQuery methods that get information (like .attr, using one parameter...to "get" the value) return the first matched element's value only.
So say the selector matches 3 elements:
["<div id='div30' class='fixed_column div30_class'></div>",
"<div id='div2' class='fixed_column div2_class'></div>",
"<div id='div17' class='fixed_column div17_class'></div>"]
Then the value returned from .attr("class") will be: fixed_column div30_class because it's the first matched element.
I'm not sure, but I think you're expecting jQuery to return an array of all the matched elements' values, which it just doesn't. So that doesn't mean jQuery isn't handling cross-browser issues, it just means you need to look up what the method does/returns.
I could've sworn that jQuery 2.0 has options for doing what you want - directly from calling the getters (or something similar), but I can't find it anymore :( Maybe I'm remembering incorrectly. Anyways, you could easily use $.each and/or $.map to look at every matched element, but it depends on what you were really trying to do with it.
You can't read the attributes of multiple elements into an array with .attr("class"). But why don't you just target the desired class in the selector like this?
var cols = link.parents("div.fixed_column.column_one");
Then change your conditional to check for an empty set:
if(cols.length) { ...

How can I tell whether an element matches a selector?

Let's say I've got a DOM element - how can I tell whether it matches a jQuery selector, such as p or .myclass? It's easy to use the selector to match children of the element, but I want a true/false answer to whether this particular element match?
The element may not have an ID (and I can't assign it a random one for reasons beyond this), so I can't apply my selector to the element's parent and look for children with the same ID as mine.
Will this work as intended? I can't figure out Javascript object comparisons.
$(selector, myElement.parentNode).each({
if (this == myElement) // Found it
});
Seems like there would be an easy way to see whether a DOM element matches a jQuery selector...
You can use the is() method:
if($(this).is("p")){
// ...
}
Without jQuery, using Element.matches():
var elements = document.querySelectorAll('div');
console.log(
elements[0].matches('.foo'), // true
elements[0].matches('.bar'), // false
elements[1].matches('[title=bar]'), // true
)
<div class='foo'></div>
<div title='bar'></div>
See supported browsers list
I believe the is() method is what you are looking for.
Otherwise, you might just try selecting the item directly, if that is what you mean.
So if it's an "a" with a class of "myclass", just do $("a.myclass")
I can't apply my selector to the
element's parent and look for children
with the same ID as mine.
You can't do that anyway - the id attribute must be unique.
Maybe you just want:
$(".complicated #selector p.with > div.manyParts").length
If there are no matches, length returns 0, which is falsy, so you can use it in an if statement, like:
if($(".doesThis #exist").length) {
// Do things
}
Probably would be worth storing it in a separate variable and THEN checking the length; that way, if you need to do anything with the matched elements, you don't have to execute the same selector again.
Try Element.matches()
Element.matches()
document.addEventListener("click", event => {
if (event.target.matches(".elementsClass")) {
// It matches
} else {
// Does not match
}
});

Categories