I tried to put a series of DOM elements having the same class inside an array, and then try to find what index is one of them located by using .indexof(). However, it seems like it is not working. Did I wrote anything wrong? Or there should be other ways that I can find an index of an element in a array?
Here is a little piece of code
window.onload = function(){
var addBtn = document.querySelectorAll(".add");
for(var i = 0; i < addBtn.length; i++){
addBtn[i].onclick = addTime;
}
};
function addTime(){
var update = parseInt(this.parentElement.getElementsByTagName("SPAN")[0].innerHTML) + 1;
var digits = this.parentElement.parentElement.querySelectorAll(".digit");
if(digits.indexOf(this.parentElement) % 2){ //Uncaught TypeError: digits.indexOf is not a function
}else{
carryOn(this, update);
}
}
It just keep telling me that "Uncaught TypeError: digits.indexOf is not a function".
querySelectorAll return a NodeList, it's an array-like object, not an actual array. It does not have an indexOf methods.
You can:
cast array method on an array-like by Array.prototype.indexOf.call(digits, ....).
produce a real array by Array.from(digits).
Related
In this code I want to remove an element from the cart_products array.
var cart_products = ["17^1", "19^1", "18^1"];
var product = 17;
$.each(cart_products,function(key, item) {
if(item.indexOf(product+"^") !== -1){
cart_products.splice(key, 1);
}
});
But I get this error in Google Chrome console:
Uncaught TypeError: Cannot read property 'indexOf' of undefined
Is there something wrong with the code?
Thanks for your help.
The problem is that you're modifying the array while jQuery's $.each is looping over it, so by the time it gets to the end, the entry that used to be at index 2 is no longer there. (I admit I'm a bit surprised $.each behaves that way, but I haven't used $.each in at least five years, so...)
If the goal is to remove matches from the array, the better choice is filter:
var cart_products = ["17^1", "19^1", "18^1"];
var product = 17;
cart_products = cart_products.filter(function(item) {
return item.indexOf(product+"^") === -1;
});
console.log(cart_products);
...or alternately if it's important to modify the array in-place rather than creating a new one use a boring for loop as Andreas points out looping backward through the array so it doesn't matter when you remove things:
var cart_products = ["17^1", "19^1", "18^1"];
var product = 17;
var target = product + "^";
for (var index = cart_products.length - 1; index >= 0; --index) {
if (cart_products[index].indexOf(target) !== -1) {
cart_products.splice(index, 1);
}
}
console.log(cart_products);
First of all, you don't need to use a jQuery each for this. Second, it's not a great idea to alter an array that you are operating on. If you're trying to remove elements from an array, use filter. Filter has the following signature:
someArray.filter(function(item, index, array) {
// return a value that is truthy to keep an item or falsey to remove it
})
Filter returns a new array with only the values that match what you want. That means you don't mess with your original array, which is a good idea anyways. In your case it would look like this:
var filteredProducst = cart_products.filter(function(item) {
return item.indexOf(product + "^")
})
I tried the following: it is working fine
function saveTitle(index,id){
arrtitle[1] = document.getElementById("title_1").value;
arrtitle[2] = document.getElementById("title_2").value;
arrtitle[3] = document.getElementById("title_3").value;
}
but as I tried the following:
function saveTitle(index,id){
for(i=1;i<=count;i++)
arrtitle[i] = document.getElementById("title_"+i).value;
}
It gives me an error that : Uncaught TypeError: Cannot read property 'value' of null
Please suggest me something. Thanks...
You can use querySelectorAll to get all the elements that contains "title_" string . See the bellow code.
function getTitles() {
var arrtitle = [];
var elements = document.querySelectorAll("*[id*='title_']");
for (i = 0; i < elements.length; i++) {
var titleId = elements[i].id.replace("title_", "");
arrtitle[titleId] = elements[i].value;
}
return arrtitle;
}
getTitles();
Based on what you've posted, if that's your actual code, the only possibility seems to be that count is higher than the maximum element that exists (or there's a hole). For example, count might be 4, and there is no element with the id of title_4.
The javascript debugger would help you find this pretty easily.
I'd also suggest using braces around the body of your for loop, which would significantly help readability.
I have an Array of a few hundred JSON Objects...
var self.collection = [Object, Object, Object, Object, Object, Object…]
Each one looks like this...
0: Object
id: "25093712"
name: "John Haberstich"
I'm iterating through the Array searching each Array.id to see if it matches any ids in a second Array...
var fbContactIDs = ["1072980313", "2502342", "2509374", "2524864", "2531941"]
$.each(self.collection, function(index, k) {
if (fbContactIDs.indexOf(k.id) > -1) {
self.collection.splice(index, 1);
};
});
However this code only works to splice three of the Objects from the self.collection array and then it breaks and gives the following error:
Uncaught TypeError: Cannot read property 'id' of undefined
The line that is causing the error is this one...
if (fbContactIDs.indexOf(k.id) > -1) {
Could anyone tell me what I'm dong wrong here?
Because the length of collection will change, the trick is to loop from rear to front
for (var index = self.collection.length - 1; index >= 0; index--) {
k = self.collection[index];
if (fbContactIDs.indexOf(k.id) > -1) {
self.collection.splice(index, 1);
};
}
You should not change the length of an array while iterating over it.
What you're trying to do is filtering and there's a specific function for that. For example:
[1,2,3,4,5,6,7,8,9,10].filter(function(x){ return (x&1) == 0; })
will return only even numbers.
In your case the solution could then simply be:
self.collection = self.collection.filter(function(k){
return fbContactIDs.indexOf(k.id) > -1;
});
or, if others are keeping a reference to self.collection and you need to mutate it inplace:
self.collection.splice(0, self.collection.length,
self.collection.filter(function(k){
return fbContactIDs.indexOf(k.id) > -1;
}));
If for some reason you like to process elements one at a time instead of using filter and you need to do this inplace a simple approach is the read-write one:
var wp = 0; // Write ptr
for (var rp=0; rp<L.length; rp++) {
if (... i want to keep L[x] ...) {
L[wp++] = L[rp];
}
}
L.splice(wp);
removing elements from an array one at a time is an O(n**2) operation (because for each element you remove also all the following ones must be slided down a place), the read-write approach is instead O(n).
In this code snippet from AdvancED DOM Scripting:
The call to delete(classes[i]); is this an array or object method? I'm unable to Google an answer.
/**
* remove a class from an element
*/
function removeClassName(element, className) {
if(!(element = $(element))) return false;
var classes = getClassNames(element);
var length = classes.length
//loop through the array in reverse, deleting matching items
// You loop in reverse as you're deleting items from
// the array which will shorten it.
for (var i = length-1; i >= 0; i--) {
if (classes[i] === className) { delete(classes[i]); }
}
element.className = classes.join(' ');
return (length == classes.length ? false : true);
};
window['ADS']['removeClassName'] = removeClassName;
The Mozilla Reference Docs says the following regarding the delete operator:
The delete operator deletes an object, an object's property, or an element at a specified index in an array.
For more information, see the following article:
http://perfectionkills.com/understanding-delete/
delete will set the value of the specified member (variable/array/object) to undefined
array/object example...
since classes[i] is actually referencing the i index of the array. It will set that specific index position to undefined, reserving the position in the array...
I think you can use simply $('p').removeClass('myClass yourClass') with jquery and put together a function to do so for any element
this is a function to call SELECT element values. but i am facing an error.
code is here.
function get_s_val(){
var foo = all_categories_1;
var ov1 = "";
for(m=0;m<=foo.length;m++){
ov1 += foo[m].value+',';
}
console.log(ov1);
var tme=setTimeout("get_s_val()", 1000);
}
get_s_val();
it shows an error like "Uncaught TypeError: Cannot read property 'value' of undefined"
but when i do some littel changes it works.. like
function get_s_val(){
var foo = all_categories_1;
var ov1 = "";
//for(m=0;m<=foo.length;m++){
ov1 += foo[0].value+',';
//}
console.log(ov1);
var tme=setTimeout("get_s_val()", 1000);
}
get_s_val();
i dont know that where i am wrong to write the code.
Modify your loop condition to run while the iterator is less than the length of the array, or you'll get undefined when you hit the non-existent element at index foo.length:
for(var m=0;m<foo.length;m++){
ov1 += foo[m].value+',';
}
...and always declare variables with the var keyword, or bad things will happen, and JSLint will whine about it (and rightly so, but that's another topic).
function get_s_val(){
var foo = all_categories_1;
var ov1 = "";
for(var m = 0; m < foo.length; m++){ // use var, and only loop from e.g.
// 0 to 2 when the length is 3, so <,
// not <=
ov1 += foo[m].value+',';
}
console.log(ov1);
setTimeout(get_s_val, 1000); // don't use a string, just pass the function.
// Plus, the variable is nowhere accessible so
// you can drop storing it
}
get_s_val();
Anyway, if you simply want to join the array's elements into a string with , as delimiter, why not do:
console.log(foo.join());
At the top of the for loop, m<=foo.length; should instead be m<foo.length;.