Access containing element of <script> - javascript

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.

Related

Is it bad to have script tag inside div?

What is bad about having a script tag inside div inside body?
I'm dynamically updating a div to reload a javascript code inside a div. Are there any issues to worry about ?
Edit
As #Bergi insisted on seeing the code. Here it is(see below). This div (along with other div(s) containing presentation HTML elements) are updated via AJAX. This script inside div contains maps to do processing of newly loaded HTML elements on page with raw data.
<div>
<script type="text/javascript">
var namesMap = <dynamic string from server here>;
var addressesMap = <dynamic string from server here>;
</script>
</div>
It is perfectly ok to place the <script> tag anywhere in the body of the document.
From here,
The SCRIPT element places a script within a document. This element may appear any number of times in the HEAD or BODY of an HTML document.
However, whenever a <script> tag occurs, it pauses the parsing of the code till the script gets loaded, and executed.
You can add <script></script> inside a DIV tag. Just check on w3c, it is valid HTML.
There is not much bad about it. Most widgets work this way. It is still valid HTML.
If you want to embed an AdSense unit in your page, you will need to do it. The same with Amazon widgets. That means majority of websites have a script tag inside div.
There are pros and cons for putting scripts inside html. The good thing is that a small script can be placed close to where it is used so you can more easily understand what the page is doing.
If nobody else but that one location needs that script then it is fine to put it there, I think.
Bad thing is that when you divide parts of your program into multiple locations it becomes more difficult to see and manage how such parts interact and interfere with each other. Whereas if you keep your html and javascript in separate files it becomes easier to understand each independently, and then finally focus on how they interact with each other. What are the "interfaces" between them.
If JavaScript is interspersed into the html then you can not organize your script-code separately from organizing the HTML.
ONE MORE THING to be aware of: If you have a DIV you may think that you can manipulate its content by re-assigning its innerHTML. And that works, except, you can not inject a script into the DIV that way. SEE:
Can scripts be inserted with innerHTML?
So one bad thing about having a script inside a DIV is that you can not replace such a script by re-assigning its innerHTML.
By SCRIPT inside <DIV> still working.
But some annoy with your layout - shacking when scroll.
Best solution: put script inside <body> or <head> :D
It was always a good practice to try to put your <script></script> tags in <head></head>. However, lately arguments appearead whether putting a tags at the end of <body></body> tags, just before made a page more faster.
I would recommend to put your <script></script> in <head></head> section of your HTML document, since it is more preffered. Additionally, putting a <script></script> inside a DIV is not a good practice.
You can post your example for a better answer abour organizing the structure of your document.
To sum up, there is no problem in what you are doing. But a more organized way is what I suggest.

Load pages via AJAX and execute javascript and CSS

