How can I tell whether an element matches a selector? - javascript

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
}
});

Related

How do I check if an element is NOT empty with jquery?

I need to check if an element is empty and if another is NOT empty. The first part of the if works but how do I check if the #dynamicForm element is NOT empty?ยจ
This obviously doesn't work but I need something like it:
if ($("#formButton").is(':empty') && $("#dynamicForm").is(':notempty')) {
//do stuff
}
if(!$("#dynamicForm").is(':empty')){
// code here...
}
Note the not operator (!) in front.
First of all you can check if the selected element is empty and negate it:
!$('#dynamicForm').is(':empty')
Furthermore you can check if it's not empty with jquery selector :not:
$('#dynamicForm').is(':not(:empty)')
A third way would be to select all elements, that are not empty and check the length of the jquery collection:
$('#dynamicForm').not(':empty').length
If you need this check in several places you can add your own function to jQuery:
$.fn.notEmpty = function() {
return !$(this).is(':empty')
}
you can use it like this:
if($('#dynamicForm').notEmpty())
That isn't realy clean and it's not keeping with the jquery conventions. So better extend the selectors instead of extending the functions:
$.extend($.expr[':'],{
notEmpty:function(c) {
return !$(c).is(':empty');
}
});
Now you can use it very straightforward:
if($('#dynamicForm').is(':notEmpty'))

Find elements using part of ID

I have, the div's where id looks like this_div_id_NUMBER, all div's has the different NUMBER part. How I find all div's just using this_div_id part of id ?
you can use querySelectorAll to hit partial attribs, including ID:
document.querySelectorAll("[id^='this_div_id']")
the ^ next to the equal sign indicates "starts with", you can use * instead, but it's prone to false-positives.
you also want to make sure to use quotes (or apos) around the comapare value in attrib selectors for maximum compatibility on querySelectorAll; in jQuery and evergreen browsers it doesn't matter, but in vanilla for old browsers it does matter.
EDIT: late breaking requirement needs a more specific selector:
document.querySelectorAll("[id^='this_div_id']:not([id$='_test_field'])");
the not() segment prevents anything ending with "_test_field" from matching.
proof of concept / demo: http://pagedemos.com/partialmatch/
querySelectorAll
querySelectorAll takes CSS selectors and returns a HTMLNodeList (a kind of array) of all the elements matching that css selector.
The css selector ^ (starts with) can be used for your purpose. Learn more about it in this article.
For your case, it would be document.querySelectorAll("[id^='this_div_id']");
Note that querySelectorAll doesn't return a live node list. That means, any changes to the dom would not be updated live in the return value of the function.
Another method would to assign all your elements a specific class and then you can use getElementsByClassName (which is much faster than querySelector).
var divs = document.getElementsByClassName("divClass");
Try this selector:
[id^="this_div_id_"]
Pure JavaScript: (reference)
document.querySelectorAll('[id^="this_div_id_"]')
jQuery: (reference)
$('[id^="this_div_id_"]')
CSS: (reference)
[id^="this_div_id_"] {
/* do your stuff */
}
Why is this working?
With the [] in the selector, you can select attributes. Use '=' to match exactly the value or use the '^=' to check if the value starts with. Read more about this here.
Using attribute selectors:
div[id^="this_div_id"]
It is better to use classes.
But there is one solution that you need (assuming you use jQuery):
$("*[id^='this_div_id']")
Just using attribute selector like below:
$("[id^='this_div_id_']")

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

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

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.

Remove element depending on it's background-image

I'm trying to remove an element from a page based on it's background attribute.
Something like:
if ( $('td').attr('background','backgroundimageurl')){this.remove();}
But this does not work any suggestions?
You can also use filter to filter the result set based on your operations:
$( 'td' ).filter( function(){
// return true of it matches, thus, keeping it in the object
return $(this).css( 'backgroundImage' ) === 'someUrlOrWhatever';
}).remove();
Demo per roXon's request: http://jsfiddle.net/danheberden/9rTZj/
However, it would be better to do a check like
return /someDomain\.com\/path\/to\/whatever/.test( $( this ).css( 'backgroundImage' ) );
in the filter function. Different browsers will return different formatting for css rules, as roXon pointed out about the === approach won't work in FF because the returned string will be url("thePath") instead of url(thePath) like in webkit. Thus, just testing for the url value would be most flexible.
The reason it's not working is that in your code snippet, "this" is the current context (most likely the window).
This might do what you want:
$('td').each(function (i, e) {
if (e.style.foo === "bar") {
$(e).remove();
}
});
each iterates through all of the elements that matched. i is the number of the loop, and e is the current element. So we test each element and then act when we find the one with the style we want.
Even shorter example:
$('td[background="backgroundimageurl"]').remove();
Do some reading on jQuery selectors. They can be really useful :)
http://api.jquery.com/category/selectors/
Try this. When you were doing attr("background","backgroundurl") this was trying to set the background attr rather than find elements matching. This will do the trick.
if($("body").find("td").css("background-image") == "backgroundimageurl"){this.detach()};

Categories