Javascript - forEach() loops not working on IE11 - javascript

forEach loops are supposed to be working in IE11 and diplay
Object doesn't support property or method 'forEach'.
It should be working since it's an ECMAScript-5 function and IE11 supports it.
However, my code here is not working:
var alltable = document.querySelectorAll('*[id^="table_"]'); //Select all elements with the id starting by "table_"
alltable.forEach(function(element) {
// Do some code
});
Any idea why ?

Well myself,
forEach() is actually working on IE11, just be careful on how you call it.
querySelectorAll() is a method which return a NodeList.
And on Internet Explorer, foreach() only works on Array objects. (It works with NodeList with ES6, not supported by IE11).
To fix this, some would advice a polyfill, which could work great, but you can also simply convert your NodeList into an array with the slice.call() method: (Explained here)
var alltable = document.querySelectorAll('*[id^="table_"]'); //Select all elements with the id starting by "table_"
var alltableArray= Array.prototype.slice.call(alltable);
alltableArray.forEach(function(element) {
// Do some code
});
Or:
var alltable = Array.prototype.slice.call(document.querySelectorAll('*[id^="table_"]')); //Select all elements with the id starting by "table_"
alltable.forEach(function(element) {
// Do some code
});
To sum up:
Be sure you're using it on an Array object and not a NodeList.
Hope that can help someone.

Related

Convert NodeList to Array for a Stepper to work with IE

I want to create a simple Vanilla JS horizontal stepper without the addition of CSS or JS libraries.
I have found this example but it doesnt work with IE browser.
The problem is the following line:
const bullets = [...document.querySelectorAll('.bullet')];
where he is converting the NodeList of 'divs' with class .bullet to Array.
Is there any way to make it work because I have tried "Array.prototype.slice" and copy the Nodelist in a JS array without success..
I would just iterate though the the nodeList with something like a for loop and add the nodelist item to the array . Something like this:
let bulletsArray = [];
let bullets = document.querySelectorAll('bullets');
for(let i = 0; i < bullets.length; i++) {
bulletsArray.push(bullets[i])
}
Heres a working demo: https://codepen.io/inklingboi/pen/BapmdBw?editors=1010
Note: my initial idea was to use Array.from() but after checking its compatibility list on mdn https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from i noticed that it isnt supported in IE
It seems that IE does not support addEventListener() function because I get an error at that line:
nextBtn.addEventListener('click', ()=> {..});

Onclick doesn't work in userscript [duplicate]

