getComputedStyle substitue: currentStyle (IE8/7) not working - javascript

I am having an issue with currentStyle which I have read is the fix before IE9 for getComputedStyle support.
I recently made this other thread regarding getting a reference to the top level LI list of a multi level navigation menu:
Selecting <li> child node but not grandchildren with vanilla JavaScript
Now I need to be able to measure the width or height of the LI's I am not able to reference with the help I received. It works, but not below IE9.
Here is what I've tried for getting the width:
this.w =function( elm ){
var s = (window.getComputedStyle) ? window.getComputedStyle(elm, "") : elm.currentStyle;
return parseInt(s.width);
}
the width comes back as NaN
SCRIPT5007: Unable to get property 'innerHTML' of undefined or null reference
I really appreciate everyone's help

elm.currentStyle.width returns "auto" when no width has been specified.
This correctly reflects the current style setting, but doesn't give you the value that you are looking for (as you might have expected getComputedStyle to do).
Instead, use elm.clientWidth
So in your example, you might use...
this.w =function( elm ){
var s = (window.getComputedStyle) ? window.getComputedStyle(elm, "") : elm.clientWidth;
return parseInt(s.width);
}
(tested in IE8 but not IE7)

Related

Array.from() with HTMLcollection does not seem to work in Chrome browser

I have a JavaScript piece of code that works on all browsers (even IE) but fail with Chrome on my HUAWEI P8 Lite with Android 6.
Chrome is version 71.0.3578.99.
The faulty code is var class_arr = Array.from(class); where class is a HTMLcollection.
It seems like Array.from() is failing although it should be supported by Chrome on mobile.
Also, I've noticed that this same code used to work one update ago, and not two updates ago strangely.
You can test the problem with this URL (of course this won't be valid as long as if I'll find a solution to my problem). You need to open the sidebar on the left and try to zoom in the map with the Plus or Minus button.
EDIT
Here is the code where I use Array.from():
export function updateSlider(all_sliders, ol_layers, class_layers) {
// updates slider with the actual opacity of the layers
for (var i = 0, len_i = all_sliders.length; i < len_i; ++i) {
var curr_slider = all_sliders[i];
// get layer from ol_layers whose title is equal to current slider id
// Find the value of the first element/object in the array, otherwise undefined is returned
// (https://stackoverflow.com/a/13964186/1979665)
var lyr = ol_layers.find(obj => {
return obj.values_["title"] === curr_slider.getAttribute("id")
});
// get class_layer (layerswitcher) from class_layers whose title is equal to current slider id
// (first we need to convert class_layers from HTMLCollection to array otherwise .find will fail)
var class_layers_arr = Array.from(class_layers);
var class_elem = class_layers_arr.find(obj => {
return obj.innerText.replace('\t','') === curr_slider.getAttribute("id")
});
// get current layer opacity and set it as the value of current slider
var curr_opacity = lyr.values_["opacity"];
curr_slider.setAttribute("value", curr_opacity);
// create new li element
var li_elem = document.createElement("LI");
// add slider input to li elem
li_elem.appendChild(curr_slider);
// add li with layer legend after layer li
insertAfter(li_elem, class_elem);
changeOpacity(curr_slider, ol_layers);
}
}
class_layers is first defined in another script as var class_layers = document.getElementsByClassName("layer");
EDIT 2
Ok, so apparently the problem is related to Chrome in general, not only on mobile. In fact, if you try the above URL in Chrome Desktop, you can reproduce the error by opening the sidebar (on the left), then closing it and pressing the + or - symbol to zoom in the map. I guess it has to do with the way click events are treated by either my code and OpenLayers. I am probably deleting this question as it sounds like I need to dig further in problematic.
SOLUTION
Not deleting because I think it maybe useful for others to see the solution.
Here is the link to the OpenLayers github issue I created and closed: https://github.com/openlayers/openlayers/issues/9105.
The problem was the event "change:resolution" fired by the View class of OL (v5.3.0) that is emitted multiple times during animation (problem also quoted here).
NEW CONSIDERATION
Turns out that I still had the problem on mobile devices.
The real fix was not to use innerText in my code and switch to innerHTML, as it was always empty in (and only in) Chrome, while with the other browsers it was not (I could actually see the string). If you are interested I can try to provide an example, but unfortunately I could not find much on this problem in the web...
It's not Array.from() problem.
Check your class_elem variable
It's undefined (because no element found for your conditions) and then it fails when your trying to get parentNode of undefined in:
export function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

Unable to get property 'options' of undefined or null reference

