IE9 Bug? <script> content executed twice when using Node.cloneNode(true) - javascript

I know IE9 is kind of old now, but it is the lowest version of IE that I still must support in a Web application I'm building.
Anyway, while doing some DOM manipulation and testing in different browsers, I noticed that IE9 was doing something very strange. I had a <script> block in a DIV element, and when I deep-cloned that DIV element using Node.cloneNode(true), and attached the clone to the document somewhere using document.body.appendChild or document.body.insertBefore, the cloned <script> block would get executed again! No other browser exhibits this behavior.
If I'm not mistaken, <script> blocks aren't supposed to be executed when appended to the document after the document has initially loaded, am I right? If I'm correct, is this a bug in IE9?
Here is a simple HTML document where you can see this behavior in action. Create an HTML document with this code and load it up in Internet Explorer using IE9 emulation. You should see an alert popup that says "hey". Next, click the "Click Me" button, and you will see the same popup get executed again!
<!DOCTYPE html>
<html>
<head>
<title>IE9 Script Tag Bug Test</title>
<script>
function ButtonClick(){
var Elem = document.getElementById('mydiv');
var ElemClone = Elem.cloneNode(true);
document.body.insertBefore(ElemClone,Elem);
}
</script>
</head>
<body>
<div id="mydiv">
This is a DIV.
<script>
alert("hey");
</script>
</div>
<button onclick="ButtonClick();">Click Me</button>
</body>
</html>

Related

Microsoft Edge Extension, how to manipulate popup.html DOM

I'm new on Browser Extension dev.
I'm trying to do some easy stuff, but I don't really know why doens't work.
What is the problem? I can't manipulate DOM of my popup.html file.
Here an example:
<html>
<head>
<script src="js/jquery.js"></script>
<script src="js/main.js"></script>
</head>
<body id="content">
<p> Hello world </p>
<button id="go" />
</body>
</html>
And here my very simple main.js file:
$(document).ready(function() {
$('#go').click( function(){
$( "#content" ).empty();
alert("Done");
});
});
After click, the content of my Body seems doesn't disappear, but if I put an alert, I can see that my code work (when the alert show). But after click() event (when I close the alert), the popup file it's restored and paragraph is still here.
So, what I'm doing wrong? Can I manipulate the DOM of my popup file? Or my JS code need fix?
I've made some tests, and I notice that any event, any data and any action die after click() event.
I've also try
location.href = "other_page.html";
the redirect work, but as I said after click I return in popup.html file.
Thanks, I'm here for more specification
I had the same problem....
I think Edge doesn't like jquery click() function.
Try with this:
document.getElementById("logout").addEventListener("click", function() {
$( "#content" ).empty();
alert("Done");
}
I've solved in this way :)

Empty document and stop further javascript

I'm writing a small script that determines if the user is on IE8 or below. If they are, the script should completely empty the document (body and head) and stop any further script executing.
I've played around with document.write() but can only get this working with window.onload. But I want it to execute as soon as it knows the browser version (which is when the script executes).
Example page setup:
<html>
<header>
Some CSS
Some meta
...
</head>
<body>
Page content
<script>
if (IE < 8) { //in reality I have a function to determine this
document.write('You browser is outdate. Please upgrade to view this site.');
}
</script>
<script src="more-scripts"></script>
</body>
</html>
This doesn't work but if I wrap the script in a window.onload it does. But then the page flashes up before the code executes. How can I get this to work?
Rather than using document.write() to print a message, you can use the .innerHTML property of the document.body element to entirely replace the body of the page. For this technique, your browser-check script should go in the head section, not the body (this is usually where scripts like this would go anyway).
<html>
<header>
Some CSS
Some meta
...
<script>
if (IE < 8) { //in reality I have a function to determine this
document.body.innerHTML = "You browser is outdate. Please upgrade to view this site.";
}
</script>
</head>
<body>
Page content
<script src="more-scripts"></script>
</body>
</html>
you could use conditional comments for that:
<!--[if IE 8]>
<script>
document.body.innerHTML = '';
document.write('You browser is outdate. Please upgrade to view this site.');
</script>
<![endif]-->

Javascript onclick function works in everything except FF and IE

I have written a simple quiz in javascript and it works fine in my browser of choice, but when I tested it in IE and FF the buttons don't work. I get a "ReferenceError: Option1button() is not defined"
even in this little bit of code I get the same error:
<!DOCTYPE HTML >
<html><head><title></title></head>
<body onload="loadPlayer();">
<script type="text/javascript">
function Option1button(){
document.getElementById("op1").style.display = 'none';
}
function loadPlayer() {
document.write("<div id=\"op1\"><button onclick='Option1button()'>choose</button> OPTIONS <br></div>");
}
</script>
</body>
</html>
You CANNOT use document.write anywhere except code that runs immediately.
If you are trying to defer it so that the button doesn't appear until the function is defined, just do this:
<body>
<script>function Option1Button() {...}</script>
<div id="op1">...</div>
Since scripts block the page from loading, the button won't appear until the function is ready to be called.

innerDocument.getElementById(<elment ID>).click(); doesn't work in Firefox/chrome, in IE it works

I am working with Iframes for controlling the elements of iframe by automating it from the parent html file.
I was trying to to click the link defined in iframe.html file from the test.html file using function click() on javascript while loading test.html :
Test.html file :
function handleMainOnload(){
alert("main frame loaded");
var innerFrame = document.getElementById("frame1");
alert("hi-1" + innerFrame.ownerDocument.title);
var innerDocument = frame1.document;
alert("hi" + innerDocument.title);
innerDocument.getElementById("input1").value = "Dynamically Inserted Text";
innerDocument.getElementById("a1").click();
}
<body onload="handleMainOnload();">
<iframe id="frame1" src="iframe.html"/>
iframe.html file :
<a id="a1" href="http://www.google.co.in"> Google.. click</a>
This achor id = a1 automatically get clicked onload of test.html in IE but doesn't work on any browser apart from IE. Please help.
From Javascriptkit.com:
click() - Executes a click on a element as if the user manually clicked on it. In most browsers, click() only works on form INPUT elements that's non "submit" or "reset". It can't be used to simulate a click on a link or form submit button.
I have verified that this is the reason why it's not working for you. Also, I had to change the following line:
var innerDocument = frame1.document;
to
var innerDocument = window.frames["frame1"].document;
Will update with a way to do this in jQuery.
EDIT:
Here's how you do it in jQuery. Essentially you bind a click event and then call click() on the element. This simulates the action since there is no standard way of executing clicks on hyperlinks.
$(document).ready(function() {
$("#frame1").ready(function () { //The function below executes once the iframe has finished loading
alert("iframe loaded");
$('#frame1').contents().find('#a1').click(function() {
alert("Hello");
$('#frame1').attr('src', $('#frame1').contents().find('#a1').attr("href"));
$('#frame1').load();
});
$('#frame1').contents().find('#a1').click();
});
});
Create the event, initialize it and dispatch it on the node.
See https://developer.mozilla.org/en/DOM/element.dispatchEvent for example.
Just remember to call createEvent on the document that has the node you're going to dispatch on.
You can do this without jQuery and without click event handlers on the anchor tags. (Confirmed with IE 9, FF 15, Chrome 23)
The reason it wasn't working (and for JackWilson's edit) is that [in IE at least] innerFrame.document == innerFrame.ownerDocument, so you were not actually looking for the anchor in the iFrame's content document. Use innerFrame.contentDocument instead.
(I haven't confirmed JackWilson's solution for using window.frames[] in browsers other than IE but some browsers may require referencing window.frames[] by index instead of its id. Anybody know for sure?)
Main page: "aclicktest.html":
<!DOCTYPE html>
<html>
<head><title>A click test</title></head>
<body onload="clickIframe();">
<a id="alocal" href="http://stackoverflow.com" target=_blank>Local link</a>
<iframe id='frame1' src="iframeaclicktest.html"></iframe>
<input type='button' value='click local' onclick='clickLocal();'/>
<input type='button' value='click iframe' onclick='clickIframe();'/>
<script type="text/javascript">
function clickLocal(){document.getElementById("alocal").click();}
function clickIframe(){document.getElementById("frame1").contentDocument.getElementById("aiframe").click();}
</script>
</body>
</html>
Iframe page: "iframeaclicktest.html":
<!DOCTYPE html>
<html>
<head><title>A click test IFRAME</title></head>
<body>
<a id="aiframe" href="http://stackoverflow.com" target=_blank>IFRAME link</a>
</body>
</html>
That's interesting that your old code was working in IE. What version? And did you define doctype? It may have been quirks mode behavior.

