With jquery.load() I'm loading some html into my page from a file which also contains javascript functions.
later I try to remove the html and the javascript using jquery.empty but it seems once the script is parsed by the browser I can't get rid of it, so I'm looking for suggestions on how to do this.
Below is the test source:
index.html
<head>
<script src="//code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$(function(){
$('#loadEmbScrpt').click(function(){
$('#embDiv').load('http://maccyd10.hostoi.com/test.html');
});
$('#remEmbScrpt').click(function(){
$('#embDiv').empty();
});
});
<body>
<div id="embDiv"></div>
<div id="output"></div>
<input type="button" id="loadEmbScrpt" value="embed script into page"/>
<input type="button" id="remEmbScrpt" value="remove embedded script from page"/>
<input type="button" id="testButton" value="run embedded script test function"/>
</body>
test.html
<script>
$('#testButton').on('click',function(){
$('#output').append("<p>test</p>");
});
</script>
And here is a link to the above in action (I could not post this to jsfiddle due to XSS protection).
http://maccyd10.hostoi.com
Have a play with this http://jsfiddle.net/6eWRQ/
As others have alluded to, the DOM and the Javascript VM are two separate systems within the browser.
The DOM is the browser's internal model of the HTML document to be rendered. It deals with HTML elements such as <script> and their position within the HTML document.
The Javascript VM deals with javascript code - it deals with running any Javascript code within <script> tags or pulled in from external js files.
it seems once the script is parsed by the browser I can't get rid of it
You can of course remove the <script> element from the DOM - but after the browser has parsed it this will have zero effect on the javascript VM - because then the javascript code inside the tag it has already been consumed and executed by the VM. Once the code has run, it cannot be un-run.
In the case of the example jsfiddle this is even clearer - removing a <script> element containing a function doesn't mean you can't call that function any more, once the code inside the <script> has already been executed by the VM. The VM has its own internal model of the function and changes to the original code in the DOM after it has been executed are simply irrelevant to it.
Removing the containing <script> element from the DOM using javascript is effectively pointless in this situation - it's just redundant. The DOM rendering engine has no use for it because it's not a visual element, and the javascript VM has no use for it because it's already-processed input.
To do what you want you should remove the #remEmbScrpt button, and instead use the following to undo the binding performed by the loaded script:
$('#testButton').off('click');
As has been mentioned in the comments, you can't get rid of javascript once it has been loaded.
With that being said, if you wish to undo the changes made by the script you posted above, the .off() function will unbind all attached to a handler (so if any other events are attached to click, they will be removed to).
e.g. the following will unbind the functions from the click events on $('#loadEmbScrpt') and $('#remEmbScrpt') :
$('#loadEmbScrpt').off('click');
$('#remEmbScrpt').off('click');
or if you want it all in one line:
$('#loadEmbScrpt,#remEmbScrpt').off('click');
Let me know if that solves your problem
Related
Got a little problem here. Basically, I'm trying to add a script tag after the page loads.
This is what I am doing:
index.php:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function getad()
{
$.post('assets/getad.php', "ad", function(response) {
response = response.replace('document.write','document.getElementById("ad").innerHTML = ');
eval(response);
console.log(response);
});
}
getad();
</script>
<div id="ad"></div>
</body>
</html>
getad.php:
<?php
echo file_get_contents("http://ads1.qadabra.com/t?id=a823aca3-9e3c-4ddd-a0cc-14b497cad85b&size=300x250");
?>
You can find a demo here: http://dev.cj.gy/game/
As you can see, the #ad div DOES get filled with the correct script tag, but it doesnt actually run, If I edit the page to include the script tag right at page load, it does run.
Yes, <script> tags cause execution when parsed as part of the main document; they don't execute from being written to innerHTML.
You can create an executing script element outside of that initial parse using the DOM method of calling createElement('script'), setting its src/content and adding it to the document. This is what jQuery's getScript does.
However it wouldn't do you much good because the next script, that ads1.qadabra.com is document.writeing to the page, also itself calls document.write.
You could work your way around both of these calls at the client side (ie without getad.php), by assigning your own custom function to document.write that, instead of writing to the loading page, attempts to extract the source of the script tag passed to it, and load that in a DOM-created script element.
But in general these are scripts designed to work synchronously at document load time; anything you do to try to force them to run in a way they weren't intended to is likely to be fragile and stop working when the ad network change anything.
If you want to load a third-party ad without pausing the loading of the parent document, I suggest putting it in an iframe.
Based on the code below, I would like to know if there would be a significant change in the page loading time if i would to call the desktopPopup html scripts later (assuming I have alot of html codes which are being executed there) or am I doing it just wrong? The comparison is using the method below and against writing the entire html code without the scripts
<script id="desktop" type="text/html">
//some html in here
</script>
<script type="text/javascript">
$(function() {
$('body').one("click", function(e) {
$("body").append($('#desktop').html());
});
});
</script>
Including it right away will be faster. In this case your browsers only needs to build DOM and render it.
In the second case your browser has to:
download and execute jQuery (if it hasn't been done beforehand)
select elements from DOM, insert HTML into it
rebuild part of DOM and render it
If I have a button that executes the code
$('#main').load('welcome.html');
and in welcome.html I have a button that executes the code
$('#main').load('otherpage.html');
the Javascript isn't executed, regardless of whether that function is on the parent file's HTML code or the child's.
How can I get a Javascript function to work from externally loaded HTML files?
EDIT
Here's a bit more of a sample...
Homepage:
<body>
<div id="main"></div>
</body>
<script>
document.onLoad(){
$('#main').load('welcome.html');
}
function show(file){
$('#main').load(file+'.html');
}
</script>
welcome.html page:
Test
...however when the Test button is clicked, test.html is not loaded into the Main div.
EDIT 2
Here is what the current state is and what the issue is - exactly.
I've uploaded the bones of the code to PasteBin.
When the 'grid' button is clicked, the content changes and the footer changes.
However, the footer, which has URLs based on Javascript, comes up with the error:
Uncaught SyntaxError: Unexpected token ILLEGAL
...when trying to access the 1i.html page.
There's a difference between test the variable and 'test' the string:
Test
Probably should be:
Test
It is important to understand that when loading script into page via AJAX that the main page has already gone through document.ready . Thus, any code you load will fire immediately.
If the code you load precedes the html it references, it will not find that html when it fires.
Placing the code after the html in remote page will resolve this issue
Check jQuery.live() and jQuery.on().
Maybe your eventhandler is wrong. When you import new markup via load() or ajax(), you have to initialize the handlers from new document. The easiest way is using jQuery.on or jQuery.live() instead of jQuery.click().
$('MYBUTTON').live('click', function(){
$('#main').load('your_url.html')
})
or use the callbackfunction to (re-)initialize the buttons event.
A better solution is this: Just add the target_url to buttons rel attribute...
<button rel="YOUR_URL.html">Open Page</button>
$('button[rel]').live('click', function(){
$('#main').load($(this).attr('rel'));
})
I'm trying to do something fairly simple, but for the reason of me probably not being good enough to search documentation, I can't get this to work.
I have a functioning inline JS that looks like this:
<A title="Wolfram IP Calc" href="javascript:txt=prompt('Enter%20IP%20address,%20e.g.%2010.20.30.40/29','1.2.3.4/5');%20if(txt)%20window.open('http://www.wolframalpha.com/input/?i='+txt);void(O);">Compute!</A>
For various reasons, I'm trying to seperate the JS, and this is where I hit a snag.
I've created the following test page that gives me the error Uncaught TypeError: Cannot call method 'addEventListener' of null:
<HTML> <HEAD profile="http://www.w3.org/2005/10/profile"> <script type="text/javascript">
var compute = document.getElementById('compute');
compute.addEventListener('click', computeThatThing, false);
function computeThatThing() {
txt=prompt('Enter%20IP%20address,%20e.g.%2010.20.30.40/29','1.2.3.4/5');
if(txt) {
window.open('http://www.wolframalpha.com/input/?i='+txt);
}
}
</script></HEAD>
<BODY>
<A title="Wolfram IP Calc" id="compute" href="javascript:void(O);">Test</A>
</BODY>
</HTML>
The only thing I've been able to find that points to a problem like that is that addEventListener can't work with <A> but should handle <IMG> (which suits me fine as I'm going to pour this on some images), so I tried adding the following to no avail:
<img id="compute" src="http://products.wolframalpha.com/images/products/products-wa.png" />
Thanks in advance for pointing out what I'm doing wrong. It is probably glaringly obvious, but I have close to zero experience with JS and I have gone mostly by cargo culting when I've needed it until now.
Your code is in the <head> => runs before the elements are rendered, so document.getElementById('compute'); returns null, as MDN promise...
element = document.getElementById(id);
element is a reference to an Element object, or null if an element with the specified ID is not in the document.
MDN
Solutions:
Put the scripts in the bottom of the page.
Call the attach code in the load event.
Use jQuery library and it's DOM ready event.
What is the jQuery ready event and why is it needed?
(why no just JavaScript's load event):
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers...
...
ready docs
Move script tag at the end of BODY instead of HEAD because in current code when the script is computed html element doesn't exist in document.
Since you don't want to you jquery. Use window.onload or document.onload to execute the entire piece of code that you have in current script tag.
window.onload vs document.onload
Can we you get our JavaScript to run in the first place to
assign an event handler?
How can we get an initial piece of JavaScript to run without referencing a function in your XHTML page?
Just put a script tag in the body of your page and it will run as the page is rendered.
<script type="text/javascript">
// code goes here
</script>
Any code you put in a <script type="text/javascript"> tag will be executed immediately. Put it in your <head> and it will run before anything else. Put at the end of the <body> and it will run last.
Do keep in mind that the DOM may not be fully initialized in either of those cases. If you need the DOM use window.onload or jQuery's $(document).ready()
Also 'XHTML' and 'HTML' are not the same. XHTML is a very strict subset of HTML that in my opinion does nothing to improve upon regular HTML but it does allow for some fanciness. It has no effect whatsoever on JavaScript.
As you've tagged jQuery the way to do this is simply by including a ready function, e.g.
$(document).ready(function () {
// Assign your event handlers
});
Just put this code within a <script type="text/javascript"> block within your page.