jQuery eq() out of range [duplicate] - javascript

This question already has answers here:
Why does $('#id') return true if id doesn't exist?
(6 answers)
Closed 8 years ago.
I'm new to jQuery and I have the following misunderstanding.
<p>adasd</p>
<p>42323123</p>
...
$("p").eq(4).html("some html")
I know I have only two <p> in my HTML so I do expect that console will say me an exception or something that will signal me I'm doing the wrong thing.
console.log($("p").eq(4))
prints:
prevObject: jQuery.fn.init[2], context: document, jquery: "2.1.1", constructor: function, selector:...
Why is it working like that?

As the documentation page for jQuery's .eq() function states:
If an element cannot be found at the specified zero-based index, the method constructs a new jQuery object with an empty set and a length property of 0.
If you'd like to check whether $("p").eq(4) has successfully found an element, you can do something like this:
var paragraphFive = $("p").eq(4);
if (paragraphFive.length) {
// It exists
}
else {
// It doesn't
}

This (and many other selectors) will always return a jQuery object, regardless of whether the selector matched any elements. In the case that no elements are matched, the jQuery object returned will contain zero elements; you can test for this with .length:
console.log($("p").eq(4).length) // 0

Created this JsFiddle
HTML:
<p>first</p>
<p>second</p>
Script:
$(document).ready(function(){
window.console&&console.log($("p").length);
});
This will log '2'. You can always check if there is 4 elements in your array before reading it. This is good practice in ANY programming language BTW...

This happens because there is no 4th element to return. jQuery returns an empty set for your selection.
Try:
var el;
(el = $('p').eq(4)).length != 0 ?
el.html('some html') :
console.log('did nothing');
http://jsbin.com/dizem/1/edit

Related

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

Mootools Selector issue

Right now I have a dynamic string that assigns it's values to a particular div class.
Output looks like this
<div class="12923"></div>
I want to find that 'randNumber' div, then check if it has another class 'x'
Currently what I have now doesn't work:
var randNumber = 12923
var lookingForYou = $$('.'+randNumber);
if (lookingForYou.hasClass('XCLASS')){alert('XCLASS FOUND!');}
$$ returns an Elements instance, Elements is an array-like Class
anyway since you are basically filtering, you can tell Slick that you need an element with both class:
var randNumber = 12923;
if($$('.' + randNumber +'.XCLASS').length>0){
alert('XCLASS FOUND');
}else{
//dostuff
}
or you could just use one of the Elements methods, I think .some will be your best choice here:
var randNumber = 12923
var lookingForYou = $$('.' + randNumber);
alert(lookingForYou.some(function(el){
return el.hasClass('XCLASS');
}))
EDIT:
adding some links:
A better way to use Elements on MooTools blog
in my second example I used the some method, which, by looking at the source is not overloaded, but is just the one in Array.prototype.some:
Element.js source reference
Array.some on MDN
$$ returns an array of all matching elems. Not sure if you can do a hasclass on an array. Might have to do a .each() then do it. Try $('body').getElement('.'+randNumber).hasClass('XCLASS') this way you grab 1 elem if you don't want to mess with the array.
Here:
if (lookingForYou.hasClass('XCLASS')){alert('XCLASS FOUND!');}
$$() returns an array, and hasClass() performs the check on each element of the array, returning an array of booleans. Unfortunately, when you check if (...), then the return array, even if all of the values are false, is evaluated as true because it's non-empty.

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
}

Retrieving an element by array index in jQuery vs the each() function

