Remove all content using pure JS - javascript

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 ---

Related

How to load javascript src file into new tab [duplicate]

I'm having problems getting this to work. I first tried setting my script tags as strings and then using jquery replaceWith() to add them to the document after page load:
var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);
But I got string literal errors on that var. I then tried encoding the string like:
var a = '&left;script type="text/javascript">some script here<\/script>';
but sending that to replaceWith() outputs just that string to the browser.
Can someone please let me know how you would go about dynamically adding a <script> tag into the browser after page load, ideally via jQuery?
You can put the script into a separate file, then use $.getScript to load and run it.
Example:
$.getScript("test.js", function(){
alert("Running test.js");
});
Try the following:
<script type="text/javascript">
// Use any event to append the code
$(document).ready(function()
{
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://scriptlocation/das.js";
// Use any selector
$("head").append(s);
});
http://api.jquery.com/append
Here's the correct way to do it with modern (2014) JQuery:
$(function () {
$('<script>')
.attr('type', 'text/javascript')
.text('some script here')
.appendTo('head');
})
or if you really want to replace a div you could do:
$(function () {
$('<script>')
.attr('type', 'text/javascript')
.text('some script here')
.replaceAll('#someelement');
});
A simpler way is:
$('head').append('<script type="text/javascript" src="your.js"></script>');
You can also use this form to load css.
This answer is technically similar or equal to what jcoffland answered.
I just added a query to detect if a script is already present or not.
I need this because I work in an intranet website with a couple of modules, of which some are sharing scripts or bring their own, but these scripts do not need to be loaded everytime again. I am using this snippet since more than a year in production environment, it works like a charme. Commenting to myself: Yes I know, it would be more correct to ask if a function exists... :-)
if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
$('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}
Here is a much clearer way — no need for jQuery — which adds a script as the last child of <body>:
document.body.innerHTML +='<script src="mycdn.js"><\/script>'
But if you want to add and load scripts use Rocket Hazmat's method.
Example:
var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);
It should work. I tried it; same outcome. But when I used this:
var length = 1;
var html = "";
for (var i = 0; i < length; i++) {
html += '<div id="codeSnippet"></div>';
html += '<script type="text/javascript">';
html += 'your script here';
html += '</script>';
}
$('#someElement').replaceWith(a);
This worked for me.
Edit: I forgot the #someelement (btw I might want to use #someElement because of conventions)
The most important thing here is the += so the html is added and not replaced.
Leave a comment if it didn't work. I'd like to help you out!
There is one workaround that sounds more like a hack and I agree it's not the most elegant way of doing it, but works 100%:
Say your AJAX response is something like
<b>some html</b>
<script>alert("and some javscript")
Note that I've skipped the closing tag on purpose. Then in the script that loads the above, do the following:
$.ajax({
url: "path/to/return/the-above-js+html.php",
success: function(newhtml){
newhtml += "<";
newhtml += "/script>";
$("head").append(newhtml);
}
});
Just don't ask me why :-) This is one of those things I've come to as a result of desperate almost random trials and fails.
I have no complete suggestions on how it works, but interestingly enough, it will NOT work if you append the closing tag in one line.
In times like these, I feel like I've successfully divided by zero.
If you are trying to run some dynamically generated JavaScript, you would be slightly better off by using eval. However, JavaScript is such a dynamic language that you really should not have a need for that.
If the script is static, then Rocket's getScript-suggestion is the way to go.

Replace text on webpage using javascript

I am trying to replace some text on my sites page using javascript. I must use javascript because the replacement is dependent on the site resolution. However I found that the code bellow doesn't work. Why is it? Does similar things work on iphone (these javascript functions)? Thanks.
<SCRIPT language="JavaScript">
<!--
if ((screen.width<=500))
{
document.body.innerHTML = document.body.innerHTML.replace('text to replace', 'replacement');
}
//-->
</SCRIPT>
The screen property does not have a resize cause it's like they built it in the factory :)
You're probably interested in window.innerWidth
probably you're also interested in listening for a resize event so here you go:
function doOnResize() {
var winW = window.innerWidth;
if(winW <= 500) {
document.body.innerHTML = document.body.innerHTML.replace('text to replace', 'replacement');
}
}
doOnResize(); // Do it as soon as you can
window.addEventListener("resize", doOnResize); // and on window resize
Also make sure to place the above <script> right before the closing </body> tag. This will make sure that the JS parser is in known about the DOM content before searching and replacing text.
Your code does not work because it is executed before the DOM is ready.
window.onload = function() { /* Your code here */ };
This will make sure the DOM is ready and everything is loaded.
What about using css and js (well, jquery would probably be best) to change the display attribute of the element on the event that triggers the text change?

set innerHTML of an iframe

