I am preparing an HTML code on memory for an Iframe, when I use append it executes the code.
html = $(parser.parseFromString($("#EHtml").val(), "text/html"));
js = '<script>' + $("#EJs").val() + '</script>';
html.find('body').append(js);
$("#EHtml").val() contains HTML code
and the append function does its job but also executes the code.
Any thoughts here?
You need to just store a reference to the string of code and do 1 of two things: either do the append interaction only when you want to run the code later, or run eval(jsString) when you want to run it.
Script tags won't execute if their [type] attribute is set to anything wacky.
<script type="wacky/non-executing">
console.log("This will not execute! You will not see this!");
</script>
Its Obvious to run script when you insert it, between script tags,Because your DOM already complete loads.
And it will run twice because you put it inside the body So when you body content canges the script ran again!
So you have to set your Script tag on head of an iframe to it will run Only when you insert it or reload,and not again an again !
I am not suggesting you to use eval() because it is dangerous to use for script evaluation,eval() is basically used for another purpose !
Use <script></script> tags to run your script and place it on head if you don't want to ran it twice .
var script = document.createElement('script');
script.innerHTML = $("#EJs").val();
iframe.contentWindow.document.head.appendChild(script);
May be this will help you..
Try using entities, like
var encodeHtmlEntity = function(str) {
var buf = [];
for (var i=str.length-1;i>=0;i--) {
buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
}
return buf.join('');
};
html.find('body').append(encodeHtmlEntity(js));
to append and
var decodeHtmlEntity = function(str) {
return str.replace(/&#(\d+);/g, function(match, dec) {
return String.fromCharCode(dec);
});
};
decodeHtmlEntity(html.find('body').val());
to read.
Got it in the way I need.
I was trying to add the script tag without using ways around the problem - I mean I just wanted to add the tag as it is. Thanks every body for the inputs - I got the solution from your advises...
in the end I could append to the Iframe but it was executing in the main page context. What was causing the problem was using JQuery to do the appending... so here it is:
frame = document.getElementById("frame");
out = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;
out.document.open();
out.document.write(html.find('html')[0].outerHTML);//HTML added here
//JS appended here
js=out.document.createElement('script');
js.innerHTML = 'js code here';
out.document.getElementsByTagName("body")[0].appendChild(js);
out.document.close();
I hope its useful for someone...
Related
I create an iframe in a file and insert a <script> tag as its content. The Script src is loaded from a different file called test.js. Here is how it is done:
var scriptElement = document.querySelector("#your-widget");
var iframe = document.createElement("iframe");
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
var script = document.createElement("script");
iframe.contentWindow.document.appendChild(script);
script.src = "http://www.example.com/test.js";
Instead of loading the content of the script from http://www.example.com/test.js I want to take it from the same file where the above code is. This would like this:
var scriptElement = document.querySelector("#your-widget");
var iframe = document.createElement("iframe");
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
var script = document.createElement("script");
iframe.contentWindow.document.appendChild(script);
script.src = // ????
// the following JavaScript code should be placed inside the script
function mywidget() {
// some code
return true;
}
mywidget.succeeded = mywidget();
How can I set the Script Source from the same file instead of a different one?
If you literally just want to place that exact snippet in a script tag, you can just do so using .innerText.
script.innerText = 'function mywidget() { ...';
Then it will execute as is when it's inserted into the DOM. If you want to dynamically find and inject that code, read on.
There are exactly two ways to load a script on a page.
Add a <script> with the src attribute pointing to a file.
Create a <script> tag then set the contents to whatever you want to execute.
var script = document.createElement('script');
script.innerText = 'console.log("Hello, World!")';
document.body.appendChild(script);
If you want to extract part of a script and use those contents then the best you can do is load the contents via ajax and inject it using method 2.
Assuming you have jQuery (for easy AJAX work):
$.ajax({
url: 'path/to/script.js',
dataType: 'text', // make sure it doesn't get eval'd
success: function(contentsOfScript) {
// Refer to method 2
}
});
Now you can go about extracting the contents of that snippet in one of two ways:
Know exactly which line it begins on.
var lines = contentsOfScript.split('\n');
var snippet = lines.slice(lineNumber + 1); // adjust for 0 indexing
Generate a regular expression to identify where your code begins. This is rather tricky and very error prone if your snippet isn't easily distinguished from other code.
var snippet = contentsOfScript.match(/function mywidget.+/)[0];
Neither of these methods will work if you perform any minification on your code.
I need to do a conditional append here is the example url
www.google.com/default.asp/W12345
I want to append a JS file if the url has W and a random string of numbers after it.
How can i achieve this?
Try something like this:
<script>
if (/default\.asp\/W[\d\w]*$/.test(location.href)) {
document.write("<script src='/path/to/your/js/file.js'>");
}
</script>
Insert that code anywhere on the page, typically either in the head, either at the very end of the document.
Use the below snippet on dom-loaded. Here I'm making use of regular expression if it ends with url /wSomeString or /WsomeOtherString.
if(/.+\/w.+$/i.test(window.location.href)) {
var scriptDom = document.createElement("script");
scriptDom.type = "application/javascript";
scriptDom.src = "url/to/js"; //update JS url here.
document.body.appendChild(scriptDom);
}
Tried this :
Click me
<div id="pasteContent"></div>
var elemFunc = '<script>alert("myString");</script>';
$("#showAlert").click(function () {
$("#pasteContent").html(elemFunc);
});
What I'd like to do is to append the string alert(myString); (which is a script) that must be executed... how can I do? Is it not correct?
Add a backslash before / in </script>: http://jsfiddle.net/kxALH/3/
Your code failed, because </script> is considered as a close tag for your fiddle script. As a result, your first fiddle looked somewhat weird.
Note: If you want to execute an arbitrary string of code, $.globalEval('alert("myString")'); may suit better.
try it whit a jquery script object like this
var elemFunc = $('<script>')
.attr('type', 'text/javascript')
.html('alert("myString");');
$("#showAlert").click(function () {
$("#pasteContent").append(elemFunc);
});
Try this:
var elemFunc = '<script>alert("myString");</' + 'script>';
If you have your JS inside your HTML
Try this:
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://somedomain.com/somescript";
$("head").append(s);
Note that the script will load and you can access the variables inside it, but you wouldn't see the actual tag in the DOM.
Since what you're going equates to an eval, and eval IS evil, You can use an external script and $.getScript(), to load it via ajax...
$.getScript("http://scriptURL.com/script.js", function(){ init(); });
While doing development on a .js file I'd like to just refresh that file instead of the entire page to save time. Anyone know of any techniques for this?
Here is a function to create a new script element. It appends an incremented integer to make the URL of the script unique (as Kon suggested) in order to force a download.
var index = 0;
function refreshScript (src) {
var scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.src = src + '?' + index++;
document.getElementsByTagName('head')[0].appendChild(scriptElement);
}
Then in the Firebug console, you can call it as:
refreshScript('my_script.js');
You'll need to make sure that the index itself is not part of the script being reloaded!
The Firebug Net panel will help you see whether the script is being downloaded. The response status should be "200 OK" and not "304 Not Modified. Also, you should see the index appended in the query string.
The Firebug HTML panel will help you see whether the script element was appended to the head element.
UPDATE:
Here is a version that uses a timestamp instead of an index variable. As #davyM suggests, it is a more flexible approach:
function refreshScript (src) {
var scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.src = src + '?' + (new Date).getTime();
document.getElementsByTagName('head')[0].appendChild(scriptElement);
}
Alexei's points are also well-stated.
I suggest you to use Firebug for this purpose.
See this video, it helped me a lot.
http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/
If you're talking about the unfortunate case of client-side/browser caching of your .js file, then you can simply version your .js file. You can:
Rename the .js file itself (not preferred)
Update the include line to reference yourfile.js?1, yourfile.js?2, etc.. Thus forcing the browser to request the latest version from the server. (preferred)
Unfortunately, you have to refresh the web page to see edits to your JavaScript take place. There is no way that I know of to edit JavaScript in "real-time" and see those edits effect without a refresh.
You can use Firebug to insert new JavaScript, and make real-time changes to DOM objects; but you cannot edit JavaScript that has already been run.
If you just fed up refilling the forms while developing just use form recover extensions like this one https://addons.mozilla.org/ru/firefox/addon/lazarus-form-recovery/
I was wondering if eval (or some variant of jQuery's getScript) can be used to position external javascript in places other than the end of the DOM or at the head. I've tried:
var head = document.getElementById("fig");
instead of
var head = document.getElementsById("head")[0];
with
var script = document.createElement("script");
script.text = $(".code").val();
head.appendChild(script);
But I can't seem to get it to work regardless. (The code does work, but Firebug shows the code being replaced both at #fig and at the end of the page, right before the </body> tag.
Basically the JavaScript toolkit I'm using renders things based on where the script tag is located, and I'm trying to dynamically modify the javascript based on user input (hence I can't really refer to a new external JS file - I'd rather run an eval, which isn't ideal).
I guess the worst case scenario would be to save the user input into a "new" file using PHP or something and use getScript pointing to that new PHP file, but it seems exceedingly hacky.
Thank you once again!
Does the "JavaScript toolkit" you refer to use document.write or document.writeln to insert output into the page? If so, you could override that function to append the script output into the correct location:
document.write = function(s) {
$('#fig').append(s);
};
document.writeln = function(s) {
$('#fig').append(s + '\n');
};
and then load and execute the script using $.getScript.
Edit: A more robust way of doing it, depending on how the code is added:
var output = '';
document.write = function(s) {
output += s;
};
document.writeln = function(s) {
output += s + '\n';
};
$.getScript('URL of script here', function() {
$('#fig').append(output);
});