Can't execute inline script with Element.insertAdjacentHTML() - javascript

Can I use insertAdjacentHTML to execute inline javascript?
What works in the browser console:
$('body').append('<script>alert(1)</script>')
What I need to work in browser console:
document.body.insertAdjacentHTML('beforeend', '<script>alert(1)</script>');
The VanillaJS solution does not work. I would be glad about a reason

Using insertAdjacentHTML, although the script tag is added to the page, it won't be parsed or executed.
For the script to actually run you need to use createElement:
var script = document.createElement('script');
script.innerText = "console.log('Hello!');";
document.body.append(script);

var script = document.createElement('script'); // create a new script element
script.innerText = "alert('Hello!');"; // InnerText property html-encodes the content,
document.body.append(script); //append innterText to script

Related

Use javascript to append an inline jquery script

I am trying to use a simple vanilla js script within the page to append some jQuery to the end of the body, where it will come after the jQuery lib load and thus work. I can append js to it fine as shown here..
window.onload = function(){
var script = document.createElement('script');
script.text = "alert('ok');";
document.body.appendChild(script);
};
Attemping to append jQuery:
window.onload = function(){
var script = document.createElement('script');
script.text = "$(window).load(function() {";
script.text += "alert('ok');";
script.text += "});";
document.body.appendChild(script);
};
Works fine appending vanilla, breaks with any jQuery. Why?
*the += instead of one line was one suggested fix to this, but with no luck
**Feels like this should be a duplicate and I'm finding similar issues but not specifically inserting (and triggering, which I realise may be a problem) jQuery.

Script Execution - innerHTML, jQuery html()

document.body.innerHTML = "<script>alert(11);</script>"
$("body").html("<script>alert(11);</script>")
innerHTML is not executed.
jQuery html() is executed.
Why so?
Without getting into the theoretical questions of why jQuery chose to do this, the jQuery html() behaves differently than the native innerHTML. By default, jQuery will find the script tags within the HTML, and load then asynchronously. If this behavior is undesirable, you can use $.parseHTML to prevent this from happening by setting the third argument to false.
$("body").empty().append($.parseHTML("<script>alert(11);</script>", document, false));
Note that the script tags will not be added to the DOM using this method.
Conversely, if you wish to achieve the same affect as your jQuery statement in vanilla JS, you can do the following.
var script = document.createElement('script');
script.text = 'alert(11);';
document.body.innerHTML = '';
document.body.appendChild(script);
Try this...
var x = document.createElement('script');
var y = document.getElementsByTagName('script')[0];
x.text = "alert(11);"
y.parentNode.insertBefore(x, y);
Using innerHTML will stop the script from executing according to the documentation in simple words without going into details.
<script type="text/javascript">
var script = document.createElement('script');
script.appendChild(document.createTextNode("alert('11')"));
document.body.appendChild(script);
</script>

How to dynamically insert jquery code

I am trying use jQuery's rich animation features on dynamically loaded content.
I can dynamically insert script into an element like so:
var element = document.createElement("div");
element.innerHTML = "some html here";
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'alert("Alert!");';
element.appendChild (script);
The problem occurs when I try to insert jquery code into the script element. This does not work and causes the script to not run at all.
var element = document.createElement("div");
element.innerHTML = "some html here";
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'alert("Alert!");\n';
script.text = script.text+'$("div").animate({height:300,opacity:0.4},"slow");\n';
element.appendChild (script);
I can successfully append javascript code to change the elements I want, but using jquery functions will simplify things.
With firebug I can see the script elements has been loaded into the dom, however when I add the jquery code to it, nothing happens, not even the alert.
I have included the jquery source file in my main document and wrapped all of my code into a window.addEventListener('load', function()) to call the functions that initiates the code above when the page finishes loading.
Is there a way to dynamically create calls to jquery functions? Am I going about this the right way? I've been stumped for a while and google hasnt solved this one for me, any help is appreciated.
This should do what you want:
$('body').append('<s' + 'cript>console.log("lol");</script>');
But why are you not wrapping your code into a function which you can then call whenever you please?
function iAnimateThings() {
$("div").animate({height:300,opacity:0.4},"slow");
}
hey nothing wrong with your code you just missed one single inverted comma on this line
script.text = script.text+'$("div").animate({height:300,opacity:0.4},"slow")';
here is your working fiddle
http://jsfiddle.net/vYut9/

Cross browser alternatives to eval

My html page dynamically loads pages via Ajax for dynamic panels on the page. I need the script tags in the dynamically loaded pages to be executed. I fixed the code from a SO question. It works fine on FF/Safari/Chrome.
But dom nodes of type script work differently on IE. -- I can't seem to add text to a script node in IE 7:
// variable "data" holds the script element's content from an
// incoming html page loaded via ajax
var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(data)); // doesn't work on ie
// also doesn't work on IE 7:
script.innerHTML = data;
script.innerText = data;
Any ideas for getting the sw to work on IE? (Other than using eval.)
You should simple call eval(data).
Although it is true that eval should usually be avoided, this is one of the few exceptions.
EDIT: Without eval, you can do it like this:
var scriptNode = document.createElement('script');
scriptNode.type = 'text/javascript';
scriptNode.text = data;
document.head.appendChild(scriptNode);
document.head.removeChild(scriptNode); //Optional
You have a few options I can think of (other than using eval).
The script could be served from a separate path; setting the src of the script element instead of its content should work, even in IE.
The script to be executed could be attached to the onload listener of an image or other element, which can be appended to the document as you are doing with the script element.
use Function instead of eval. This will at least keep the evaluated code out of the local scope: new Function(data)();

How to insert javascript using innerHTML (ie6 is giving me a unknown runtime error)

var head =document.getElementsByTagName("head")[0];
newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = '$(window).load(function(){ someFooo(); }); ';
head.appendChild(newScript);
This is causing an Unknown Runtime Error in IE6. Any other way around this?
Try the text property instead:
newScript.text = '$(window).load(function(){ someFooo(); });';
This works in non-IE browsers as well. I've used this in FF2, FF3, FF3.5, Safari 4 (win), Opera 9+, Chrome 2, Chrome 3, and they all work.
According to the spec (I have to say this otherwise I feel misleading), you're supposed to use appendChild:
var script = '$(window).load(function(){ someFooo(); });';
newScript.appendChild(document.createTextNode(script));
But that fails in IE (<script> elements are not allowed to have children or some other inane IE thing). So just go with the former.
Looks like this is an issue with innerHTML being used in a readonly element. This happens too when you try to set innerHTML in tbody. According to msdn documentation:
(...) Doing this can also be a little
tricky because you cannot use
innerHTML to inject into the HEAD or
STYLE element directly. (Both of these
tags are READ ONLY.) The best way to
dynamically add styles to a page is to
wait for the document to load, and
then create the rule in a new style
sheet.
Why is it a readonly attribute? Here is an explanation.
So, you need to use a DOM approach to do this dynamic loading. Check this link to load external javascript resources and this one to inline scripts which is your case.
newScript = document.createElement('script');
newScript.type = 'text/javascript';
var head = document.getElementsByTagName("head")[0];
var src = '$(window).load(function(){ someFooo(); }); ';
newScript.text = src;
head.appendChild(newScript);

Categories

Resources