IE 8 - Object doesn't support this property or method - javascript

I'm working on old IE Compatibility, specially IE 8.
But, my JS is not working ->
I got the Object doesn't support this property or method error on my item item_tracked
;(function () {
setTimeout(function () {
currentItems().forEach(function (item_tracked) {
/* item_tracked here */
$(item_tracked.getView()).addClass('animated');
/* item_tracked problem here */
});
}, 500);
})();
any idea?

Assuming currentItems() returns an Array, your problem is that IE8 does not support Array.prototype.forEach.
You could substite a for loop or use a polyfill.

Related

Javascript property thunk [duplicate]

I need to log setting of document.cookie. I can not redefine cookie property just with document.cookie = {...} So I need to get setter for document.cookie. But Object.getOwnPropertyDescriptor(document, "cookie") returns undefined.
UPD. While I was writing the question I found a working solution, but it uses deprecated __lookupGetter__ and __lookupSetter__ methods. Is there any solution which doesn't use obsolete API?
The standardized way of accessing getters and setters is with Object.getOwnPropertyDescriptor, but as the name suggests, it only looks on the objects own properties (it does not look up the prototype chain). document is an instance of HTMLDocument, which inherits from Document. In modern browsers the cookie property is defined on Document.prototype, whereas in older versions of Firefox it is defined on HTMLDocument.prototype.
var cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
if (cookieDesc && cookieDesc.configurable) {
Object.defineProperty(document, 'cookie', {
get: function () {
return cookieDesc.get.call(document);
},
set: function (val) {
console.log(val);
cookieDesc.set.call(document, val);
}
});
}
Ironically, in the most privacy-concerned browser Safari, the descriptor has set configurable to false and does not contain the getter nor setter, and neither does __lookupGetter__ or __lookupSetter__. So I haven't found a way to override document.cookie in Safari yet (8.0.8 on OS X and iOS 9.0.2). WebKit nightly acts the same way as Safari, so it doesn't seem to get fixed anytime soon.
Update October 2019: Tested the above code in Safari 12.1.2 on MacOS Mojave, and cookieDesk is now configurable! This means my proof of concept document.cookie protection from 2015 might actually work now :)
While I was writing the question I found next code solves my problem:
var cookie_setter_orig = document.__lookupSetter__("cookie").bind(document);
var cookie_getter_orig = document.__lookupGetter__("cookie").bind(document);
Object.defineProperty(document, "cookie", {
get: function () {
return cookie_getter_orig();
},
set: function (val) {
console.log(val);
cookie_setter_orig(val);
}
});
But I don't like using deprecated methods, so I hope there is a better solution.

JavaScript code working on other browsers but not working on IE11, why?

I am using this JS code to add a class on a activate bootstrap 4 navigation link, and on most browsers it is working, but on IE11 not. Any idea why?
"use strict";
var nav = document.querySelector('.navbar');
var links = nav.querySelectorAll('.highlight');
links.forEach(function(link){
if (link.href == window.location.href.split("#")[0]) {
link.classList.add('active');
}
});
links.forEach(function(link){
link.addEventListener('click', function(e) {
links.forEach(function(link){
link.classList.remove('active');
});
this.classList.add('active');
});
});
var kontaktLink = document.querySelector('.kontaktLink');
var navBarToggle = document.getElementById('navbarSupportedContent');
var togglerButton = document.querySelector('.navbar-toggler');
kontaktLink.addEventListener('click', function() {
if (navBarToggle.classList.contains('show')) {
navBarToggle.classList.remove('show');
navBarToggle.classList.add('collapse');
togglerButton.classList.add('collapsed');
togglerButton.setAttribute('aria-expanded','false');
}
});
Because of IE... :)
Check out your console output for errors. There will be some function that is not supported in ie 11
Unsupported querySelectorAll
Maybe unsupported classList property
Or maybe even forEach function
IE11 only support up to ECMAScript 5, whereas other more modern browsers use ECMAScript 6. They don't intent on updating it either.
ES 5 basically has less features for Javascript than ES 6, so that could be the culprit.
I like to use https://caniuse.com/ to see which functions are supported by which browser.
For example, it looks like querySelectorAll is supported by IE11:
https://caniuse.com/#search=queryselectorall
EDIT:
If you do wish to use ES6 features in IE11, you can have a look at BabelJS.
https://babeljs.io/
So, IE11 does not support forEach on a nodeList. I solved this problem by expanding the nodeList.prototype:
NodeList.prototype.forEach = Array.prototype.forEach;

