The below piece of code is not working in IE8, but, it is working perfectly on FireFox and Google Chorome, Even, there is no error thrown by IE8, but, output is not coming. Any Idea? What is the actual problem?
<html>
<head/>
<body>
<script type="text/javascript">
(function(){
var inpEle = document.createElement("div");
inpEle.setAttribute("id", "div1");
var texEle = document.createTextNode("This is my Sample Para. I am testing it again my own level that prove How i am capable of.");
inpEle.appendChild(texEle);
document.body.appendChild(inpEle);
})();
(function(){
var inpEle1 = document.createElement("input");
inpEle1.setAttribute("type", "button");inpEle1.setAttribute("value", "Show");inpEle1.setAttribute("onclick", "Show()");
document.body.appendChild(inpEle1);
var inpEle2 = document.createElement("input");
inpEle2.setAttribute("type", "button");inpEle2.setAttribute("value", "Hide");inpEle2.setAttribute("onclick", "Hide()");
document.body.appendChild(inpEle2);
})();
</script>
<script type="text/javascript">
window.onload= function(){
document.getElementById('div1').style.display="none";
}
Show = function (){
document.getElementById('div1').style.border="2pt solid green";
document.getElementById('div1').style.display="";
}
Hide = function(){
document.getElementById('div1').style.border="";
document.getElementById('div1').style.display="none";
}
</script>
</body>
</html>
You may not be able to use document.body.appendChild() in IE8 before the </body> tag has been parsed and your code is trying to append to the body while it is still being parsed. Early versions of IE like IE6 might just abort (e.g. literally crash) when you did this. Later versions (like IE8) will just simply ignore your request.
You can use document.write() to add content while the body is being parsed.
You can postpone calling your code until after the body has finished loading and parsing (such a <body onload="xxx()"> handler) or when an event such as window.onload fires.
You can appendChild() to an element that has finished parsing (something that is before your script).
The simplest solution is probably to put a <div id="container"></div> in the body before your script and append to that instead of the body or put your code in a function and have the body onload event call your function.
See this article for description of the issue.
don't use setattribute use anonymous function for events
inpEle1.onclick = function() {
Show();
};
Also it works in IE tester in IE8, but not IE7, do you have it using IE7 compatibility
Go to Internet Options - Security Tab - Internet - click on the "Custom" button then scroll down to the Miscellaneous section."Allow script-initiated windows without size or position constraints" Find "Active Scripting" then check enable.
I noticed than element.style.display doesn't always work with IE8.
Here is a method to improve compatibility :
if (element.style.setAttribute)
element.style.setAttribute("display", value);
else
element.style.display = value;
Best regards,
Related
I am trying to set the onclick event using javascript. The following code works:
var link = document.createElement('a');
link.setAttribute('href', "#");
link.setAttribute('onclick', "alert('click')");
I then use appendChild to add link to the rest of the document.
But I obviously would like a more complicated callback than alert, so I tried this:
link.onclick = function() {alert('clicked');};
and this:
link.onclick = (function() {alert('clicked');});
But that does nothing. When I click the link, nothing happens. I have testing using chrome and browsing the DOM object shows me for that element that the onclick attribute is NULL.
Why am I not able to pass a function into onclick?
EDIT:
I tried using addEventListener as suggested below with the same results. The DOM for the link shows onclick as null.
My problem may be that the DOM for this element might not have been fully built yet. At this point the page has been loaded and the user clicks a button. The button executes javascript that builds up a new div that it appends to the page by calling document.body.appendChild. This link is a member of the new div. If this is my problem, how do I work around it?
I have been unable to reproduce the problem. Contrary to the OP's findings, the line below works fine on the latest versions of IE, FF, Opera, Chrome and Safari.
link.onclick = function() {alert('clicked');};
You can visit this jsFiddle to test on your own browser:
http://jsfiddle.net/6MjgB/7/
Assuning we have this in the html page:
<div id="x"></div>
The following code works fine on the browsers I have tried it with:
var link = document.createElement('a');
link.appendChild(document.createTextNode("Hi"));
link.setAttribute('href', "#");
link.onclick= function() {link.appendChild(document.createTextNode("Clicked"));}
document.getElementById("x").appendChild(link);
If there is a browser compatibility issue, using jQuery should solve it and make code much much more concise:
var $link = $("<a>").html("Hi").attr("href","#").click(function (){$link.html("Clicked")})
$("#x").html($link)
If brevity is not a strong enough argument for using jQuery, browser compatibility should be ... and vise versa :-)
NOTE: I am not using alert() in the code because jsFiddle does not seem to like it :-(
If you're doing this with JavaScript, then use addEventListener(), with addEventListener('click', function(e) {...}) to get the event stored as e. If you don't pass in the event like this, it will not be accessible (although Chrome appears to be smart enough to figure this out, not all browsers are Chrome).
Full Working JSBin Demo.
StackOverflow Demo...
document.getElementById('my-link').addEventListener('click', function(e) {
console.log('Click happened for: ' + e.target.id);
});
Link
You can add a DOM even listener with addEventListener(...), as David said. I've included attachEvent for compatibility with IE.
var link = document.createElement('a');
link.setAttribute('href', "#");
if(link.addEventListener){
link.addEventListener('click', function(){
alert('clicked');
});
}else if(link.attachEvent){
link.attachEvent('onclick', function(){
alert('clicked');
});
}
Setting an attribute doesn't look right. The simplest way is just this:
link.onclick = function() {
alert('click');
};
But using addEventListener as JCOC611 suggested is more flexible, as it allows you to bind multiple event handlers to the same element. Keep in mind you might need a fallback to attachEvent for compatibility with older Internet Explorer versions.
Use sth like this if you like:
<button id="myBtn">Try it</button>
<p id="demo"></p>
<script>
document.getElementById("myBtn").onclick=function(){displayDate()};
function displayDate()
{
document.getElementById("demo").innerHTML=Date();
}
</script>
I am trying to move a DOM node from the "root" page to a new pop-up that is created via window.open(). Here is the code I am using.
var win = window.open('/Search/Print', 'printSearchResults'),
table = $('#printTable');
win.document.close();
setTimeout(function () {
var el = win.document.createElement("table");
el.innerHTML = table.html();
win.document.body.appendChild(el);
}, 40);
It works in Chrome, but in IE8, I receive the following error: "Unknown runtime error."
I've also tried it this way:
var p = window.open('/Search/Print', 'printSearchResults'),
table = $('#printTable');
setTimeout(function () {
p.document.body.appendChild(table.clone(false)[0]);
}, 100);
Doing it this way, I receive "No such interface supported" in IE8. Again, Chrome works fine.
Does anyone have a way to do what I'm trying to achieve?
Here is the HTML for the pop-up window just for the sake of completeness:
<!DOCTYPE html>
<html>
<head>
<title>Print Results</title>
</head>
<body>
</body>
</html>
I tested your code on IE9 ( and IE8/7 browser mode).
Instead of el.innerHTML = table.html();
using jquery $(el).html(table.html()); fixed the issue.
To be able to use iframes and new windows, you should initialise them with addres: about:blank, before you write() to them. Also note that loading/opening the window/frame takes time, so you cannot write to them at right away. set a timeout, or check onload.
Please see this answer for more info.
Good luck!
<html>
<head></head>
<body>
<div class="abcd"></div>
<style>
.new_info {
color:red;
}
</style>
<script>
function getBox(){
var sende = document.querySelectorAll(".abcd");
alert(sende[0].hasChildNodes());
alert(y[0].hasChildNodes());
if(sende[0].hasChildNodes() == false && sende[0].nodeValue == null){
var newdiv = document.createElement('div');
newdiv.innerHTML = "which i want";
newdiv.className = "new_info";
sende[0].appendChild(newdiv);
}
}
getBox();
</script>
</body>
</html>
In above code i want to fill div tag having class 'abcd' with some div as childnode having some text like 'which i want'. this work well in other browser but not in IE8.
what should i do to work this code in IE8 too ?
The querySelectorAll does not work in IE8 eg only works only in IE8 standards mode and there are bug reports of it when it comes to IE8.
For solution check out:
Cross Browser getElementsByClassName
Sadly or luckily because of these cross browser issues, there exist JavaScript libraries to benefit from which clear all that mess for us internally.
What this code is doing alert(y[0].hasChildNodes()); in your code, because of this it is not executing.
See Demo: http://jsfiddle.net/rathoreahsan/NmFNH
i have commented alert(y[0].hasChildNodes()); and it is working.
This is my code
<script>
var body = "dddddd"
var script = "<script>window.print();</scr'+'ipt>";
var newWin = $("#printf")[0].contentWindow.document;
newWin.open();
newWin.close();
$("body",newWin).append(body+script);
</script>
<iframe id="printf"></iframe>
This works but it prints the parent page, how do I get it to print just the iframe?
I would not expect that to work
try instead
window.frames["printf"].focus();
window.frames["printf"].print();
and use
<iframe id="printf" name="printf"></iframe>
Alternatively try good old
var newWin = window.frames["printf"];
newWin.document.write('<body onload="window.print()">dddd</body>');
newWin.document.close();
if jQuery cannot hack it
Live Demo
document.getElementById("printf").contentWindow.print();
Same origin policy applies.
Easy way (tested on ie7+, firefox, Chrome,safari ) would be this
//id is the id of the iframe
function printFrame(id) {
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
return false;
}
an alternate option, which may or may not be suitable, but cleaner if it is:
If you always want to just print the iframe from the page, you can have a separate "#media print{}" stylesheet that hides everything besides the iframe. Then you can just print the page normally.
You can use this command:
document.getElementById('iframeid').contentWindow.print();
This command basically is the same as window.print(), but as the window we would like to print is in the iframe, we first need to obtain an instance of that window as a javascript object.
So, in reference to that iframe, we first obtain the iframe by using it's id, and then it's contentWindow returns a window(DOM) object. So, we are able to directly use the window.print() function on this object.
I had issues with all of the above solutions in IE8, have found a decent workaround that is tested in IE 8+9, Chrome, Safari and Firefox. For my situation i needed to print a report that was generated dynamically:
// create content of iframe
var content = '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">'+
'<head><link href="/css/print.css" media="all" rel="stylesheet" type="text/css"></head>'+
'<body>(rest of body content)'+
'<script type="text/javascript">function printPage() { window.focus(); window.print();return; }</script>'+
'</body></html>';
Note the printPage() javascript method before the body close tag.
Next create the iframe and append it to the parent body so its contentWindow is available:
var newIframe = document.createElement('iframe');
newIframe.width = '0';
newIframe.height = '0';
newIframe.src = 'about:blank';
document.body.appendChild(newIframe);
Next set the content:
newIframe.contentWindow.contents = content;
newIframe.src = 'javascript:window["contents"]';
Here we are setting the dynamic content variable to the iframe's window object then invoking it via the javascript: scheme.
Finally to print; focus the iframe and call the javascript printPage() function within the iframe content:
newIframe.focus();
setTimeout(function() {
newIframe.contentWindow.printPage();
}, 200);
return;
The setTimeout is not necessarily needed, however if you're loading large amounts of content i found Chrome occasionally failed to print without it so this step is recommended. The alternative is to wrap 'newIframe.contentWindow.printPage();' in a try catch and place the setTimeout wrapped version in the catch block.
Hope this helps someone as i spent a lot of time finding a solution that worked well across multiple browsers. Thanks to SpareCycles.
EDIT:
Instead of using setTimeout to call the printPage function use the following:
newIframe.onload = function() {
newIframe.contentWindow.printPage();
}
At this time, there is no need for the script tag inside the iframe. This works for me (tested in Chrome, Firefox, IE11 and node-webkit 0.12):
<script>
window.onload = function() {
var body = 'dddddd';
var newWin = document.getElementById('printf').contentWindow;
newWin.document.write(body);
newWin.document.close(); //important!
newWin.focus(); //IE fix
newWin.print();
}
</script>
<iframe id="printf"></iframe>
Thanks to all answers, save my day.
If you are setting the contents of IFrame using javascript document.write() then you must close the document by newWin.document.close(); otherwise the following code will not work and print will print the contents of whole page instead of only the IFrame contents.
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
I was stuck trying to implement this in typescript, all of the above would not work. I had to first cast the element in order for typescript to have access to the contentWindow.
let iframe = document.getElementById('frameId') as HTMLIFrameElement;
iframe.contentWindow.print();
Use this code for IE9 and above:
window.frames["printf"].focus();
window.frames["printf"].print();
For IE8:
window.frames[0].focus();
window.frames[0].print();
I am wondering what's your purpose of doing the iframe print.
I met a similar problem a moment ago: use chrome's print preview to generate a PDF file of a iframe.
Finally I solved my problem with a trick:
$('#print').click(function() {
$('#noniframe').hide(); // hide other elements
window.print(); // now, only the iframe left
$('#noniframe').show(); // show other elements again.
});
I'm looking for a way to remove the entire content of a web page using pure Javascript -- no libraries.
I tried:
document.documentElement.innerHTML = "whatever";
but that doesn't work: it replaces the inside of the <html/> element. I'm looking at replacing the entire document, including if possible the doctype and <?xml declaration.
I think a browser rightfully assumes a page with content-type text/html will always be a web page - so whilst you may do something like...
document.body.innerHTML = '';
It will still have some HTML hanging around.
You could try...
document.documentElement.innerHTML = '';
...which left me with <html></html>.
Yi Jiang did suggest something clever.
window.location = 'about:blank';
This will take you to a blank page - an internal mechanism provided by most browsers I believe.
I think however the best solution is to use document.open() which will clear the screen.
var i = document.childNodes.length - 1;
while (i >= 0) {
console.log(document.childNodes[i]);
document.removeChild(document.childNodes[i--]);
}
Removes everything (doctype also) on FF 3.6, Chrome 3.195, and Safari 4.0. IE8 breaks since the child wants to remove its parent.
Revisiting a while later, could also be done like this:
while (document.firstChild) {
document.removeChild(document.firstChild);
}
According to Dotoro's article on the document.clear method, they (since it's deprecated) recommend calling document.open instead, which clears the page, since it starts a new stream.
This way, you avoid the nasty about:blank hack.
One can remove both the <html> element (document.documentElement) and the doctype (document.doctype).
document.doctype.remove();
document.documentElement.remove();
Alternatively, a loop can be used to remove all children of the document.
while(document.firstChild) document.firstChild.remove();
document.open() or document.write() work as well.
After the page has already fully loaded:
document.write('');
document.close();
I believe this will do it
document.clear() //deprecated
window.location = "about:blank" //this clears out everything
I believe this will still leave the doctype node hanging around, but:
document.documentElement.remove()
or the equivalent
document.getElementsByTagName("html")[0].remove()
document.documentElement.innerHTML='';
document.open();
The Document.open() method opens a document for writing.
if you dont use open method, you cant modify Document after set innerhtml to empty string
Live demo
If youre using jQuery here's your solution
<div id="mydiv">some text</div>
<br><br>
<button id="bn" style="cursor:pointer">Empty div</button>
<script type="text/javascript">
$(document).on('click', '#bn', function() {
$("#mydiv").empty();
$("#bn").empty().append("Done!");
});
</script>
If youre using javascript here's your solution
<div id="purejar">some text</div>
<br><br>
<button id="bnjar" onclick="run()" style="cursor:pointer">Empty div</button>
<script type="text/javascript">
var run = function() {
var purejar = document.getElementById("purejar");
var bn = document.getElementById("bnjar");
purejar.innerHTML = '';
bn.innerHTML = 'Done!';
}
</script>
Im just curious as to why you'd want to do that. Now theres no way that I know of to replace absolutely everything down to the doctype declaration but if you are wanting to go to those lengths why not redirect the user to a specially crafted page that has the template you need with the doctype you need and then fill out the content there?
EDIT: in response to comment, what you could do is strip all content then create an iframe make it fill the entire page, and then you have total control of the content. Be aware that this is a big hack and will probably be very painful - but it would work :)
REMOVE EVERYTHING BUT --- !DOCTYPE html ---
var l = document.childNodes.length;
while (l > 1) { var i = document.childNodes[1]; document.removeChild(i); l--; }
TESTED ON FIREFOX WEB INSPECTOR - childNodes[1] IS --- !DOCTYPE html ---