I dont know this may be duplicate but,
I use ajax in my website, now in response to that call i send some html and script.
Then I replace that data with some of my element exist in page.
Now, I want to make second ajax call so I have removed html content from loaded div. Then again ajax call return some other html code and script. But Some times it is conflict between previous script and newly arrived script.
EX.
1st response I replace html and script with some element: $('.ma_right_main').html(response.data);
then before 2nd call I remove content:
$('.ma_right_main').html('');
2nd response I replace html and script with some element: $('.ma_right_main').html(response.data);
but after replace it 2nd time script returned from first time still there in execution. I want to remove it just like how I can remove html content.
I don't think once a browser has loaded a script that it can be removed (this doesn't mean you can't remove it from the dom, but it would still exist.) For example if you had a script with variable x, load the page so the script gets loaded, remove the script from the dom, x I think would still be defined.
There are ways around this though, if each dynamically loaded script was its own object, when "unloading" you could set the object to null. This is a solution I came across a while back when looking for a similar solution.
Found the reference I was referring to: https://stackoverflow.com/a/1346903/1475461
The scripts aren't naturally executed at all. (Setting .innerHTML will not execute scripts inside the HTML).
jQuery manually finds all the script elements in the html, removes them and evaluates them. So if you are using .html and don't want the scripts to execute, do not include scripts in the html.
And you cannot deactivate scripts, so you need to refactor your website with this in mind. Don't include new code in responses if they can conflict with previous ones. Use generic code that is always loaded.
Related
I am including some related content on misc. web pages by adding a <script> tag near the end of the <body> tag, which then loads other javascript files. The flow is a little convoluted, so I’ll try to explain it before asking my question:
A browser loads a page with our <script> element near the end of the <body> element
The src attribute of the script tag points to a javascript file which (in some cases) injects a second <script> element
The src attribute of the injected <script> element points to yet another javascript file, which finally injects some content on the appropriate part of the page.
We are using this two-stage approach to be able to do some basic processing before deciding whether to include the final content, which could take some time to load.
The problem is that IE8 (and maybe older versions) loads the last javascript twice. It appears that the act of setting the src attribute will trigger a load, but so will appending the script tag to the DOM. Is there any way to avoid this?
I have created a bare-bones demo of the problem. If you have some way of tracing the HTTP requests, you will see that IE8 loads js_test2.js twice.
The root difference is that IE executes a script element the first time it is added to a parent element's childNodes, regardless of whether the parent element is actually in the document. Other browsers only execute script when it is added to a node inside the document's tree of childNodes.
jQuery's domManip function (line 524 of jQuery 1.3.2), which is called by append and other similar jQuery methods, tries to be clever and calls evalScript for any <script> elements it finds in the final parsed HTML, to execute the script (by doing AJAX requests if necessary for external scripts). (The actual script elements have been removed from the parsed childNodes to stop them getting executed on insertion into the document, presumably so that scripts are only executed once when content containing them is appended into multiple elements at once.)
However, because the previous clean function, whilst parsing the HTML, appended the script element to a wrapper div, IE will have already executed the script. So you get two executions.
The best thing to do is avoid using domManip functions like append with HTML strings when you're doing anything with scripts.
In fact, forget putting your content in a serialised HTML string and getting jQuery to parse it; just do it the much more reliable plain DOM way:
var s= document.createElement('script');
s.type= 'text/javascript';
s.charset= 'UTF-8';
s.src= 'js_test2.js';
document.getElementById('some_container').appendChild(s);
(To be honest, after viewing the stomach-churning source code of the clean function, I'm having serious doubts about using jQuery's HTML-string-based DOM manipulations for anything at all. It's supposed to fix up browser bugs, but the dumb-regex processing seems to me likely to cause as many problems as it solves.)
Incidentally with this initial call:
document.write(unescape("%3Cscript src='js_test1.js' type='text/javascript'%3E%3C/script%3E"));
You don't need to unescape here; I don't know why so many people do. The sequence </ needs to be avoided in an inline script as it would end the <script> tag, and if you're doing XHTML < and & should be avoided too (or ]]> if you're using a CDATA wrapper), but there's an easier way of doing all that with just JavaScript string literals:
document.write('\x3Cscript src="js_test1.js" type="text/javascript">\x3C/script>"));
I've seen that behavior happening on other versions of IE under similar circumstances (such as cloning of <script> nodes) and I never got to know how to stop the script from executing twice, so what I ended up doing was adding a guard on the script code for it not to run twice. It was something like:
if (typeof(loaded) == 'undefined') {
// the whole code goes in here
var loaded = true;
}
If you can't find a way of preventing the script to execute twice, you may want to try that approach instead.
It would seem that jquery is fetching the second instance of js_test2 using XmlHttpRequest.
Why I don't know but its the behaviour of JQuery you need to investigate.
You can check to see if a script is already in the document before loading it-
function fetchscript(url, callback){
var S= document.getElementsByTagName('script'), L= S.length;
while(L){
if(S[--L].src== url) return true;
}
//create and append script and any callbacks
}
I find the same problem,only happen in IE.
jQuery‘s html() method chains is: html>append>domManip>clean
clean() method use innerHTML make string to DOM, innerHTML in IE has a bug that script tag will immediately load(first load), jQuery evalScript script tags at the end of domManip method(ajax load).then script file load twice in IE.
I think jQuery should fix this problem,update the clean() method
It's possible that this is because you use document.write when you're already in a <script> element. Have you tried appending to <head> instead of document.write?
I've seen a few topics that hint along the lines I'm looking for, but I need to take this a step further.
I have a site that uses AJAX to insert new content as it is added to the site. This content sometimes includes inline JavaScript. As it is right now, if this inline JavaScript includes a document.write() call, the rest of the page content is wiped out and replaced with the contents of the write call and ruins the page.
These inline <script> elements are always contained within a DIV, but due to the nature of the site's software, the DIVs may appear more than once in the same post, and as such can't make use of names or IDs to help the script find where the new content goes.
I see that many posts say that the currently executing <script> should appear as the last element in document.scripts, however, what happens when the <script> is added mid-page via AJAX? In the layout of the page, the <script> is not always the last one on the page, so if it is added after the page is finished loading, even if not at the end of the document, will it still appear as the last entry in document.scripts?
I'm afraid you have a serious problem on your hands.
Once the document has finished rendering, document.write will replace it. So if you are trying to include markup via AJAX that has such calls in SCRIPT elements and you want to execute those scripts, you're going to overwrite the document.
In other words, you really can't mix AJAX and document.write. You need to rework to do without one or the other.
While this answer only really satisfies my specific issue, it may be of assistance to others, so I'll post what I did:
I used some of the raw data that made up the javascript calls to create an ID for the containing DIV, allowing that DIV to have a unique ID that the script could access in the DOM. This way, when the code was injected via the AJAX script and the inline script was executed, it would target its own container's innerHTML and overwrite itself with the intended code that was supposed to display on the page.
In my specific usage, my script would take a series of numbers as parameters and replace them with various images, symbols and words, depending on what the numbers represented. I ended up formatting the output as something like:
<div id="{param1param2param3}">
<script>
document.getElementById('param1param2param3').innerHTML={all the content the script is supposed to generate};
</script>
</div>
The result is the same whether the page is loaded normally or via AJAX. In the rare case that there are two blocks with the same ID (meaning the exact same parameters), all browsers seem to handle it correctly and replace each DIV with the intended code. I don't know if each script is actually targetting its own container or any of the others with the same ID, but since they'd all end up with identical contents anyway, it doesn't matter as long as all the DIVs get replaced with their intended content.
It could be further extended by having the script remove the ID from the DIV it was working on, so that other "identical" blocks don't try to execute on the same DIV over and over.
I'm using ajax (with jQuery) to update parts of a webpage.
The queries return html to insert at various places.
However, these html blocks sometimes contain javascript that write stuff
where they're located. I mean, in some div of the html returned by AJAX, there's a script that gets included, and this script executes some document.write() instructions (typically scripts from our ads publisher we don't have any control over).
Now, if I just take the html returned by my AJAX queries and update the DOM with it, the javascript doesn't get executed.
What's the cleanest/easiest way to make sure that document.write() writes its stuff at the appropriate spots ?
You can't use document.write() with dynamically inserted content. The issue is that the current document has already been opened, parsed and closed upon the initial page load. If you now invoke document.write() from one of these scripts, it will clear the current document and start writing a new document. That will blank your browser window and write just the new content (which is certainly not what you want).
The options I can think of are:
Put the content in an iframe and load it via the .src attribute, not via ajax so the content can load into a new document and document.write() can do its normal, expected thing.
Change those scripts to not use document.write(). If you control that code, then the scripts need to be changed to insert content into a specific DOM element, not to try to write into the document stream because the document stream will not work the way you want once the original document has been parsed and the document closed.
Hack document.write() (by temporarily replacing it with a different method) so it captures the document.write() content in a different way while your dynamic content is being loaded and then you dynamically insert it into some existing DOM element rather than use the actual document.write(). This is truly a hack and it cannot be guaranteed that this will work in all browsers.
As you've no doubt discovered, document.write totally destroys the current document.
There are a few ways to handle it, the easiest one I've found is to replace document.write with a function that uses regular DOM manipulations.
document.write = function(str) {
var oldtxt = $("#destdiv").html();
oldtxt += str;
$("#destdiv").html(oldtxt);
}
I know that jQuery automatically parses script elements and append them to the head, however I dont have much of a choice. I need to insert an html string exactly into a specified div. so for example <script src='http://.....'></script> into <div id="lb"></div>.
The problem is that the scripts get loaded from a server which I have no control over and is using a document.write() script. So if that gets appended to the header, there will be severe issues. How can I do this with or without jQuery?
Ok. So to rephrase your question:
You want to insert some < script > tags in your page. These tags load javascript files that have document.write() in them.
Now you want the document.write() to happen in some divs, and not in the header.
I think you would then need to render those script tags directly in the source of your page from the very start. Felix noted correctly that when you load thse script tags later, the whole page will be replaced by what is outputted by the document.write() function.
Thus, javascript or JQuery cannot load these script tags. You should render them serverside in the initial version of your page..!
If you don't want your script to alter the content of you page you could insert it in an iframe instead of a div ? document should refer to the iframe then. I don't exactly get what you want though.
Document.write() will put the script at the end of the document (afaik). Then, you would need to look-up these script-tags and put them into the proper DIVs (with a $(elm).append(scriptObj)).
But I might not understand what your problem is...
When I write the following code directly into my html page under a script tag, the string "test" gets appended to my page without replacing the rest of its content (1):
document.write("test");
However, if I place that same code into a separate javascript file like (2):
<script src="http://127.0.0.1/whatever.js" type="text/javascript"></script>
Suddenly that same code rewrites my entire page.
Is there a way to perform a document.write() from a remote file and get the result in (1)?
Thanks for your time.
If you use doc.write while the page page is rendering, it will insert or append the string. If you use doc.write after it's rendered, or after window.onload, it will essentially begin the rendering process again, and overwrite the page.
It's my guess that you are getting asynchronous behavior when loading the script, and it's not executing until after onload. I can't recreate your problem.
You may be including your script at the top of the page. Where it gets the document.write() stuff and thus writes the text instead of a append behaviour.
The safer solution is to append a document element to the page - that should always work