I am trying to run a function onclick of any button with class="stopMusic". I'm getting an error in Firebug
document.getElementByClass is not a function
Here is my code:
var stopMusicExt = document.getElementByClass("stopButton");
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You probably meant document.getElementsByClassName() (and then grabbing the first item off the resulting node list):
var stopMusicExt = document.getElementsByClassName("stopButton")[0];
stopButton.onclick = function() {
var ta = document.getElementsByClassName("stopButton")[0];
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You may still get the error
document.getElementsByClassName is not a function
in older browsers, though, in which case you can provide a fallback implementation if you need to support those older browsers.
Before jumping into any further error checking please first check whether its
document.getElementsByClassName() itself.
double check its getElements and not getElement
As others have said, you're not using the right function name and it doesn't exist univerally in all browsers.
If you need to do cross-browser fetching of anything other than an element with an id with document.getElementById(), then I would strongly suggest you get a library that supports CSS3 selectors across all browsers. It will save you a massive amount of development time, testing and bug fixing. The easiest thing to do is to just use jQuery because it's so widely available, has excellent documentation, has free CDN access and has an excellent community of people behind it to answer questions. If that seems like more than you need, then you can get Sizzle which is just a selector library (it's actually the selector engine inside of jQuery and others). I've used it by itself in other projects and it's easy, productive and small.
If you want to select multiple nodes at once, you can do that many different ways. If you give them all the same class, you can do that with:
var list = document.getElementsByClassName("myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
and it will return a list of nodes that have that class name.
In Sizzle, it would be this:
var list = Sizzle(".myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
In jQuery, it would be this:
$(".myButton").each(function(index, element) {
// element is a node with the desired class name
});
In both Sizzle and jQuery, you can put multiple class names into the selector like this and use much more complicated and powerful selectors:
$(".myButton, .myInput, .homepage.gallery, #submitButton").each(function(index, element) {
// element is a node that matches the selector
});
It should be getElementsByClassName, and not getElementByClass. See this - https://developer.mozilla.org/en/DOM/document.getElementsByClassName.
Note that some browsers/versions may not support this.
My solutions is:
Change:
document.getElementsByClassName('.className')
To:
document.querySelector('.className')
you spelt it wrongly, it should be " getElementsByClassName ",
var objs = document.getElementsByClassName("stopButton");
var stopMusicExt = objs[0]; //retrieve the first node in the stack
//your remaining function goes down here..
document['player'].stopMusicExt(ta.value);
ta.value = "";
document.getElementsByClassName - returns a stack of nodes with more than one item, since CLASS attributes are used to assign to multiple objects...
it should be getElementsByClassName NOT getElementByClassName ==> you missed "s" in Elements
const collectionItems = document.getElementsByClassName('.item');
document.querySelectorAll works pretty well and allows you to further narrow down your selection.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
document.getElementByClass is not a function
Yes, it is not a function nor method because it should be document.getElementsByClassName
enter code here
var stopMusicExt = document.getElementByClass("stopButton").value;
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
// .value will hold all data from class stopButton
The getElementByClass does not exists, probably you want to use getElementsByClassName. However you can use alternative approach (used in angular/vue/react... templates)
function stop(ta) {
console.log(ta.value) // document['player'].stopMusicExt(ta.value);
ta.value='';
}
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 1'>
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 2'>
If you wrote this "getElementByClassName" then you will encounter with this error "document.getElementByClass is not a function" so to overcome that error just write "getElementsByClassName". Because it should be Elements not Element.

referring the array with a dynamic string name

I have an array.
var ABCD=[{Key:"Milk",Value:"1" },{Key:"Bread",Value:"2" }];
now need to find using the key in this array (ABCD) using a dynamic string value (returned from a function myFunction("guest_user")). I am using something like this which is working in all the browsers apart from IE because of the eval() and would be great if someone can advise on this.
var entry = eval(myFunction("guest_user")).find(function(e) { return e.Key === "Milk"; });
the return value myFunction("guest_user") is ABCD which is the array name defined above.
myFunction is returning a request parameter .. .
function myFunction(key) {
var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search);
return result && unescape(result[1]) || "";
}
The issue in IE11 is not the eval() function. It's the find() method.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find, and you'll see that find() is not supported in Internet Explorer.
You can, however, add the functionality to IE by using the Polyfill from the same link.
That said, it's best to avoid using eval() altogether. You can do so by placing your arrays in an object, such as:
var obj = {ABCD: [{Key ...}];
You can then reference the appropriate array by calling:
obj[myFunction("guest_user")].find(...
adding polyfill method (Adding a function to Array.prototype in IE results in it being pushed in to every array as an element ) and as Rick advised obj[myFunction("guest_user")].find( is working on IE.

Javascript DOM: Pinpointing "input" elements by their type?

I have a need to find and manipulate <input type="checkbox"> from a table. At the moment I have a very spartan function:
function testAjaxCheckBoxes() {
var table = document.getElementById("ajax_output");
var nodeList = table.getElementsByTagName("input");
}
That is all I know how to do at the moment. I have a nodeList object of all tags of <input>, but I don't know how to check each one's type or attributes.
I suppose the more general question is how do you view and manipulate attributes of any kind through DOM?
If you have the luxury of targeting Firefox >=3.5 and IE >=8, you can use
document.querySelectorAll("input[type=file]")
to get an array of DOM elements as desired. See more at the MDC documentation.
Once you have an element, you can use the getAttribute, setAttribute, and removeAttribute methods to read, write, and remove attributes.
.getAttribute(attr);
so, if you want to check each item in the nodeList to see if it's a fileupload...
var nodeList = document.getElementsByTagName("input");
for(item in nodeList) {
if(nodeList[item].getAttribute("type") == "file") {
alert("i'm a file");
}
else {
alert(nodeList[item].getAttribute("type"));
}
};
If you where to use a library (you should) like JQuery/Mootools etc
It would look like that
var inputs=$('#ajax_output input[type=checkbox]');
OR
var inputs=$('ajax_output').getElements('input[type=checkbox]');`

Convert NodeList to array

I'm having a hard time converting a NodeList to an array in IE 8. The following works perfectly in Chrome, but in IE 8 toArray() is not recognized as valid:
NodeList.prototype.toArray = function() {
var a = [];
for (var i = 0, len = this.length; i < len; i++) {
a[i] = this[i];
}
return a;
}
document.all.tags("div").toArray();
I tried adding a prototype function to an array just to check my sanity and it works correctly. That makes me think IE 8 doesn't actually return a NodeList? Here's a full example:
http://jsfiddle.net/e4RbH/
What am I doing wrong?
If you're looking for a modern answer using ES6:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
var nodes = document.querySelectorAll('div');
nodes = Array.from(nodes);
Old question, but here is a tried & true method:
var nodes=document.querySelectorAll("div"); // returns a node list
nodes=Array.prototype.slice.call(nodes); // copies to an array
Explanation
document.querySelectorAll uses a CSS-style selector to find elements and returns a node list. It works as of IE 8.
The slice method copies a portion of an array-like collection (in this case all of it) into a new array.
call allows you to borrow a method from one object to use on another
To find the node list you could also have used `document.getElementsByTagName(), but this one is more flexible.
First, don't use document.all -- it's non-standard and deprecated. Use document.getElementsByTagName to get the DIV elements in your case.
Second, don't extend DOM objects such as NodeList -- built-in objects are a very strange breed and are not required to behave like any other objects that you generally work with. See this article for an in-depth explanation of this: What's wrong with extending the DOM.
IE doesn't support NodeList in the standard way. This is why you should roll your own namespace and NOT extend browser core objects.
You can do alert( typeof window.NodeList ) and see if it's undefined or not.

Categories

Resources