IE javascript problem with break or classname - javascript

i'm not really sure whats the problem here, it works with chrome and ff but not ie.
var newdiv = document.createElement("div");
newdiv.innerHTML = xhr.responseText;
el = newdiv.firstChild.nextSibling;
var next;
do{
next = addpoint.nextSibling;
if(next.className != "commentstyle golduser") break;
}while(addpoint = next);
document.getElementById("testimonialcommentlisting"+id).insertBefore(el,next);
error is at this line document.getElementById("testimonialcommentlisting"+id).insertBefore(el,next);
**UPDATE**
ok this is werid, i did some test and i found the problem. the problem is with var el
for chrome and ff el is div element while ie is null.
here comes the weirder problem. By right, newdiv.firstChild should be the div element but i dont know why ff and chrome register it as a text element and clearly my responseText is something like this
<div>blahblah</div>
i hope somebody understands what i'm talking about.

Your loop follows an odd construction. You're fetching addpoint.nextSibling then looking at its className attribute, and only then checking to see if the node is valid. This means on the last iteration through the loop, when next is null, you're trying to access the className property of null.
while (next) {
if (next.className != 'commentstyle golduser') break;
next = next.nextSibling;
}
Without more context from what surrounds this loop I don't know how addpoint fits in. It's not necessary just to make the loop work, though if you do need to change addpoint there's no reason you can't do so using this loop construction.
The point is that you are never checking next.className when next is null.

Related

Error adding options to a select menu with javascript

I was having two problems: the first is that javascript is not adding options to a menu, and the second was an "Unexpected or invalid token" error at the end of my for loop.
Update:
The token error was a weird character thing. I deleted the line that was causing the problem and retyped it and now I am not getting the error anymore, but my script still is not adding options.
I have read about adding options to a select menu but the answers I've found there haven't worked for me. I should point out that this is part of a Joomla website (v3.8), because that can cause some unexpected behaviour.
I have a function which is supposed to pick out a particular select menu based on the string "id", clear its contents, and re-populate it with the elements of the "options" array.
function resetSelectMenu(id, options){
// Selects the correct menu, enables it, and removes all of its options.
var selectMenu = jQuery('#sel-' + id);
selectMenu.prop('disabled', false);
selectMenu.empty();
// Makes an option element and sets its text and value.
var el = document.createElement("option");
el.text = 'blah';
el.value = 'blah';
// Does not succeed in adding an option to menu.
selectMenu.add(el);
// I declared loop variables here to make sure there are no re-declaration issues.
var i;
var opt;
// The loop is entered and the array is iterated through.
for(i = 0; i < options.length; i++){
opt = options[i];
el = document.createElement("option");
el.text = opt;
el.value = i + 1;
// Does not succeed in adding an option to menu.
selectMenu.add(el);
}​
}
The function does target the correct menu and clear its contents, but it is not adding the "blah" option or anything from the "options" array. I've tried using "appendChild(el)" instead of add but I get an error of the form "appendChild() is not a function". I did a lot of console logs to determine that all the parts of the code are working as expected except for "selectMenu.add(el);"
So this was just a noob mistake. I looked a bit harder and found this related question, and the top answer by Matt told me I needed to use append(el) instead of add(el). I looked into the documentation and the add method just affects the jQuery object but doesn't actually affect the DOM at all, whereas append does. If I were to use add I would need to explicitly tell the jQuery object to refresh the DOM.
It's also possible that there is still an issue with me using selectMenu.empty() instead of something like selectMenu.find('option').remove(), but at the moment it's not causing any errors. Since my select element only contains option elements I feel like these two commands would be the same, but on the other hand maybe the latter is better because it allows for the addition of different kinds of elements later.

Can't assign querySelectorAll() to a variable - weird behaviour