I was writing a "pluginable" function when I noticed the following behavior (tested in FF 3.5.9 with Firebug 1.5.3).
$.fn.computerMove = function () {
var board = $(this);
var emptySquares = board.find('div.clickable');
var randPosition = Math.floor(Math.random() * emptySquares.length);
emptySquares.each(function (index) {
if (index === randPosition) {
// logs a jQuery object
console.log($(this));
}
});
target = emptySquares[randPosition];
// logs a non-jQuery object
console.log(target);
// throws error: attr() not a function for target
board.placeMark({'position' : target.attr('id')});
}
I noticed the problem when the script threw an error at target.attr('id') (attr not a function). When I checked the log, I noticed that the output (in Firebug) for target was:
<div style="width: 97px; height: 97px;" class="square clickable" id="8"></div>
If I output $(target), or $(this) from the each() function, I get a nice jQuery object:
[ div#8.square ]
Now here comes my question: why does this happen, considering that find() seems to return an array of jQuery objects? Why do I have to do $() to target all over again?
[div#0.square, div#1.square, div#2.square, div#3.square, div#4.square, div#5.square, div#6.square, div#7.square, div#8.square]
Just a curiosity :).
.find() returns not an array of jQuery objects, but one jQuery object containing an array of DOM elements (a jQuery object, at it's core, is a wrapper around a DOM element array).
When you're iterating through, each element you're on is a DOM element. So, it needs to be wrapped in $(this) to become jQuery object and have access to those methods.
Also as a side note: The id attribute can't begin with a number, since it's invalid HTML you may or may not experience strange behavior, especially cross-browser (this rule applies for any invalid HTML).
No, the find method doesn't return an array of jQuery objects. You are creating a jQuery object for each element here:
console.log($(this));
If you log the value without creating a jQuery object from it:
console.log(this);
you will see that it's an element, not a jQuery object.
When you access the jQuery object as an array, you get an element. If you want a jQuery object you have to create one from the element.

an array of strings as a jQuery selector? [duplicate]

This question already has answers here:
Easy way to turn JavaScript array into comma-separated list?
(22 answers)
Closed 6 months ago.
I have an array of strings that are valid jQuery selectors (i.e. IDs of elements on the page):
["#p1", "#p2", "#p3", "#p4", "#p5"]
I want to select elements with those IDs into a jQuery array. This is probably elementary, but I can't find anything online. I could have a for-loop which creates a string "#p1,#p2,#p3,#p4,#p5" which could then be passed to jQuery as a single selector, but isn't there another way? Isn't there a way to pass an array of strings as a selector?
EDIT: Actually, there is an answer out there already.
Well, there's 'join':
["#p1", "#p2", "#p3", "#p4", "#p5"].join(", ")
EDIT - Extra info:
It is possible to select an array of elements, problem is here you don't have the elements yet, just the selector strings. Any way you slice it you're gonna have to execute a search like .getElementById or use an actual jQuery select.
Try the Array.join method:
var a = ["#p1", "#p2", "#p3", "#p4", "#p5"];
var s = a.join(", ");
//s should now be "#p1, #p2, #p3, ..."
$(s).whateverYouWant();
What about $(foo.join(", "))?
Use the array.join method to join them together
$(theArray.join(','));
Going to officially answer your question: with a one-liner:
//If this is only one use variable you can use
$(['#p1','#p2','#p3','#p4','#p5'].join(',')).methodToUse();
//if you DO need it as a variable you can
var joined = ['#p1','#p2','#p3','#p4','#p5'].join(',');
$(joined).methodsToUse();
If you want them to do something individually there is also .each();
In the example below, each p ids clicks makes any one of them red:
var peas = ['#p1','#p2','#p3','#p4','#p5'];
$.each(peas, i => {
$(peas[i]).click(() => {
$(peas[i]).css({'color':'red'});
});
});
When you throw 'i' into a function parameter, it finds the values inside the arrays appropriately. When you do '.each()' the format looks like this:
$.each(array, function(i){
// any code you wish as long as you have an array selector
//$(array[i]).whatever function
});
An even bigger example. Say you want to make the P you click on red, but want the other ps return to default color. Just make a function that removes the selected ID from the array and voila!
var peas = ['#p1','#p2','#p3','#p4','#p5'],
poppy=(v,i)=>peas.toString().replace(`,${v[i]}`,'').replace(`${v[i]},`,'');
(// get each pea index
$.each(peas,i=>///funciton(i){ code inside}
(//set up each individual index's functions
$('.peastock').append(`<p id="p${[i+1]}">I am ${peas[i]}</p>`),
$(peas[i]).click(()=>(
$(peas[i]).css({"color":"red","background-color":"rgba(128,0,0,0.1)"}),
$(poppy(peas,i)).css({'color':'black','background-color':'rgba(255,255,255,0.2)'}))))),
$('.peastock').append(`
<div id="ree">ES6 isnt suitable for all of jQuery's usage!</div>
<div>Since some functions inside of jQuery's methods dont require 'this' or 'return'</div>
<div>You can learn this by going here</div>
`),
$("*").css({"margin":"0 auto","padding":"1%"}),
$("* .peastock, .peastock, .peastock *").css({"background-color":"rgba(128,0,0,0.1)"})
);
I know someone is bound to want to know about each value array as jquery selectors. Hope everything goes well!
Source:
jQuery .each()
The fiddle in action (with updates!)
I think you're looking for join.
var arr = ["#p1", "#p2", "#p3", "#p4", "#p5"];
$(arr.join(","))
Shorter:
$( ["#p1", "#p2", "#p3", "#p4", "#p5"].toString() );

Categories

Resources