why is if (element.innerHTML == "") not working in firefox
but works fine in IE , any ideas please ?
Hard to say without seeing your HTML, but I'd say probably because you have some empty white space in the element, and IE doesn't treat that as a text node, while FF does.
I believe it is actually a more strict standards compliance to treat any empty white space between tags as a text node, but IE doesn't comply.
You could do:
var htmlstring = element.innerHTML;
// use the native .trim() if it exists
// otherwise use a regular expression
htmlstring = (htmlstring.trim) ? htmlstring.trim() : htmlstring.replace(/^\s+/,'');
if(htmlstring == '') {...
Or just get rid of the whitespace in your HTML markup manually.
An alternative method to check for the empty string is to check the length:
element.innerHTML.length == 0
But, you'd still have to trim() if you had a whitespace string you wanted to match.
You could check if element.innerHTML.trim() == "" for the best results. However, then you have to extend the string prototype with a trim() method:
if (!String.prototype.trim) {
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };
}
if (element.innerHTML.trim() == "") {
//do something
}
For me, it seemed like setting my innerHTML was not working in Firefox nor Chrome but it did work in IE because of my error. It turned out that I was never getting the element using getElementById in the first place. IE seems to do just fine with elements which are defined with name= with getElementById but Firefox and Chrome was more stringent and accepts only id= elements. (More correctly in my view)
I hope this saves somebody some frustration.
Why does IE do these sorts of things and confuse people...
Related
I have problem with my javascript code working on IE. I think I know exactly why it is working wrong, although I dont know how to change it.
Let me explain:
My code consist of small part of code inside $(document).ready() and a lot of inside $ajax.success(). The first part works normally, then I thought I have problem with ajax - that it simply dont work on IE. The error was:
Script65535 unexpected call to method or property access.
Jquery - 1.7.2.min.js line 5847, character 5
And line 5847 is APPEND function!!! It simply must work!
5844 append: function() {
5845 return this.domManip(arguments, true, function( elem ) {
5846 if ( this.nodeType === 1 ) {
5847 this.appendChild( elem );
5848 }
5849 });
5850 }
Then I found on google, that IE have problems when the multi-dimension array is changed to text. And only two appends in my ajax.success() function appends the content of arrays!
$('.display_info_here').append(tab_szablony[i][lang_number-2].toUpperCase()+'</br></br>');
I tried to change the array to text in another way, but it didnt worked
var arrr = tab_szablony[i][lang_number-2];
$('.display_info_here').append(arrr.toUpperCase()+'</br></br>');
It works on IE 9+, but not in 8 :(
Thanks for any help :)
Ok guys/girls.
Below is some jQuery that runs in Firefox but no IE. I have no idea why it craps out in one and not the other.
Anyone??
function SwapTextAssetforPOS() {
$("*").each(function () {
if ($(this).children().length == 0) {
$(this).text($(this).text().replace('Assets', 'POS'));
$(this).text($(this).text().replace('Asset', 'POS'));
$(this).text($(this).text().replace('assets', 'POS'));
$(this).text($(this).text().replace('asset', 'POS'));
}
});
}
Sorry folks - the error that I get is:-
SCRIPT65535: Unexpected call to method or property access.
jquery-1.6.min.js, line 16 character 60352
EDIT:------------------------------------------------------------------------------------
Ok so an update - I removed the * selector and IE no longer blows up, my issue now is that I cant figure how to get it to do the replace on the element. I have the following code to ping up all the text elements in the object:
function SwapTextAssetforPOS() {
var containerElementByID = $("#assetDetailContents");
containerElementByID.children().children().each(function () {
var $this = $(this);
alert($this.text());
});
This chucks me up an alert for every bit of text, however some is contained within a table, some is within a span, and some is just there. I have no control over a majority of this stuff so my new question is how do I get the previous replace to work using this type of selector. -- I can believe how painful this is..
Cheers again
I see the problem in my IE browser. When you do the $("*").each... it takes every single element in the page (including title, script, etc). When you do .text(), looks like it fails for some elements in IE for which .text() doesn't make sense. Replace "*" for "div" and it should work for the divs for example.Maybe you could do something like if ($(this).text()) {$(this).text($(this).text().replace('Assets', 'POS'));} to make sure the text() is defined for that element.
Still, going through the whole DOM is overkill. Can you add a class to the elements that can have the text?, like class="replaceable" so you could just do a $(".replaceable").text(...
Ok folks - so firstly thanks for the help.
I have resolved the issue by cobbling a number of suggestions together and by doing a little bit of investigative work.
In a nutshell IE was crapping out when it ran up against an tag. I no not why but this is where it fell over every time.
function SwapTextAssetforPOS() {
var overlaycon = $("#jq-selectionHelper").find("*:not(img)"); //This line simply looks at the div surrounding the template and returns (to an array I believe) every element therein except for img tag
//as this breaks in IE when tying to do the replace text stuff below.
overlaycon.each(function () {
var $this = $(this);
if ($this.children().length == 0) {
$this.text($(this).text().replace('Assets', 'POS'));
$this.text($(this).text().replace('Asset', 'POS'));
$this.text($(this).text().replace('assets', 'POS'));
$this.text($(this).text().replace('asset', 'POS'));
}
});
}
This code runs and I believe is a lot more efficient than my original offering. Any further suggestions for performance re-factoring are welcome but thank the lord this is now working.
Thanks again for all the help.
Regards
This code has no problem as seen here . I tested in IE and FF both works fine
http://jsfiddle.net/wKWRC/
You should use F12 developer tool for IE and see what error you are getting that way others can know what exact problem is . You can debug script and see where you are getting error . IE is sensitive to javascript errors and its possible there is some error before you are calling this function .
http://msdn.microsoft.com/en-us/library/gg699336%28v=vs.85%29.aspx
Just a hunch but you might be running out of memory in IE.
First, using $('*') is never advisable, its better that you narrow it down with a selector like $('p').
Also, every time you call $(this) you create a new jQuery object, so if there are a lot of elements on your page you're making 9 objects every time.
The convention is to set $this = $(this) at the begining of the function so you only use one object.
function SwapTextAssetforPOS() {
$("*").each(function () {
var $this = $(this);
if ($this.children().length == 0) {
$this.text($this.text().replace('Assets', 'POS'));
$this.text($this.text().replace('Asset', 'POS'));
$this.text($this.text().replace('assets', 'POS'));
$this.text($this.text().replace('asset', 'POS'));
}
});
}
try it like this
for (var i = 0, replacements = ['Assets','assets','asset','Asset']; i < 4; i++)
$("*:contains('" + replacements[i] +"')").map(function() { this.innerHTML = this.innerHTML.replace(/asset(s){0,1}/igm, 'POS'); })
r = r.replace(/<TR><TD><\/TD><\/TR>/gi, rider_html);
...does not work in IE but works in all other browsers.
Any ideas or alternatives?
I've come to the conclusion that the variable r must not have the value in it you expect because the regex replacement should work fine if there is actually a match. You can see in this jsFiddle that the replace works fine if "r" actually has a match in it.
This is the code from fiddle and it shows the proper replacement in IE.
var r = "aa<TR><TD></TD></TR>bb";
var rider_html = " foo ";
r = r.replace(/<TR><TD><\/TD><\/TR>/gi, rider_html);
alert(r);
So, we can't really go further to diagnose without knowing what the value of "r" is and where it came from or knowing something more specific about the version of IE that you're running in (in which case you can just try the fiddle in that version yourself).
If r came from the HTML of the document, then string matching on it is a bad thing because IE does not keep the original HTML around. Instead it reconstitutes it when needed from the parsed page and it puts some things in different order (like attributes), different or no quotes around attributes, different capitalization, different spacing, etc...
You could do something like this:
var rows = document.getElementsByTagName('tr');
for (var i = 0; i < rows.length; i++) {
var children = rows[i].children;
if (children.length === 1 && children[0].nodeName.toLowerCase() === 'td') {
children[0].innerHTML = someHTMLdata
}
}
Note that this sets the value of the table cell, rather than replacing the whole row. If you want to do something other than this, you'll have to use DOM methods rather than innerHTML and specify exactly what you actually want.
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;
}
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.