I was trying to crawl a very old website for a specific tag, I need to get it by it's for= attribute. So I used this piece of code.
var character = document.querySelectorAll("label[for=char_1]");
For some reason it returns an undefined, but I was using this script for a few days now and it worked like a charm. Here's the fun part. Typing that command in browsers console will result in undefined. But typing this alone:
document.querySelectorAll("label[for=char_1]");
Will return a proper NodeList. Why it won't assign to a variable...?
edit: It seems that deleting var and typing character without it will make it work. It's resolved but I would still love to get an answer to "why is this happening"?
edit2:
for (var i = 0; i < 15; i++) {
var character = document.querySelectorAll("label[for=char_" + i +"]");
console.log(character); // this will return [] from the script.
var color = character[0].children[0].style.color;
}
A simple for loop. All I get is Cannot read property 'children' of undefined. But I can type in the very same command document.querySelectorAll... and it will work in the browser and will return NodeList.
I had it working like this in a very hacky script. It worked.
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
edit3:
var character1 = document.querySelectorAll("label[for=char_1]");
var characterColor1 = character1[0].children[0].style.color;
var character2 = document.querySelectorAll("label[for=char_2]");
var characterColor2 = character2[0].children[0].style.color;
// ...
The above code works without a single problem though. I don't think it's DOM not being ready as this code is also run from Greasemonkey script and it works. The only difference is the for loop.
var x = ""; // returns undefined, because it's a var assignment.
var elements = document.querySelectorAll('div');
That's expected behavior when pasted into the console.
edit: It seems that deleting var and typing character without it will make it work. It's resolved
I'm afraid you're creating a global scope variable now. or perhaps characters is an already defined variable in that scope.
Buhah, as I said in edit 3 "the only difference is the for loop". I was so busy trying to find an answer in the DOM-related things that I made the simplest mistake ever done in programming.
See?
char_1
With...
for(var i = 0...)
0! And I was testing char_1 in the browser instead of char_0. Which - truly - returns [] instead of something useful. Time to go on a holiday break I guess, my brain seems to be there already. :)

KinteticJS - destroying nodes, infinite while loop because child doesn't get removed

KinerticJS version: 4.4.3
I have this problem when i want to remove a layer from stage. When I call Layer.destroy() kinetic runs upon an node which can't be removed. I don't get any error, but the while loop gets infinite since the loop is based on the length of the children.
destroy: function (_nameSpace) {
var parent = this.getParent(),
stage = this.getStage(),
dd = Kinetic.DD,
go = Kinetic.Global;
var tempLength
// destroy children
while (this.children && this.children.length > 0) {
this.children[0].destroy();
}
}
The object which, in my case, can not be removed is a Kinetic.Image. When I trace the node type it returns a Shape (which is correct). Also, i can trace all the stuff which i want to know from the object...
Rectangles do get removed.
I created a low level test in fiddle, and there everything is working fine and dandy, so it has te be something with my code. Than again, the node whicht is not being removed IS a valid object, so why does is not being removed?
I created a error message, so i wouldn't crash my browser everytime:
tempLength = this.children.length
this.children[0].destroy();
if (tempLength == this.children.length) {
throw 'item not removed ' + this.children[0].getNodeType();
}
As you can see i check right after i destroyed an item if the length of the children did change, so i can assume thah no other code is interfering. For example adding an node when destroying one.
I'm at a dead end here. I hope somebody can help me out or point me in any direction. Anyway, thanks for reading :)
Ok, i figured out what the issue was. Somehow i aadded a same Kinetic.Image twice to a layer. When destroying the layer it could not remove it's child.
I assume this is an Kinetic bug. I should not be able to break the framework so (relatively) easy.
https://github.com/ericdrowell/KineticJS/issues/434

Why would .append randomly fail in jquery?