In javascript, how can I set the innerHTML of an iframe? I mean: how to set, not get.
window["ifrm_name"].document.innerHTML= "<h1>Hi</h1>" does not work, and the same for other solutions.
Iframe and parent document are on the same domain.
I would need to set html of the whole document iframe, not its body.
I would need to avoid jquery solution.
A really simple example ...
<iframe id="fred" width="200" height="200"></iframe>
then the following Javascript is run, either inline, part of an event, etc ...
var s = document.getElementById('fred');
s.contentDocument.write("fred rules");
the "contentDocument" is the equivalent of the "document" you get in the main window, so you can make calls against this to set the body, head, any elements inside ... etc.
I've only tested this in IE8, Chrome and Firefox ... so you may want to test in IE6/7 if you have copies available.
In Firefox and Chrome (don't know about Opera), you can use the data: URI scheme.
<iframe src=".... data: URI data here ......">
JSFiddle example
Here is a tool to generate data:URI encoded data.
This does not work in IE:
For security reasons, data URIs are restricted to downloaded resources. Data URIs cannot be used for navigation, for scripting, or to populate frame or iframe elements.
If however as you say in the comment, getting/setting the document's body is enough, you are much easier off using one of the linked examples.
There is also the srcdoc attribute:
<iframe srcdoc="<p><h1>Hello</h1> world</p>"></iframe>
Demo, Polyfill.
In improving my file uploads in an AJAXS env I had the same need. This worked for me in ie8 and ff 22.0. Both the body innerhtml and div innerhtml work.
function copyframedata(data) {
var x = document.getElementById("photo_mgr_frame");
var y = x.contentWindow || x.contentDocument;
if (y.document) y = y.document;
y.getElementById('photo_mgr_mb').innerHTML = data;
}
got it from w3
I came across the same problem but here's an easy fix.
function Run(){
var txt = "<h1>Hello World</h1>";
var frame = document.getElementById('frame');
var frame = (frame.contentWindow || frame.contentDocument);
if (frame.document) frame = frame.document;
frame.open();
frame.write(txt);
frame.close();
}
<iframe id='frame'>
</iframe>
<button onclick='Run()'>Run</button>

Accessing frames via the DOM in IE

OK, every other browser works fine with the method I have coded so far but for some reason Internet Explorer will not work. I have spent hours of time (more time than actually developing the feature!) on compatibility and am close to giving up!
I have a forum and one of its neat features is the WYSIWYG editor. For that, I essentially have an IFrame that acts as the document:
<iframe name="writer" src="/scripts/blank.html" class="writer"></iframe>
This is the current state of the JavaScript (constantly updated):
function initEditor()
{
w = frames['writer']
wc = g('writerCopy')
if(w == null) return
frames['writer'].document.designMode = 'on'
frames['writer'].document.body.innerHTML = styleSheet+wc.value
frames['writer'].focus()
}
It works partially now, but fails on the line:
frames['writer'].document.body.innerHTML = styleSheet+wc.value
in Internet Explorer with "'frames.writer.document.body' is null or not an object".
I'm not even sure IE supports that designMode.
And, .contentDocument is only IE8, IE7 and less uses .contentWindow.document, but iframe windows are part of the frames-collection.
try this, should be crossbrowser:
<iframe name="writer"></iframe>
frames["writer"].document.body.innerHTML = "some html...";
You need to point your iframe to a dummy document for IE. Just create a file blank.html with the following:
<html><body></body></html>
and set <iframe src="blank.html" ... >
Then you can go about referencing frame.document.body.innerHTML = '...' to your hearts content.
BTW that is a terrible title to a question.
Evidently IE8 does not make frame elements available until the entire parent page has loaded. Also note, you can write to the frame before the parent page loads, but this will overwrite the frame and prevent it from being loaded.
The easy solution is to move the InitEditor() call from inside the body to here:
<body onload="InitEditor()">
Perhaps the iframe isn't loaded yet. I can duplicate your "'frames.writer.document.body' is null or not an object" error. I added a setTimeout around it and it then worked for me.
setTimeout(function () {
frames['writer'].document.body.innerHTML = "some text";
}, 200);
Have you activated IE's debugging facilities?
Am I missing something here? shouldn't you use something like:
window.frames[nameOrNumberOfFrame]...
See also in MSDN:
This collection contains only window
objects and does not provide access to
the corresponding frame and iframe
objects. To access these objects, use
the all collection for the document
containing the objects.
In the end I used frames['frameName'].document.write('someText') but only if the other method fails.

How do I inject javascript to a page on IE 8?

Lets suppose that I have the following markup:
<div id="placeHolder"></div>
and I have a JavaScript variable jsVar that contains some markup and some JavaScript.
By using Mootools 1.1 I can inject the JavaScript content into the placeholder like this:
$('placeHolder').setHTML(jsVar);
This works in Firefox, Opera, and even Safari and the resulting markup looks like this:
<div id="placeHolder">
<strong>I was injected</strong>
<script type="text/javascript">
alert("I was injected too!");
</script>
</div>
However, on IE 8 I get the following:
<div id="placeHolder">
<strong>I was injected</strong>
</div>
Is there any way to inject the JavaScript on IE 8 or does it security model forbid me from doing this at all?
I tried Luca Matteis' suggestion of using
document.getElementById("placeHolder").innerHTML = jsVar;
instead of the MooTools code and I get the same result. This is not a MooTools issue.
This MSDN post specifically addresses how to use innerHTML to insert javascript into a page. You are right: IE does consider this a security issue, so requires you to jump through certain hoops to get the script injected... presumably hackers can read this MSDN post as well as we can, so I'm at a loss as to why MS considers this extra layer of indirection "secure", but I digress.
From the MSDN article:
<HTML>
<SCRIPT>
function insertScript(){
var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>";
var sScript="<SCRIPT DEFER>";
sScript = sScript + "function go2(){ alert('Hello from inserted script.') }";
sScript = sScript + "</SCRIPT" + ">";
ScriptDiv.innerHTML = sHTML + sScript;
}
</SCRIPT>
<BODY onload="insertScript();">
<DIV ID="ScriptDiv"></DIV>
</BODY>
</HTML>
If at all possible, you may wish to consider using a document.write injected script loading tag to increase security and reduce cross-browser incompatibility. I understand this may not be possible, but it's worth considering.
This is how we did it on our site about a year ago to get it working in IE. Here are the steps:
add the HTML to an orphan DOM element
search the orphan node for script tags (orphan.getElementsByTagName)
get the code from those script nodes (save for later), and then remove them from the orphan
add the html leftover that is in the orphan and add it to the placeholder (placeholder.innerHTML = orphan.innerHTML)
create a script element and add the stored code to it (scriptElem.text = 'alert("my code");')
then add the script element to the DOM (preferably the head), then remove it
function set_html( id, html ) {
// create orphan element set HTML to
var orphNode = document.createElement('div');
orphNode.innerHTML = html;
// get the script nodes, add them into an arrary, and remove them from orphan node
var scriptNodes = orphNode.getElementsByTagName('script');
var scripts = [];
while(scriptNodes.length) {
// push into script array
var node = scriptNodes[0];
scripts.push(node.text);
// then remove it
node.parentNode.removeChild(node);
}
// add html to place holder element (note: we are adding the html before we execute the scripts)
document.getElementById(id).innerHTML = orphNode.innerHTML;
// execute stored scripts
var head = document.getElementsByTagName('head')[0];
while(scripts.length) {
// create script node
var scriptNode = document.createElement('script');
scriptNode.type = 'text/javascript';
scriptNode.text = scripts.shift(); // add the code to the script node
head.appendChild(scriptNode); // add it to the page
head.removeChild(scriptNode); // then remove it
}
}
set_html('ph', 'this is my html. alert("alert");');
I have encountered the same issues with IE8 (and IE7)
The only way I could dynamically inject a script (with an src) is by using a timer:
source = "bla.js";
setTimeout(function () {
// run main code
var s = document.createElement('script');
s.setAttribute('src', source);
document.getElementsByTagName('body')[0].appendChild(s);
}, 50);
If you have inline code you would like to inject, you can drop the timer and use the "text" method for the script element:
s.text = "alert('hello world');";
I know my answer has come pretty late; however, better late than never :-)
I am not sure about MooTools, but have you tried innerHTML ?
document.getElementById("placeHolder").innerHTML
= jsVar;
You may need to eval the contents of the script tag. This would require parsing to find scripts in your jsVar, and eval(whatsBetweenTheScriptTags).
Since IE refuses to insert the content by default you will have to execute it yourself, but you can at least trick IE into doing the parsing for you.
Simply use string.replace() to swap all the <script> tags for <textarea class="myScript" style="display:none">, preserving the content. Then stick the result into an innerHTML of a div.
After this is done, you can use
div.getElementsByTagName("textarea")
to get all the textareas, loop through them and look for your marker class ("myScript" in this case), and either eval(textarea.value) or (new Function(textarea.value))() the ones you care about.
I never tried it, it just came to my mind... Can you try the following:
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = '//javascript code here'; // not sure if it works
// OR
script.innerText = '//javascript code here'; // not sure if it works
// OR
script.src = 'my_javascript_file.js';
document.getElementById('placeholder').appendChild(script);
You can use the same technique (DOM) to insert HTML markup.
I am sorry, perhaps I am missing something here--but with this being a mootools 1.11 question, why don't you use assets.js?
// you can also add a json argument with events, etc.
new Asset.javascript("path-to-script.js", {
onload: function() {
callFuncFromScript();
},
id: "myscript"
});
Isn't one of the reasons why we're using a framework not to have to reinvent the wheel all over again...
as far as the 'other' content is concerned, how do you happen to get it? if through the Request class, it can do what you want nicely by using the options:
{
update: $("targetId"),
evalScripts: true,
evalResponse: false
}
When you say it "works" in those other browsers, do you mean you get the alert popup message, or do you just mean the <script> tag makes it into the DOM tree?
If your goal is the former, realize that the behaviour of injecting html with embedded <script> is very browser-dependent. For example in the latest MooTools I can try:
$(element).set('html', '<strong>Foo</strong><script>alert(3)</script>')
and I do not get the popup, not in IE(7), not in FF(3) (however I do get the <script> node into the DOM successfully). To get it to alert in all browsers, you must do as this answer does.
And my comment is really late, but it's also the most accurate one here - the reason you're not seeing the <script> contents running is because you didn't add the defer attribute to the <script> tag. The MSDN article specifically says you need to do that in order for the <script> tag to run.

Categories

Resources