I'm dynamically changing a script tag's src attribute using JavaScript.
Problem is, that I'd like to "undo" the previous JavaScript before re-executing it.
Any way to do this?
Thanks,
g3
I can describe a method I used to achieve a partial undo in a project. Ugly, but might be useful. First, you may need to refactor your script to work from within an iframe, and/or wrap it in a with statement to give it easy access to some objects in the parent (don't even think of with(opener); you'll want something more precise like with({someObject: opener.someObject}).
When your script runs, it can use the iframe's global scope and DOM freely. Then, instead of reloading the <script> tag, you overwrite the whole iframe, which will reset everything your script did inside the iframe.
Related
I want to load HTML as string into an iframe via Javascript.
like this:
$('#iframe1').contents().find('html').html("<h1>This is an iframe</h1>");
this worked great until I found out, that inside this HTML upcomming Javascript like document.write are writing to the wrong document -> the parent!
Here is a Plunker to show it:
http://plnkr.co/edit/YQAqqSDCVKnP3uhLj4lF?p=preview
if I load the same HTML to the iframe via src as external document, the document.write goes to the iframe (and not to the parent), which is what i was expecting.
Are there some insights out there?
How can I tell the browser to correctly create the iframes document scope before it executes its Javascript?
PS: Its meant to be for preview purposes, so i inject HTML-Code of a (trusted!) source, but within that code, document.write is allowed.
Ok. srcdoc is helpfull here.
$('#iframe1').attr({srcdoc:intrusiveHTML});
I updated the Plunker.
With srcdoc, Javascript won't slip up with the document scope.
It won't work in IE (http://caniuse.com/#feat=iframe-srcdoc), so it might help to use Polyfill additionally:
https://github.com/jugglinmike/srcdoc-polyfill
But I did not test that yet.
Instead of using document.write, use document.getElementById('iframe1').contentWindow.document.write.
Because when you point document it will take main window document, so we need to indicate which iframe doument need to be used.
I'm looking for a non-invasive javascript HTML/CSS/JS injection into page.
I'm ideally looking to use document.write, but keep the original contents that were on the page. So doing the following:
javascript:document.write("blablabla"); - this removes all the content on page, I don't want to use innerHTML += to append the data.
Any suggestions?
If document.write is called after the onload event for the document it needs to re-open the document - effectively truncating it. While you can explicitly call document.write() inline (either with javascript directly embedded in the page or with a tag which does not use defer/async) this is considered bad practice as it blocks all the other processing of the page.
You can inject elements by constructing them in Javascript personally I prefer to set the innerHTML of an existing placeholder to an HTML fragment:
<div id='placeholder/></div>
...
document.getElementById('placeholder').innerHTML="<h2>hello world!</h2>";
(using createElement becomes messy and slow when creating/injecting complex HTML)
document.write will always overwrite the whole page as far I know. One option is to append/prepend your code to a div or to the bottom of your body.
$(elementObj).append(contents);
//or
$(elementObj).prepend(contents);
You can createElement() then use one of the methods above to inject your code into the newly created element.
I want to add a script that applies to a DOM object of a certain type right after it is loaded/rendered. This type of object always comes together with the javascript script, and I want to put them together within some tag. Is it right to do it as below? If so, I suspect span is not the best tag to be used here because it may interact with the way the element inside will be displayed. What tag should I use?
<span>
<div>the dom object to be modified by the script</div>
<script>theJavascriptFunctionThatModifiesTheDomObject()</script>
</span>
I doubt this is the best way to load your script just after a particular element has been loaded by DOM due to these reasons:-
It makes your page load slower.
User will see your complete page in a discrete way.
Instead you should do this:-
Specify a selector to your element.
Include your single javascript code at the end of body.
Update DOM elements using that script.
EDIT:
Solution1: Append your JS at the end of body so that it has access to all the DOM elements.
Since you are injecting the element in DOM using ajax, you can define a success handler for XHR object which will modify your element in DOM.
Solution2: You can define a separate method in your JS and bind this method on some event. In your HTML markup define a data-event attribute and in your success handler append the element to DOM, extract the data-event using jquery data method and trigger that event.
Atleast it will keep you markup far away from scripting logic.
Some useful Links:
Best practices for speeding up your website - yahoo
Why we should load scripts at end - SO Link
The problem here is the script tag does not know where it is located in the DOM. It would be better to do something like add a class to the element[s] you want to alter. On DOM ready, you look up the element[s] and do your magic.
I would avoid this approach; scripts block the page loading
– so if you did this after several dom elements the page would run slow (or not at all if errors were found)
Try using jquery onready - example here : http://api.jquery.com/ready/
And scripts [usually] need to go on the bottom of the page to allow the page to load first
…there are exceptions to this rule such as the well known modernizer script library that needs to go first so it can evaluate the dom as it loads
I was trying to write a global JavaScriptfunction which overrides any HTML object (img, iframe, links and so on) before it being loaded by the page. The purpose of the overiding action was to to change the SRC and HREF of these objects using the DOM to any other link.
Unfortunately I didn't find any solution to that without firstly loading the object and only then changing it by the onload event.
My second option was to change the SRC and HREF by matching these attributes with a regular expression and replacing the resultant values. I prefer not to do so because it's slow and consumes a lot of time.
I would be glad if someone can share with his/her experience and help me solve this out.
JavaScript only works within the DOM.
You could however, load the page via AJAX, get the content and do any string manipulation on it.
If you are trying to modify items that exist in the static HTML of the page, you cannot modify them with javascript until they are successfully loaded by the browser. There is no way to modify them before that. They may or may not be visible to the viewer before you have a chance to modify them.
To solve this issue, there are a couple of options.
Put CSS style rules in the page that causes all items that you want to modify to initially be hidden and then your javascript can modify them and then show them so they will not be seen before your modification.
Don't put the items that you want to modify in the static part of your HTML page. You can either create them programmatically with javascript and insert them into the page or you can load them via ajax, modify them after loading them via ajax and then insert them into the page.
For both of these scenarios, you will have to devise a fallback plan if javascript is not enabled.
I have inline javascript within my HTML. Each individual component that requires animation or action (sliders, expanding text areas, etc.) each have their own inline script, that sets up the animation and such for that individual component.
The way i have it set up, Each script is position dependent: it references its own position in the DOM, and traverses it to find the component it wants to manipulate (e.g. "add onclick to the parent div"). This is normally an incredibly bad idea for several reasons:
having to repeat the same code all over the place, losing DRY
being very verbose, repeating the same chunk of text over and over, taking up bandwidth
cluttering up your HTML with a bunch of inline scripts, making it hard to read
However, the second problem is easily solved with GZIP, and i have solved the first and last problem.
This has the advantage of locality of reference: the component and the scripts they require are kept in one place, not spread out over separate files. Also, I isolate each set of scripts in a (function(){})(), and avoid polluting the global namespace, so each set of scripts for each component is written once and doesn't interact with scripts written elsewhere at all. Perfect modularity
So the question is, how can i stop JQuery eating my script tags when i do Ajax DOM insertions/replacements? If it didn't eat my scripts, because each component is completely self-contained with it's own scripts, i can simply run every script tag in the new component's DOM and that would be that; everything will be set up. No more fiddling with decided which global scripts need to be re-run depending on which component changed.
However, since JQuery seems to insist on stripping my script tags and moving them somewhere, this no longer works. I could do the insertion by modifying replacing the HTML of the entire document, but that causes the whole screen to flash as it reflows (among other problems). Any ideas?
I don't know about jQuery explicitly, but most libraries will remove script elements from content returned from XHR that they intend to insert using innerHTML. That is because inserting innerHTML does not execute the scripts (in the vast majority of browsers). Looking at the jQuery source, the load method strips out script elements.
So they strip out the script elements, then insert the HTML. This ensures the scripts aren't executed or cause issues.
Some libraries have an "execute script" (or similar) flag that, if set, means they will pass the script element content to eval, but there are pitfalls with that too.
One solution is to put all your script snippets into separate files, then use a src attribute on the script elements. If you can't find a jQuery method that doesn't remove the scripts, it's pretty simple to write your own "get" or "load" or whatever function that doesn't, or use one of the thousands that are already written.
If you are only using script elements, you can simply create a script element, set the src attribute and put it in the DOM (this is one method of doing AJAX).
in your html keep spaces for all the replacements using container divs, so that everything you're replacing through AJAX has a special place in the DOM. jQuery wont eat your script tag.
Alternatively, you can also put an id on your script tags and then access then by using the ids.