jQuery compare two DOM object? - javascript

Clicking on an element:
$('.my_list').click(function(){
var selected_object = $(this);
$('.my_list').each(function(){
var current_object = $(this);
if( selected_object == current_object ) alert('FOUND IT !');
});
});
I don't know why, but I don't get the alert message "FOUND IT !".

You can use the jQuery.is function:
Check the current matched set of elements against a selector, element,
or jQuery object and return true if at least one of these elements
matches the given arguments.
if (selected_object.is(current_object)) {
...
}
An alternate solution is to use jQuery.get function to get the raw elements and compare them using == or === operator:
if (selected_object.get(0) == current_object.get(0)) {
...
}
jsFiddle demo

There's good answer provided... but it's important to understand, why you directly can't compare selectors in jQuery.
jQuery selectors return data structures which will never be equal in the sense of reference equality. So the only way to figure this out is to get DOM reference from the jQuery object and to compare DOM elements.
The simplest comparison of DOM reference for the above example would be:
selected_object.[0] == current_object.[0]

Related

Pure JavaScript alternative to jQuerys .find

I have this in jQuery:
$(document).bind("click touchstart", function(e) {
if (e.target.class != searchControls && !searchControls.find(e.target).length) {
//do something
});
});
What this does is checks the click and if it's not the search element a child of that element, then I can run something. What I'm trying to do is find a pure JavaScript alternative to this.
So far I have:
var searchTrigger = document.querySelector(".header__search-btn"),
productSearch = document.querySelector(".product-search"),
searchControls = document.querySelectorAll(".product-search__positioner");
document.onclick = function (e) {
if (e.target.class != searchControls && e.parentNode != searchControls)
// do something
}
}
However this still fires my function inside the if statement, so clearly I'm going wrong—not sure how wrong. Help appreciated.
document.querySelectorAll returns a collection of DOM elements. e.target.class != searchControls doesn't make sense (ignoring that target.class doesn't even exist): Assuming you mean className, you are trying to compare a string with a list of DOM elements. That will always be false.
So lets ignore that part and look at e.parentNode != searchControls. The event object doesn't have a property parentNode. Again, even if you meant e.target.parentNode, it would not make much sense, since you are testing whether a single element is identical to a list of elements.
Based in your use of .find, you basically want to know whether a node is contained in another node. Every DOM node has a method .contains, so all you have to do is iterate over the collection of DOM elements and call that method:
var contained = false;
for (var i = 0; i < searchControls.length; i++) {
if (searchControls[i].contains(e.target)) {
contained = true;
break;
}
}
This can easily be moved into its own reusable function.
There is no e.target.class. If you are checking for class name then it should be
e.target.className
Then to check for parent elements class name
e.target.parentNode.className
if you are looking to search inside the parent node then use
e.target.parentNode.querySelector("pass your selector here")
if you want to search for just child elements:
e.target.querySelector("pass your selector here")

Filter the $(this) element in loop jquery