i am getting the above error in ie 10 please give me a suggestion.it is working fine in
function getSelectedIndex(element, value) {
var selectedIndex = 0;
for(i = 0; i < element.options.length; i++) {
if(element.options[i].value == value) {
selectedIndex = i;
break;
}
}
return selectedIndex;
}
element.options.length is giving Unable to get property 'options' of undefined or null reference.please suggest me a sample code.
Edit : It was working for me when I was using IE11 with compatibility mode, but when I removed it and ran it in normal mode, the above issue occurred.
Use elements.options.indexOf(value) (assuming element is defined, which it doesn't seem to be). By the way, your current design will return zero if the first element matches or there is no match at all. If you really want to write your own version of indexOf, better to return -1 in the case of no match as it does.
actually the message gives you exactly what you need to know.
you are trying to read a property of something that does not have a value, and here it is "element" or "element.options", check the place where they are set before the function call.
for IE10 it's a strict one, it doesn't support the use of
element.options.length
instead you should use:
document.getElementById("optionsID").value
I hope this helps

Portability of nextElementSibling/nextSibling

I'm currently writing an accordion and running into the same problem as described in nextSibling difference between IE and FF? - specifically differences between Microsoft's nextSibling / nextElementSibling and that implemented by everyone else.
For various reasons, using jquery is not an option. Nor is getting all my MS users to upgrade to MSIE9
Currently I'm using the following code to work around the problem:
// tr is a TR doc element at entry....
while (nthRow--) {
// for Chrome, FF tr=tr.nextElementSibling; for MSIE...tr=tr.nextSibling;
tr=tr.nextElementSibling ? tr.nextElementSibling : tr=tr.nextSibling;
if (!tr || tr.nodeName != "TR") {
break;
}
tr.style.display="";
}
Which seems to do what I expect in MSIE6, FF and Chrome - i.e. the nthRow TR elements below the initial TR are made visible (previously style.display="none").
But is this likely to have unexpected side effects?
(I'm a bit of a newbie with Javascript ;)
nextSibling will see HTML code comments, so be sure to keep them out.
Other than that you should be alright since you won't have any text nodes between your tr elements.
The only other issue I could think of would be in Firefox 3 where nextElementSibling hadn't yet been implemented. So if you're supporting that browser, you'll need to manually emulate nextElementSibling. (Pretty sure they had it implemented in FF3.5 though.)
You'll be safer to create a nextElementSibling() function:
tr = tr.nextElementSibling || nextElementSibling(tr);
function nextElementSibling( el ) {
do { el = el.nextSibling } while ( el && el.nodeType !== 1 );
return el;
}
Considering previous answers, I am currently implementing it this way to grant cross-browser compatibilty:
function nextElementSibling(el) {
if (el.nextElementSibling) return el.nextElementSibling;
do { el = el.nextSibling } while (el && el.nodeType !== 1);
return el;
}
This way, I can avoid the do/while loop for browsers that support nextElementSibling.
Maybe I'm too scared of WHILE loops in JS :)
One advantage of this solution is recursability:
//this will always works:
var e = nextElementSibling(nextElementSibling(this));
//this will crash on IE, as looking for a property of an undefined obj:
var e = this.nextElementSibling.nextElementSibling || nextElementSibling(nextElementSibling(this));
Firefox nextSibling returns whitespace \n while Internet Explorer does not.
Before nextElementSibling was introduced, we had to do something like this:
var element2 = document.getElementById("xxx").nextSibling;
while (element2.nodeType !=1)
{
element2 = element2.nextSibling;
}

how can i pass a parameters to a function to get current Style

Good day,
I wonder how to get currentStyle in IE, passing parameters to an function argument like this:
function test(el,value){
return document.getElementById(el).currentStyle[value];
}
if i'd use a similar function to get Style from Firefox, Chrome and so on, it would result.
using a function like this:
function test(el,value){
return getComputedStyle(document.getElementById(obj))[value];
}
, where value is the element property like backgroundColor, i.e:
alert(test('ObjectId','backgroundColor'));
....
it would return backgroundColor in FF, Chrome.. but not in Internet Explorer
What r possibles solutions..?
Thnx..
please i'm not looking for a jQuery soluction...
Here what I use to retrieve a style property value
function getStyle(el,sProp,toInt){
var elem = el;
if (elem.currentStyle) {
return toInt
? parseInt(elem.currentStyle[sProp],10)
: elem.currentStyle[sProp] || 0;
} else if (window.getComputedStyle) {
var compStyle = window.getComputedStyle(elem, null)[sProp];
return toInt ? parseInt(compStyle,10) : compStyle || 0;
}
return String(elem.style[sProp]||0);
}
This is (sadly) very complex.
I have written a browser independent resolver but I can't share it with you.
Unless you are writing your own framework I have to ask, why do you want to be able to resolve everything?
Is there a specific property (or some properties) you want? Because that could be a lot easier.
If you just want the background color then .style.backgroundColor is probably sufficient.
Also, there is a bug in your example script:
alert(test('ObjectId'),'backgroundColor');
Should be:
alert(test('ObjectId','backgroundColor'));
Not the first time I made the same mistake ;) - took me half a day to find it

Works in firefox but not IE8

This is working fine in firefox but only closes the first page and then breaks in IE8. Firebug in IE8 says that x.item(o) is null. I can't figure out why this works in firefox but not IE. Thanks for any help.
pager(x=document.getElementsByName("pg1"));
function pager( x ) {
var curr = document.getElementById('showing');
$(curr).fadeOut('fast');
curr.id = 'hide';
$(x).fadeIn('slow');
x.item(0).id ='showing';
}
if(x.item(0).id = NULL )
That's an assignment. You wanted == for comparison.
(What's NULL in capital letters? An element's id property won't be null; if it's not set, it'll be an empty string.)
It seems to me you'd be better off using jQuery's toggle method.

Categories

Resources