I'm using jquery to add elements to a blank list.
on the page I have:
<ul id="myList">
</ul>
and I go through a loop like this in the script that's called from a dynamically created event handler. (It's "onDrop" of a list item having been sorted with a drag operation)
var myListItemHTML;
for (var i = 0 ; i < 5 ; i++)
{
myListItemHTML += '<li id=listItem'+i+'>This is item number'+i+'</li>';
}
$('#myList').append(myListItemHTML);
and if I check after...
if ($('#myList li').length == 0 )
{
alert('Going to crash now since I'm expecting list items')
}
roughly 95% of the time the list is populated, but about 5% of the time I hit my alert that's going to cause an exception later.
Has anyone run into this? Is there a callback or way to know when/if the append really happens?
var myListItemHTML;
for (var i = 0 ; i < 5 ; i++)
{
$('#myList').append('<li id=listItem'+i+'>This is item number'+i+'</li>');
}
Try just appending inside the for loop.
if ($('#myList li').length == 0 )
{
alert('Going to crash now since I\'m expecting list items')
}
You need a \ before the ' so it doesn't conflict.
edit: jsfiddle that shows "undefined" http://jsfiddle.net/gyEre/1/
This is a bit of a longshot, because I'm making an assumption about your code beyond what was posted. Here goes:
I had a problem with some code once, which worked perfectly in all Browsers except Chrome, wherein it would fail randomly and seemingly without cause.
My problem, ultimately, was that Chrome was actually executing my JavaScript too fast, and that it was throwing off some of the timing in some of the AJAX calls that were being made earlier.
My code was such that AJAX event A triggered, which then passed data to AJAX event B. In Chrome only, though, I found that event B was on occasion occurring before event A, and that was the error condition.
If I recall, I think the solution was to force one key AJAX request to be made synchronously, though that should be used with care. Please see: http://api.jquery.com/jQuery.ajaxSetup/
I hope that's not too vague to be helpful. Good luck!
What I've learned is that I can't trust jquery for DOM manipulation called through dynamically created events. I welcome someone to prove me wrong, but this approach:
addListItem = function (itemID, itemText)
{
var li = document.createElement('li');
li.setAttribute("id", itemID);
var liText = document.createTextNode(itemText);
li.appendChild(goalTextNode);
document.getElementById('myList').appendChild(li);
}
for (var i = 0 ; i < 5 ; i++)
{
addListItem('listItem'+i, 'Item Text'+i);
}
will work 100% of the time and never fail.
In my experience, if the script in which the prepend function is used in the -tag, it will not work because the script is loaded before the DOM is ready.
To avoid this kind frustration, is a good habit to place your javascript before the tag.

Why does IE give unexpected errors when setting innerHTML

I tried to set innerHTML on an element in firefox and it worked fine, tried it in IE and got unexpected errors with no obvious reason why.
For example if you try and set the innerHTML of a table to " hi from stu " it will fail, because the table must be followed by a sequence.
You're seeing that behaviour because innerHTML is read-only for table elements in IE. From MSDN's innerHTML Property documentation:
The property is read/write for all objects except the following, for which it is read-only: COL, COLGROUP, FRAMESET, HEAD, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR.
Don't know why you're being down-modded for the question Stu, as this is something I solved quite recently. The trick is to 'squirt' the HTML into a DOM element that is not currently attached to the document tree. Here's the code snippet that does it:
// removing the scripts to avoid any 'Permission Denied' errors in IE
var cleaned = html.replace(/<script(.|\s)*?\/script>/g, "");
// IE is stricter on malformed HTML injecting direct into DOM. By injecting into
// an element that's not yet part of DOM it's more lenient and will clean it up.
if (jQuery.browser.msie)
{
var tempElement = document.createElement("DIV");
tempElement.innerHTML = cleaned;
cleaned = tempElement.innerHTML;
tempElement = null;
}
// now 'cleaned' is ready to use...
Note we're using only using jQuery in this snippet here to test for whether the browser is IE, there's no hard dependency on jQuery.
check the scope of the element you are trying to set the innerHTML. since FF and IE handle this in a different way
http://www.ericvasilik.com/2006/07/code-karma.html
I have been battling with the problem of replacing a list of links in a table with a different list of links. As above, the problem comes with IE and its readonly property of table elements.
Append for me wasn't an option so I have (finally) worked out this (which works for Ch, FF and IE 8.0 (yet to try others - but I am hopeful)).
replaceInReadOnly(document.getElementById("links"), "<a href>........etc</a>");
function replaceInReadOnly(element, content){
var newNode = document.createElement();
newNode.innerHTML = content;
var oldNode = element.firstChild;
var output = element.replaceChild(newNode, oldNode);
}
Works for me - I hope it works for you
"Apparently firefox isn't this picky" ==> Apparently FireFox is so buggy, that it doesn't register this obvious violation of basic html-nesting rules ...
As someone pointed out in another forum, FireFox will accept, that you append an entire html-document as a child of a form-field or even an image ,-(
Have you tried setting innerText and/or textContent? Some nodes (like SCRIPT tags) won't behave as expected when you try to change their innerHTML in IE. More here about innerText versus textContent:
http://blog.coderlab.us/2006/04/18/the-textcontent-and-innertext-properties/
Are you setting a completely different innerHTML or replacing a pattern in the innerHTML? I ask because if you're trying to do a trivial search/replace via the 'power' of innerHTML, you will find some types of element not playing in IE.
This can be cautiously remedied by surrounding your attempt in a try/catch and bubbling up the DOM via parentNode until you successfully manage to do it.
But this is not going to be suitable if you're inserting brand-new content.
You can modify the behavior. Here is some code that prevents garbage collection of otherwise-referenced elements in IE:
if (/(msie|trident)/i.test(navigator.userAgent)) {
var innerhtml_get = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").get
var innerhtml_set = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").set
Object.defineProperty(HTMLElement.prototype, "innerHTML", {
get: function () {return innerhtml_get.call (this)},
set: function(new_html) {
var childNodes = this.childNodes
for (var curlen = childNodes.length, i = curlen; i > 0; i--) {
this.removeChild (childNodes[0])
}
innerhtml_set.call (this, new_html)
}
})
}
var mydiv = document.createElement ('div')
mydiv.innerHTML = "test"
document.body.appendChild (mydiv)
document.body.innerHTML = ""
console.log (mydiv.innerHTML)
http://jsfiddle.net/DLLbc/9/
I just figured out that if you try to set innerHTML on an element in IE that isn't logically correct it will throw this error.
For example if you try and set the innerHTML of a table to " hi from stu " it will fail, because the table must be followed by a sequence.
Apparently firefox isn't this picky.
Hope it helps.

Categories