I am trying to perform an action to other elements than the $(this) item
$('.items').click(function(){
var myitem = $(this);
$(".items").each(function() {
if (myitem == $(this)){
break;
} else {
//perform action
}
});
});
Where did I go wrong? Is there any better method?
Try to use the .not() function to filter out the current element,
$('.items').click(function(){
$('.items').not(this).each(function(){
//perform action here.
});
});
What went wrong?
When using the jQuery method (a.k.a. $) a new instance of the jQuery object is created, containing a list of elements matching your selector along side with a rich prototype of jQuery's methods.
Your mistake was to try and compare two different instances.
What you could have done was to compare the elements themselves by making the following changes:
// change this:
var myitem = $(this);
// to this:
var myitem = this;
// change this:
if (myitem == $(this)){
// to this:
if (myitem == this){
Unless you intend to use the jQuery object functionality there's no reason to initiate a new instance. Simply use the element itself when possible. It's a best practice to avoid such use cases. Performance wise.
Best solution
But the best solution in your case is what was mentioned in all other answers, using jQuery's not method to exclude the element from the newly created instance.
Using.not() to avoid
Try this
$(".items").not($(this)).each(function() {
});
OR
As per your code
$(".items").not(myitem).each(function() {
});
you can use not() to ignore the element which is clicked:
$(".items").not(this).each(function() {
});

jQuery.find() returns an object even when there's no matching child element in the DOM

I am trying to find an element with the ID '' that is within the element '', and therefore is its child.
I am using the $.find method to perform the search.
If the child object is found, I'd like to perform some actions, and if the child object isn't found, I'd like to do different things.
However, even though I know that there is no such child element existing, the jQuery.find method reports an object that I am not sure, from inspecting in the Watches window, what it is.
Here's the relevant code snippet:
function CreateResourceKeyTextBox(resourceKeyId, editMode) {
var resourceKeyTableCell = $("#tdKeyResourceKeyId" + resourceKeyId);
var resourceKeyNameTextBox = null;
var alreadyExistingResourceKeyNameTextBox = resourceKeyTableCell.find('#txtResourceKeyName' + resourceKeyId);
if (alreadyExistingResourceKeyNameTextBox != null && typeof alreadyExistingResourceKeyNameTextBox != "undefined") {
resourceKeyTableCell.html('');
resourceKeyNameTextBox = alreadyExistingResourceKeyNameTextBox;
resourceKeyNameTextBox.css('display', 'block');
resourceKeyNameTextBox.appendTo('#tdKeyResourceKeyId' + resourceKeyId);
resourceKeyNameTextBox.css('width', '96%');
}
jQuery query functions always return an object, even if there's no matching DOM elements.
Check the length, it will be 0 if there's no element in the set :
if (alreadyExistingResourceKeyNameTextBox.length ...
jquery's find method returns a jquery object whose internal matched elements are the corresponding elements to your css selector.
If css selector fails to match any elements, then, jquery's find method's return object's internal matched elements is an empty array. You can get internal matched elements with .get method as follows:
var elems = $.find(css_selector).get()
this method returns array of DOM elements not jquery object instances, and you can check empty array using following syntax
var elems = $.find(css_selector).get()
if(elems.length === 0){
//array is empty
}else{
//array is not empty
}
This behaviour of jquery minimizes any syntax errors you might get otherwise, jquery will work without errors, no matter your css selector matches any DOM elements or not. This is beneficial in most cases, where you simply apply some changes on matched elements regardless of there are any. If existence of such elements is critical to your business logic, you should check it manually.
You should use alreadyExistingResourceKeyNameTextBox.length != 0 instead I think
if an object is not found using jquery .find() method, it always return an empty array. if you are getting anything other than that, you need to check your DOM. You can always check the length of the result i.e. result.length > 0 || result.length === 1, depending on your need

jQuery set call back on child elements

I am trying to attach an onChange callback to all the input elements under the div #dim. It selects all 3 input elements, but returns an exception:
Uncaught TypeError: Object 0 has no method 'change'
It may be because x may not be a jQuery object. How would I make this work?
function registercb() {
var sel = $("div.dim > input");
for (x in sel) {
x.change(function() {
dosomething();
});
}
}
You can simply do:
function registercb() {
$("div.dim > input").change(dosomething);
}
A few things to watch for:
Inside that iteration (don't use this, see the next point) x is the DOM element, not a jQuery object which has the .change() method, you would need to wrap it in a jQuery object like $(x), but again that isn't the correct solution here.
Don't use a for(...in...) loop to iterate an object (a jQuery object is array-like), that type of loop is for enumeration.
Most jQuery functions (almost all) run on more than one element, so just run it on the set to affect all elements, .change() is one of these.
In the cases you do need to loop, check out .each(), as it'll make your life much easier, don't use this here, it's only an example of what it would look like:
Example:
function registercb() {
$("div.dim > input").each(function() {
$(this).change(dosomething);
});
}
You don't have to loop over the elements. You can think of a jQuery object as holding a collection. When you do:
var sel = $("div.dim > input");
It means that sel has all the input elements in it, so then when you run a method like change() it will affect all of the elements in the collection. Thus you can do something like this:
function registercb() {
$("div.dim > input").change(function(){
dosomething();
});
}
Bonus knowledge: Now your problem is that when you were doing for( x in sel ) you are getting a lot of stuff on the jQuery object itself that you don't want. If you run the following code in chrome you'll see it outputting a lot unexpected stuff:
for( x in sel ){
console.log( x );
}
Instead jQuery has the each that lets you loop over the things you want:
sel.each(function(index, item){
console.log(item);
});
You can even use it on other things, which is really handy!
$([1,2,3]).each(function( index item ){
console.log( item ); // 1,2,3
})
Assuming your 'dim' div has an ID rather than a class of dim, you can simply do this:
$("#dim > input").change(function() { dosomething(); });
Working example.
In the text you refer to #dim whereas in the code you're refering to .dim - # selects by ID and . selects by class, so if your div is in the format <div id="dim"> then you won't find any matched elements with div.dim as your selector.

Check if element exists in jQuery [duplicate]

This question already has answers here:
Is there an "exists" function for jQuery?
(47 answers)
Closed 8 years ago.
How do I check if an element exists if the element is created by .append() method?
$('elemId').length doesn't work for me.
$('elemId').length doesn't work for
me.
You need to put # before element id:
$('#elemId').length
---^
With vanilla JavaScript, you don't need the hash (#) e.g. document.getElementById('id_here') , however when using jQuery, you do need to put hash to target elements based on id just like CSS.
Try to check the length of the selector, if it returns you something then the element must exists else not.
if( $('#selector').length ) // use this if you are using id to check
{
// it exists
}
if( $('.selector').length ) // use this if you are using class to check
{
// it exists
}
Try this:
if ($("#mydiv").length > 0){
// do something here
}
The length property will return zero if element does not exists.
How do I check if an element exists
if ($("#mydiv").length){ }
If it is 0, it will evaluate to false, anything more than that true.
There is no need for a greater than, less than comparison.
your elemId as its name suggests, is an Id attribute, these are all you can do to check if it exists:
Vanilla JavaScript: in case you have more advanced selectors:
//you can use it for more advanced selectors
if(document.querySelectorAll("#elemId").length){}
if(document.querySelector("#elemId")){}
//you can use it if your selector has only an Id attribute
if(document.getElementById("elemId")){}
jQuery:
if(jQuery("#elemId").length){}
You can also use array-like notation and check for the first element.
The first element of an empty array or collection is simply undefined, so you get the "normal" javascript truthy/falsy behaviour:
var el = $('body')[0];
if (el) {
console.log('element found', el);
}
if (!el) {
console.log('no element found');
}
You can use native JS to test for the existence of an object:
if (document.getElementById('elemId') instanceof Object){
// do something here
}
Don't forget, jQuery is nothing more than a sophisticated (and very useful) wrapper around native Javascript commands and properties
If you have a class on your element, then you can try the following:
if( $('.exists_content').hasClass('exists_content') ){
//element available
}

Categories

Resources