I've been searching for a while now, but I can't figure out how to load an entire page via AJAX and still execute all javascript and css.
Mostly I just end up with the plain text without any CSS.
Is there a way to do this? I tried jQuery.get, jQuery.load and jQuery.ajax, but none really work like that.
I have a different solution. You may try it with an iframe. Use jQuery to append an iframe script including all relevant codes into some part of your page (like some div). This may do it for you including CSS, like;
$('<iframe src="your_page.html"/>').appendTo('#your_div');
Or you may try something like;
$('<iframe src="your_page.html"/>').load(function(){
alert('the iframe is done loading');
}).appendTo('#your_div');
I have solved similar problem as following.
Download the webpage over ajax
Iterate it over and find any <script> and </script> tags
Get content from within these tags as text
Create new <script> element and insert there the code
Append the tag to your webpage
Another thing is you will need to somehow call the script..
I have done it this way:
I set standardized function names like initAddedScript callback which I am calling after appending the script to the page. Same as I have deinitScript called when I do not need the code (and its variables,..) anymore.
I must say this is awful solution, which likely means you have bad application architecture so as I have had:)
With css is it the same, but you do not need any handlers. Just append the style tag to your documents head.
If the page you load doesn't have any style data, then the external stylesheets must have relative paths that are not correct relative to the invoking document. Remember, this isn't an iFrame - you aren't framing an external document in your document, you're combining one document into another.
Another problem is that loading your complete page will also load the doctype, html, head, and body tags - which modern browsers will cope with most of the time, but the results are undefined because it's not valid HTML to jam one document into another wholesale. And this brings me to the third reason why it won't work: CSS links outside of the head section aren't valid, and the misplaced head section caused by your haphazard document-in-document collage.
What I'd do for compliance (and correct rendering) is this, which would be implemented in the Success callback:
Copy all link elements to a new jQuery element.
Copy the contents of all script in the head section
Copy the .html() contents from the loaded document's body tag
Append the link elements (copied out in step 1) to your host document's head
Create a new script tag with your copied script contents and stick it in the head too
Done!
Complicated? Kind of, I guess, but if you really want to load an entire page using AJAX it's your only option. It's also going to cause problems with the page's JavaScript no matter what you do, particularly code that's supposed to run during the initial load. There's nothing you can do about this. If it's a problem, you need to either rewrite the source page to be more load-friendly or you could figure out how to make an iFrame suit your needs.
It's also worth considering whether it'd work to just load your external CSS in the host document in the first place.
I suppose you are looking for something like this:
your page div --> load --> www.some-site.com
After a quik search the closest solution seems to be the one by "And": Load website into DIV
You have to run a web server and create a proxy.php page with this content:
Then your JQuery load() function should be like this:
$("#your_div_id").load("proxy.php?url=http://some-site.com");
NB. I have tested this solution and it should not load all the CSS from the target page, probably you'll have to recreate them. For example the image files stored on the remote server will not loaded, I suppose due to authentication policy.
You will be also able to view only the target page without the possibility to browse the target site.
Anyway I hope this could be a step forward to your solution.
Get your entire webpage as text using ajax
document.open();
document.write(this.responseText);
document.close();
OR
document.documentElement.outerHTML = this.responseText;
But you need to change the path of css and js pages in original webpage if the resulting webpage is in another directory.

Remove ajax loaded content and script

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.

jQuery Appending script to div

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

If Javascript code block is not at end of HTML file, but is using jQuery's $(document).ready(function() {...}), will it slow down the page display?

It is said that Javascript code should be all placed at the end of HTML file, so that the page content is shown first, for the user to see something (so that the user is satisfied to see something instead of waiting another 12 seconds, for example).
But to better encapsulation of the HTML and match Javascript code, such as an "Image Carousel", then usually the HTML and Javascript is placed in one single file, so there are Javascript code blocks all intermixed with HTML code throughout the final HTML file.
But what if all these Javascript code blocks use jQuery's $(document).ready(function() { ... }) to perform the task, then won't the page display be very fast as well? I think not as fast as when the Javascript is actually placed at the end of the HTML file, but close enough, because it merely adds a function to the ready event queue.
I think the point is to place the js at the bottom of the page (usually just inside the closing </body> tag) so that the content of the page is displayed while the js is downloading.
If you have your jQuery code spread out throughout the HTML in separate .ready() calls, then no matter what, it won't run until the <body> has fully loaded. So the question would be how much javascript do you have in the HTML?
If there's quite a bit, then it will slow down the display of any content that comes after each script. If it is a relatively small amount of code, then it won't likely make much noticeable difference.
If it is really important to you to have the page's content displayed as soon as possible, then place all scripts after the content.
I personally wouldn't mix javascript with HTML just for the sake of association. You could have unexpected results if you start removing/appending content that happens to include a script. I'd rather use appropriately named classes and IDs, as well as lots of code comments.
Also keep in mind that those .ready() calls won't work until jQuery has loaded, which would mean that it would need to be at the top of the page, or at least before your first call.
So again it gets back to the question of which is more important to you. If you want the content visible as quickly as possible, place all js at the bottom. If you want your method of intermixing js and HTML, you'll have some delay in displaying the page.

Categories

Resources