Basic jQuery .load Problem

I am trying to use jQuery's .load function to dynamically load content into my webpage. This seem so simple, but I cannot make it work. To try and figure it out, I made a test page with just basic structure, but the external content still won't load:
jquery.html
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$('#foo').load('test.html');
</script>
<div id="foo"></div>
</body>
</html>
test.html
<p>Text text</p>
I'm sure I have made a tiny error, but I can't find it anywhere!
You need to encapsulate your script in the $(document).ready() otherwise #foo won't exist when the script is executed:
<script>
$(document).ready(function(){
$('#foo').load('test.html');
});
</script>
You need to wait for the document to be ready before you can access the DOM. Just add a $(document).ready() around your original code:
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$(document).ready( function() {
$('#foo').load('test.html');
});
</script>
<div id="foo"></div>
</body>
</html>
or if you want a shorter code:
$(function() {
$('#foo').load('test.html');
});
Informally, what's happening is that, as your browser reads the code you wrote, it's drawing its contents as it goes along. When it reaches your <script> tag, it executes it. But when $("#foo") gets executed, the browser's still processing the <script> and hasn't reached the part of the code where you told it there's a div called foo, so the browser doesn't know it exists, and jquery will just find nothing.
Of course, the idea that the browser will just sequentially read your code and render it as it goes is naive at best, so while it might seem that just moving the <script> tag to the bottom of the code would work, you're not actually guaranteed it will work. Instead, the browser will notify you when it's done drawing the page by firing a load (and possibly a DOMContentLoaded) event. So all code that depends on the whole html being drawn should be executed in an event handler bound to those events.
jQuery makes waiting for the page to be loaded easy, just use something like this:
$.ready(function() {
doStuff();
});

Categories