I have been working on code to calculate shipping costs. I had the code working in HTML but realized that it needed to be in XHTML 1.0 Strict. Knowing that it worked I started working on the validation errors. I now have it error free but the code stopped outputting the Total Cost. Where am I going wrong here?
updated code
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title> "Calculate Shipping" </title>
<script type="text/javascript">
// <![CDATA[
function calculateShipping() }
var price = parseFloat(document.getElementById('price').value);
//This will add $1.50 to any purchases that are less than or equal
to $25.00.
if (price <= 25){
price = (price) + 1.5;
} else {
//return price * 10 / 100
var percentToAdd=(price) * .1;
price=(price)+(percentToAdd);
}
document.getElementById('result').innerHTML='Total Order Cost:
'+price;
// ]]>
</script>
</head>
<body>
<h1>Enter Purchase Price</h1>
<form action="#">
<div id="result">
<input type="text" name="price" id="price" />
<input type="button" value="Submit" onclick=calculateShipping(); return
false;" />
</div>
</form>
</body>
</html>
The browser might be trying to evaluate those CDATA declarations as Javascript (remember that most browsers will parse the XHTML as if it were HTML). Try putting them inside Javascript comments.
<script type="text/javascript">
// <![CDATA[
// ]]>
</script>
Another possibility is putting the Javascript in a separate file instead of trying to embed it into the document
<script type="text/javascript" src="shipping.js"></script>
Finally, you might want to check out this similar question: When is a CDATA section necessary within a script tag?
You are missing a final closing }
also use comments on your CDATA statements or remove them (as missingno sez).
Here's what's wrong:
You're missing a closing } on your function;
You're performing a lower-than operation on a string. That's just a really bad habit.
Your CDATA tag may be interpreted as JavaScript.
Instead of using parseFloat in all the wrong places, just put the parseFloat around your variable definition:
var price = parseFloat(document.getElementById('price').value);
Also, make sure you close your brackets. Just put a } on the last line, in this case, and your function will be closed correctly
Finally, you should really put a double slash before each of the CDATA parts. Like missingno said:
<script type="text/javascript">
// <![CDATA[
// ]]>
</script>
Comment it out by using single line comments.
PS: try just using HTML5, with this doctype:
<!DOCTYPE html>
Also, you should make sure all your quotes are closed. If you are running this through a debugger and it is giving you no errors, you should really use a better debugger. I've fixed your code and put it in a jsbin, you can see it here. Try putting your code in there next time. I'm sure it'll give you all the errors you're getting.
PS: you might not be getting errors because your "js error debugger" only checks .js files, and you've made your script an inline script. Try putting just the JS code in the debugger next time.
Related
I am trying to get a very simple javascript project going, but I cannot get any function to execute. Here is a simple example. It is obviously just an example. I have tried everything I can think of to get the browser to recognize that I am trying to call a function that has been defined, but it never does anything but just display the text, rather than call anything. In the below example, I simply get a page with the text: "varTimesTwo(3);"
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
</script>
varTimesTwo(3);
</body>
</html>
your code is wrong, you have to place varTimesTwo(3); inside the script tag, like this:
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
varTimesTwo(3);
</script>
</body>
</html>
Keep all JavaScript code in the script tags, or better yet, in a file
separate from the html file using <script src="myjsfile.js"></script>
You can use document.write(string) to write a string to the document.
This string is treated as HTML so you need to use <p>text</p> or <br> to get line breaks.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
document.write("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
Alternatively, you can use window.alert(string) or simply alert(string) to pop up an alert box. But if you have turned off pop-ups in the browser, these will not pop up.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
alert("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
console.log(string) writes to the debugging console, which you can see on many browsers with either control-shift-J or F12.
The javascript debugging console is also useful for learning javascript without messing with input and output. Anything you type in the JS console is immediately executed, so you can define functions there and play with them without having to write additional code to write the output or read input.
Finally, these techniques are insufficient for most websites as they are actually used. Instead, what is done is to define an html container element and change the text or html that is inside. jQuery provides a browser-independent method of manipulating the document to change items on the page.
I have been playing around with Scala/Lift/Comet/Ajax etc. recently. I came across a problem which boils down to this:
Summary
I want to update a specific div (by id) when a certain event occurs. If the div does not exist yet, it must be created and appended to the HTML body.
Currently I cannot get this to work when using the Lift framework.
Source File
LIFT_PROJECT/src/main/webapp/static/mouseViewTest.html:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
// <![CDATA[
$(document).ready(function() {
updateOrCreateMouseDiv('123', 'coords')
});
function updateOrCreateMouseDiv(uniqueId, coords) {
if ($('#mouse_'+uniqueId).length == 0) {
$('body').append('<div id=' + uniqueId + '>' + coords + '</div>');
}
$('#mouse_'+uniqueId).html(coords)
}
// ]]>
</script>
</head>
<body></body>
</html>
The Error
If I open the above file directly in a browser (file:///LIFT_PROJECT/src/main/webapp/static/mouseViewTest.html) it works i.e. a new div is created.
But if I run it through Lift/Jetty (http://localhost:8080/static/mouseViewTest) I get the following JavaScript error:
Chrome:
Uncaught Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7
Firefox (Firebug):
An invalid or illegal string was specified" code: "12
Comparing the Sources in Browser
When comparing the page sources in the browser, I can see only one difference, namely: Lift adds the following JavaScript just before the closing </body> tag:
<script type="text/javascript" src="/ajax_request/liftAjax.js"></script>
<script type="text/javascript">
// <![CDATA[
var lift_page = "F320717045475W3A";
// ]]>
</script>
Questions
Does anyone have an idea why this happens?
If I would want to move the JavaScript code into the Scala file (using Lift's JavaScript and jQuery support), what would the code look like?
Please note: When I used Jq("body") ~> JqAppend() to create new divs, it worked. I just didn't know how to check whether the div id already existed. Thats why I moved the code into the template, planning on using Lift's Call function to execute the JS function. And thats when these problems started...
Thanks!
I recently ran into a similar problem and, from what I've gathered, the problem is because the page when served by lift is served as XHTML and there are some issues when writing to the DOM if the page is XHTML vs. HTML. I don't know whether this is a bug with jQuery or Safari or if it's just something that's not possible in XHTML, but a quick way to fix it is to modify your Boot.scala to tell Lift to not use XHTML as the mime type with this line:
LiftRules.useXhtmlMimeType = false
Okay - this is the dumbest glitch I have seen in a while:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>
var data = "</script>";
</script>
</head>
<body>
This should break!
</body>
</html>
This causes syntax errors because the JavaScript parser is actually reading the contents of the string. How stupid!
How can I put </script> in my code. Is there any way?
Is there a valid reason for this behavior?
Within X(HT)ML (when actually treated as such), scripts are required to be escaped as CDATA for precisely this reason. http://www.w3.org/TR/xhtml1/diffs.html#h-4.8
In XHTML, the script and style elements are declared as having #PCDATA content. As a result, < and & will be treated as the start of markup, and entities such as < and & will be recognized as entity references by the XML processor to < and & respectively. Wrapping the content of the script or style element within a CDATA marked section avoids the expansion of these entities.
<script type="text/javascript">
<![CDATA[
... unescaped script content ...
]]>
</script>
If your XHTML document is just served as text/html and treated as tag soup, that doesn't apply and you'll just have to "escape" the string like '</scr' + 'ipt>'.
It's not a glitch - this is normal expected behaviour and quite rightly so if you think about it. HTML specs do not define scripting languages, so all the engine should see is plain text up until </script>, which closes the tag. There are a couple of options, other than the ones already outlined:
// escape the / character, changing the format of the "closing" tag
var data = "<\/script>";
// break up the string
var data = "</"+"script>";
The first method works because HTML doesn't use \ for escaping, it's treated as a literal character, and of course <\/script> isn't a valid closing tag. The second one works for more obvious reasons, but I've been told by someone else here that it shouldn't be used (and I never quite understood why).
Write it this way:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>
<!--
var data = "</script>";
-->
</script>
</head>
<body>
This should break!
</body>
</html>
The reason is simply that HTML is parsed before executing javascript and the <!-- and --> make the parser ignore all tags that appear in this section.
If you can believe the HTML4 standard, the script content
ends at the first ETAGO ("</") delimiter followed by a name start character ([a-zA-Z])
So, the JavaScript parser is not reading the contents of the string as you describe; the JavaScript parser never gets anything after var data = ", which obviously isn't a valid script.
The simplest way to avoid accidentally ending your JavaScript early is to use Andy E's first suggestion:
var data = "<\/script>";
This way the HTML parser doesn't see </ so the script content doesn't end, and \/ is equivalent to / in a JavaScript string literal, so the results are correct. This is also the method shown for JavaScript in the standard.
Is there any way to fix the error that a JavaScript & causes in w3 validation? The problem is that i have to use && in a if statement and these two &&'s causes errors in w3 validation.
EDIT:
Same problem with "<" and ">".
There are a few things you can do.
You can enclose it within HTML comments:
<script type="text/javascript">
<!--
if (foo && bar) ...
//-->
</script>
You can enclose it in a CDATA section:
<script type="text/javascript">
// <![CDATA[
if (foo && bar) ...
// ]]>
</script>
You can include in in a file instead:
<script src="foobar.js" type="text/javascript"></script>
The primary answer is: Use JavaScript files for JavaScript, not HTML files, and use the src attribute of script tags. (Combine all your JS into one file, minimize, gzip, etc. for performance.)
But, you can embed JavaScript in HTML if absolutely necessary. Use a valid, modern DOCTYPE and you don't have to resort to comment tags and CDATA sections.
Valid HTML5 example:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Example</title>
<script type='text/javascript'>
function foo() {
var a = 1, b = 2;
if (a && b) {
alert("Both");
}
if (a < b) {
alert("a < b");
}
if (a > b) {
alert("a > b");
}
}
</script>
</head>
<body>
<p>Hi there</p>
</body>
</html>
That will also validate as HTML4 strict if you change the doctype to
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
Note that in both cases, you need to be careful about end tags in your script --
This causes the problem:
<script type='text/javascript'>
alert("</td>");
</script>
This solves the problem by prefacing the slash with a backslash (or you can break the end tag up into separate string literals):
<script type='text/javascript'>
alert("<\/td>");
// -or-
alert("<" + "/td>");
</script>
But again, the basic answer is: Don't embed JavaScript within HTML files when you can avoid it, use JavaScript files for that.
Based on your description, I suspect that you're talking about script that's inside an event property in an HTML tag (such as onclick). In that event, the script code needs to be HTML encoded. Elijah hit the nail on the head there.
For example:
<input type="submit" onclick="if(somevar && othervar) callFunc("clicked");">
You do not need to do that inside a <script></script> block.
Escape & with &, < with <, and > with >.
I read that you should define your JavaScript functions in the <head> tag, but how does the location of the <script> (whether in the <head>, <body>, or any other tag) affect a JavaScript function.
Specifically, how does it affect the scope of the function and where you can call it from?
Telling people to add <SCRIPT> only in the head sounds like a reasonable thing to do, but as others have said there are many reasons why this isn't recommended or even practical - mainly speed and the way that HTML pages are generated dynamically.
This is what the HTML 4 spec says :
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.
And some sample HTML. Doesn't it look pretty all formatted here :)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...some JavaScript...
</SCRIPT>
</BODY>
</HTML>
And something to look forward to in HTML 5 :
New async attribute in <SCRIPT> :
Note: There are ways [sic] a script can be
executed:
The async attribute is "true": The
script will be executed asynchrously
with the rest of the page, so the
script will be executed while the page
continues the parsing.
The async attribute is "false", but
the defer attribute is "true": The
script will be executed when the page
is finished with the parsing.
The normal rules of play still stand; don't use stuff before it's defined. :)
Also, take note that the 'put everything at the bottom' advice isn't the only rule in the book - in some cases it may not be feasible and in other cases it may make more sense to put the script elsewhere.
The main reason for putting a script at the bottom of a document is for performance, scripts, unlike other HTTP requests, do not load in parallel, meaning they'll slow down the loading of the rest of your page. Another reason for putting scripts at the bottom is so you don't have to use any 'DOM ready' functions. Since the script tag is below all elements the DOM will be ready for manipulation!
EDIT: Read this: http://developer.yahoo.com/performance/rules.html#js_bottom
One of the aspects of placement is performance. See this fine article within the YSlow discussion for why it's sometimes recommended you put them at the bottom of the document.
As for issues of scope, the usual visibility rules for Javascript (vars defined inside or outside of functions, local, global, closures, etc.) are not affected so far as I know.
Position of script tag does matter.
If you bind a Function with document Element then the document element has to be loaded first before we implement function. suppose getTeachers() is function in getTeachers.js file.
This will give you an error:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<span id="results" /></span>
</body>
</html>
It gives error before head is loaded first and it cannot find element with id specified.
The below code is correction:
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
<script type="text/javascript" src="getTeachers.js"></script>
</head>
<body>
<form>
<input type = "button" id="buttonId" value = "Press for Results" /><br />
</form>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};
</script>
<span id="results" /></span>
</body>
</html>
If your script refers to an ID on the page and the page has not been rendered (i.e. script is before HTML, or your script is executed with onload, rather then the DOM is ready) you can also get an error.
It doesn't. Most programming framework scatter scripts all throughout the page. I've only rarely seen problems because of that (and only from older browsers).
If you pull Javascripts in through XMLHttpRequest, like Diodeus said, it probably won't work. In my case, there was no error, the browser just ignores the new script(s).
I ended up using this, not terribly elegant but works for me so far:
http://zeta-puppis.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/
How to use execJS: http://zeta-puppis.com/2006/02/23/javascript-script-execution-in-innerhtml/
Note: Watch out for < in this line: for(var i=0;i<st.length; i++)
If you have an inline script (outside functions) located before functions it may call, you may get an error because they may not be not available yet. Not saying it is always going to happen, just that it may depending on browser type or version.
Javascript's scoping rules are similar to perl - you can call any function at the current or any higher scope level. The only restriction is that the function has to be defined at the time you call it. The position in the source is irrelevant - only the position in time matters.
You should avoid putting scripts in the <head> if possible as it slows down page display (see the link Alan posted).