I have a multi-frame layout. One of the frames contains a form, which I am submitting through XMLHttpRequest. Now when I use document.write() to rewrite the frame with the form, and the new page I am adding contains any javascript then the javascript is not exectuted in IE6?
For example:
document.write("<html><head><script>alert(1);</script></head><body>test</body></html>");
In the above case the page content is replaced with test but the alert() isn't executed. This works fine in Firefox.
What is a workaround to the above problem?
Instead of having the JS code out in the open, enclose it in a function (let's call it "doIt"). Your frame window (let's say it's name is "formFrame") has a parent window (even if it's not visible) in which you can execute JS code. Do the actual frame rewrite operation in that scope:
window.parent.rewriteFormFrame(theHtml);
Where rewriteFormFrame function in the parent window looks something like this:
function rewriteFormFrame(html) {
formFrame.document.body.innerHTML = html;
formFrame.doIt();
}
Workaround is to programmatically add <script> blocks to head DOM element in JavaScript at Callback function or call eval() method. It's only way you can make this work in IE 6.
Another possible alternative is to use JSON, dynamically adding scripts references which will be automatically processed by browser.
Cheers.
In short: You can't really do that. However JavaScript libraries such as jQuery provide functionality to do exactly that. If you depend on that, give jQuery a try.
Eval and/or executing scripts dynamically is bad practice. Very bad practice. Very, very, very bad practice. I can't stress enough, how bad practice it is.
AKA.: Sounds like bad design. What problem are you trying to solve again?
You could use an onload attribute in the body tag (<body onload="jsWrittenLoaded()">).
Related
I have this situation where I have to delete a script tag from the DOM with only the possibility of using another script for this.
I know this isn't a good way of working, but it's the only option at this time.
Therefor my question is if this is possible. I think that when I delete this script you will still be able to use the functions inside.
Thanks!
Is it possible to delete a script tag from the DOM by using another script for this.
Yes, you can remove <script> nodes from the DOM as you can modify any other nodes as well. You even can write a script that removes it's own element.
I think that when I delete this script you will still be able to use the functions inside.
That is correct. When the script has already been executed, the modifications it made to the environment will remain. You can't undo them other than by unloading the page (or explicitly overwriting them - if possible).
I am studying somebody else jquery script, and I noticed he is opening a tag without closing it, but it also seems that browsers does not care (Not yet tested with IE)
it is written :
$('#mydiv').append('<ul>')
But there is nowhere a
.append('</ul>')
The script does not close the list, but browsers do it automatically (I just did an 'inspect element' in the browser).
Is that a 'legal' behavior, or one should always close a tag in a javascript autogenerated content ?
To do it properly, you should be appending:
$('#mydiv').append('<ul></ul>')
Yes browsers will handle it (specifically the .innerHTML implementation handles it, not jQuery), at least the major ones, but why not be safe in all cases and use valid markup?
$('#mydiv').append('<ul>')
...still calls .innerHTML, not createElement, only in $('<ul>') is document.createElement() called. As I said originally, the browser handles it with .append(), not jQuery and not document.createElement (which doesn't take syntax like this anyway).
You can see test/play with what I mean here
Short answer: you should.
Long answer that lead to the short answer:
When you say .append('<ul>'),
or even .append('<ul></ul'), behind the scenes jQuery calls document.createElement and the browser knows what to do.
It's not like jQuery actually puts that string of HTML anywhere, but rather parses it and creates the necessary DOM elements
UPDATE-
As Nick pointed out, this might not always be the case. Relevant source: init
If you pass it just ul, it just calls createElement. If the html string is more complicated, it will go into buildFragment which is more complicated than that.
Based on this, I would say the best/fastest way to create a single element thru jQuery, is to do something like
$('<ul>').appendTo($target);
UPDATE 2-
So apparently jQuery only calls createElement in some methods, but append ends up calling clean which has a regex that closes tags. So either way, you're safe, jQuery saves you as usual.
Relevant source:
...
} else if ( typeof elem === "string" ) {
// Fix "XHTML"-style tags in all browsers
elem = elem.replace(rxhtmlTag, "<$1></$2>");
...
UPDATE 3- So it turns out jQuery doens't fix anything for you when you call append, and it just injects the string into a temporary div element. Seems like most browsers know how to deal with the HTML even if not closed properly, but to be save it's probably best to close it yourself! Or if you're feeling lazy, do something like .append($('<ul>')) which doesn't use innerHTML
This is generally how I manage progressive enhancement whilst keep the experience clean, but how safe is it? is there potential for a race condition and this not working?
Imagine the simple abstract scenario, you want to display something differently if you have javascript support.. this is generally what I will end up doing:
<div id="test">original</div>
<script type="text/javascript">
var t = document.getElementById('test');
t.innerHTML = 'changed';
</script>
Many may claim you should use a framework and wait for a domready event, and do changes there.. however there is a significant delay where the 'test' element will have already been rendered before the end of the document and the css are ready and a domready triggers.. thus causing a noticable flicker of 'original'.
Is this code liable to race condition failures? or can I guarentee that an element is discoverable and modifiable if it exists before the script?
Thanks in advance.
You can, but there are issues surrounding doing it.
First off, in IE if you attempt to manipulate a node that has not been closed (e.g. BODY before its close tag which should be below your JS) then you can encounter IE's "OPERATION ABORTED" error which will result in a blank page. Manipulation of a node includes appending nodes, moving nodes, etc.
In other browsers the behavior is undefined, however they do usually behave as you would expect. The main issue is that as your page evolves, the page may load/parse/run differently. This may cause some script to run before a browser defines referenced elements have actually been created and made available for DOM manipulation.
If you are attempting to enhance your user perceived performance (i.e. snappiness). I highly suggest that you avoid this path and look into lightening your pages. You can use Yahoo's YSlow/Google's Page Performance Firebug to help you get started.
Google's Page Speed
Yahoo's YSlow
You can manipulate the DOM before it has fully loaded, but it can be risky. You obviously can't guarantee that the bit of the DOM you are trying to manipulate actually exists yet, so your code may fail intermittently.
As long as you only modify nodes which preceed the script block (ie the node's closing tag preceeds the script's opening tag), you shouldn't encounter any problems.
If you want to make sure the operation succeeds, wrap the code in a try...catch block and call it again via setTimeout() on failure.
In Viajeros.com I have a loading indicator working since 8-9 months and I have no problems so far. It looks like this:
<body>
<script type="text/javascript">
try {
document.write('<div id="cargando"><p>Cargando...<\/p><\/div>');
document.getElementById("cargando").style.display = "block";
} catch(E) {};
</script>
Accessing the DOM prematurely throws exceptions in IE 5 and Navigator 4.
I've been making a concerted effort to improve my javascript skills lately by reading as much javascript code as I can. In doing this I've sometimes seen the javascript: prefix appended to the front of event handler attributes in HTML element tags. What's the purpose of this prefix? Basically, is there any appreciable difference between:
onchange="javascript: myFunction(this)"
and
onchange="myFunction(this)"
?
Probably nothing in your example. My understanding is that javascript: is for anchor tags (in place of an actual href). You'd use it so that your script can execute when the user clicks the link, but without initiating a navigation back to the page (which a blank href coupled with an onclick will do).
For example:
Blah
Rather than:
Blah
It should not be used in event handlers (though most browsers work defensively, and will not punish you). I would also argue that it should not be used in the href attribute of an anchor. If a browser supports javascript, it will use the properly defined event handler. If a browser does not, a javascript: link will appear broken. IMO, it is better to point them to a page explaining that they need to enable javascript to use that functionality, or better yet a non-javascript required version of the functionality. So, something like:
Ajax me
Edit: Thought of a good reason to use javascript:. Bookmarklets. For instance, this one sends you to google reader to view the rss feeds for a page:
var b=document.body;
if(b&&!document.xmlVersion){
void(z=document.createElement('script'));
void(z.src='http://www.google.com/reader/ui/subscribe-bookmarklet.js');
void(b.appendChild(z));
}else{
location='http://www.google.com/reader/view/feed/'+encodeURIComponent(location.href)
}
To have a user easily add this Bookmarklet, you would format it like so:
Drag this to your bookmarks, or right click and bookmark it!
It should only be used in the href tag.
That's ridiculous.
The accepted way is this:
Blah
But to answer the OP, there is generally no reason to use javascript: anymore. In fact, you should attach the javascript event from your script, and not inline in the markup. But, that's a purist thing I think :-D
The origins of javascript: in an event handler is actually just an IE specific thing so that you can specify the language in addition to the handler. This is because vbscript is also a supported client side scripting language in IE. Here's an example of "vbscript:".
In other browsers (as has been said by Shadow2531) javascript: is just a label and is basically ignored.
href="javascript:..." can be used in links to execute javascript code as DannySmurf points out.
javascript: in JS code (like in an onclick attribute) is just a label for use with continue/goto label statements that may or may not be supported by the browser (probably not anywhere). It could be zipzambam: instead. Even if the label can't be used, browsers still accept it so it doesn't cause an error.
This means that if someone's throwing a useless label in an onclick attribute, they probably don't know what they're doing and are just copying and pasting or doing it out of habit from doing the below.
javascript: in the href attribute signifies a Javascript URI.
Example:
javascript:(function()%7Balert(%22test%22)%3B%7D)()%3B
I am no authority in JavaScript, and perhaps more of a dunce than the asker, but AFAIK, the difference is that the javascript: prefix is preferred/required in URI-contexts, where the argument may be as well a traditional HTTP URL as a JavaScript trigger.
So, my intuitive answer would be that, since onChange expects JavaScript, the javascript: prefix is redundant (if not downright erroneous). You can, however, write javascript:myFunction(this) in your address bar, and that function is run. Without the javascript:, your browser would try to interpret myFunction(this) as a URL and tries to fetch the DNS info, browse to that server, etc...
#mercutio
That's ridiculous.
No, it's not ridiculous, javascript: is a pseudo protocol that can indeed only be used as the subject of a link, so he's quite right. Your suggestion is indeed better, but the best way of all is to use unobtrusive javascript techniques to iterate over HTML elements and add behaviour programmatically, as used in libraries like jQuery.
Basically, is there any appreciable difference between: onchange="javascript: myFunction(this)" and onchange="myFunction(this)" ?
Assuming you meant href="javascript: myFunction(this)", yes there is, especially when loading content using the javascript. Using the javascript: pseudo protocol makes the content inaccessible to some humans and all search engines, whereas using a real href and then changing the behaviour of the link using javascript makes the content accessible if javascript is turned off or not available in the particular client.
Flubba:
Use of javascript: in HREF breaks "Open in New Window" and "Open in New Tab" in a Firefox and other browsers.
It isn't "wrong", but if you want to make your site hard to navigate...
I don't know if the javascript: prefix means anything within the onevent attributes but I know they are annoying in anchor tags when trying to open the link in a new tab. The href should be used as a fall back and never to attach javascript to links.
I have a javascript function that manipulates the DOM when it is called (adds CSS classes, etc). This is invoked when the user changes some values in a form. When the document is first loading, I want to invoke this function to prepare the initial state (which is simpler in this case than setting up the DOM from the server side to the correct initial state).
Is it better to use window.onload to do this functionality or have a script block after the DOM elements I need to modify? For either case, why is it better?
For example:
function updateDOM(id) {
// updates the id element based on form state
}
should I invoke it via:
window.onload = function() { updateDOM("myElement"); };
or:
<div id="myElement">...</div>
<script language="javascript">
updateDOM("myElement");
</script>
The former seems to be the standard way to do it, but the latter seems to be just as good, perhaps better since it will update the element as soon as the script is hit, and as long as it is placed after the element, I don't see a problem with it.
Any thoughts? Is one version really better than the other?
The onload event is considered the proper way to do it, but if you don't mind using a javascript library, jQuery's $(document).ready() is even better.
$(document).ready(function(){
// manipulate the DOM all you want here
});
The advantages are:
Call $(document).ready() as many times as you want to register additional code to run - you can only set window.onload once.
$(document).ready() actions happen as soon as the DOM is complete - window.onload has to wait for images and such.
I hope I'm not becoming The Guy Who Suggests jQuery On Every JavaScript Question, but it really is great.
I've written lots of Javascript and window.onload is a terrible way to do it. It is brittle and waits until every asset of the page has loaded. So if one image takes forever or a resource doesn't timeout until 30 seconds, your code will not run before the user can see/manipulate the page.
Also, if another piece of Javascript decides to use window.onload = function() {}, your code will be blown away.
The proper way to run your code when the page is ready is wait for the element you need to change is ready/available. Many JS libraries have this as built-in functionality.
Check out:
http://docs.jquery.com/Events/ready#fn
http://developer.yahoo.com/yui/event/#onavailable
Definitely use onload. Keep your scripts separate from your page, or you'll go mad trying to disentangle them later.
Some JavaScript frameworks, such as mootools, give you access to a special event named "domready":
Contains the window Event 'domready', which will execute when the DOM has loaded. To ensure that DOM elements exist when the code attempting to access them is executed, they should be placed within the 'domready' event.
window.addEvent('domready', function() {
alert("The DOM is ready.");
});
window.onload on IE waits for the binary information to load also. It isn't a strict definition of "when the DOM is loaded". So there can be significant lag between when the page is perceived to be loaded and when your script gets fired. Because of this I would recommend looking into one of the plentiful JS frameworks (prototype/jQuery) to handle the heavy lifting for you.
#The Geek
I'm pretty sure that window.onload will be called again when a user hits the back button in IE, but doesn't get called again in Firefox. (Unless they changed it recently).
In Firefox, onload is called when the DOM has finished loading regardless of how you navigated to a page.
While I agree with the others about using window.onload if possible for clean code, I'm pretty sure that window.onload will be called again when a user hits the back button in IE, but doesn't get called again in Firefox. (Unless they changed it recently).
Edit: I could have that backwards.
In some cases, it's necessary to use inline script when you want your script to be evaluated when the user hits the back button from another page, back to your page.
Any corrections or additions to this answer are welcome... I'm not a javascript expert.
My take is the former becauase you can only have 1 window.onload function, while inline script blocks you have an n number.
onLoad because it is far easier to tell what code runs when the page loads up than having to read down through scads of html looking for script tags that might execute.