Javascript Function not working in Edge

I created a function in Javascript
function addName(okDelete = true){
amountExtraStudents++;
if(amountExtraStudents > 2){
preisAktuell = 60;
}
if(!okDelete){
jQuery('#teilnehmerExtra').append('<div class="teilnehmer-1"></div>');
}else{
jQuery('#teilnehmerExtra').append('<div class="teilnehmer-2"></div>');
}
eintragNummer++;
updateButtons();
}
But in Edge I get this error:
In Safari I dont get any Error - but the Function - and all the other functions in the rest of the Script Block are not working.
It works out fine in Chrome, Firefox and Opera, but not in Safari, IE and Edge...
Is there something incompatible with the Browser?
The error is occuring when you use the 'default parameters' feature introduced in ES6. Edge does not support it.
An ES5 version would be:
function addName(okDelete){
if (typeof okDelete === "undefined") {
okDelete = true;
}
You might also consider using a tool such as Babel to transpile your ES6 into ES5.

Proxying of document.cookie

I need to log setting of document.cookie. I can not redefine cookie property just with document.cookie = {...} So I need to get setter for document.cookie. But Object.getOwnPropertyDescriptor(document, "cookie") returns undefined.
UPD. While I was writing the question I found a working solution, but it uses deprecated __lookupGetter__ and __lookupSetter__ methods. Is there any solution which doesn't use obsolete API?
The standardized way of accessing getters and setters is with Object.getOwnPropertyDescriptor, but as the name suggests, it only looks on the objects own properties (it does not look up the prototype chain). document is an instance of HTMLDocument, which inherits from Document. In modern browsers the cookie property is defined on Document.prototype, whereas in older versions of Firefox it is defined on HTMLDocument.prototype.
var cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
if (cookieDesc && cookieDesc.configurable) {
Object.defineProperty(document, 'cookie', {
get: function () {
return cookieDesc.get.call(document);
},
set: function (val) {
console.log(val);
cookieDesc.set.call(document, val);
}
});
}
Ironically, in the most privacy-concerned browser Safari, the descriptor has set configurable to false and does not contain the getter nor setter, and neither does __lookupGetter__ or __lookupSetter__. So I haven't found a way to override document.cookie in Safari yet (8.0.8 on OS X and iOS 9.0.2). WebKit nightly acts the same way as Safari, so it doesn't seem to get fixed anytime soon.
Update October 2019: Tested the above code in Safari 12.1.2 on MacOS Mojave, and cookieDesk is now configurable! This means my proof of concept document.cookie protection from 2015 might actually work now :)
While I was writing the question I found next code solves my problem:
var cookie_setter_orig = document.__lookupSetter__("cookie").bind(document);
var cookie_getter_orig = document.__lookupGetter__("cookie").bind(document);
Object.defineProperty(document, "cookie", {
get: function () {
return cookie_getter_orig();
},
set: function (val) {
console.log(val);
cookie_setter_orig(val);
}
});
But I don't like using deprecated methods, so I hope there is a better solution.

Object.create on IE6+

I have a little problem, because I wrote my plugin using Object.create and it's working only on IE9+.
My plugin definition:
$.fn.MYPL = function (options) {
return this.each(function () {
myplg = Object.create(MYPL);
myplg.init(options, this);
});
};
But before every JS code I have the following:
if (typeof Object.create !== "function") {
Object.create = (function () {
function F() {} // created only once
return function (o) {
F.prototype = o; // reused on each invocation
return new F();
};
})();
}
It works fine on IE9+ but IE6 and IE7 (even IE8) seems to be not supporting Object.create or what? Am I missing sth?
Check Wikipedia's JavaScript version history. If you find 1.8.5 version - and this is the language version where you find this Object factory method available - 9th version of Internet Explorer is the one supporting that.
The ECMAScript 5 Compatibility Table also has this information.
You can also try for yourself using one of Microsoft's IE virtual machines (available from here or, for very old versions of IE, Multiple IE.
Sourced from From which version, IE can support Object.create(null)?
Older IE versions will not support Object.create. Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Try to create object using constructor which is described here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain

Categories