Sriram Sriram - 5 months ago 10
HTML Question

Unable to run JavaScript from .xhtml file extension; works on .html

I am unable to run basic javascript functions like

alert
etc. from within an xhtml file. Please see the xhtml file below:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta content="text/html;charset=UTF-8" />
<title>My HTML</title>
</head>
<body>
<h1>MyHTML</h1>
<p id="mytext">Hello World! This is a test.</p>
<input type="button" value="Alert" onClick="displayAlert()" />
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<input type="button" value="Open Dialog" onClick="openAndroidDialog()" />
<input type="button" value="Add highlight" onClick="changeColor()" />

<script language="javascript">
function showAndroidToast(toast) {
JSInterface.showToast(toast);
}

function openAndroidDialog() {
JSInterface.openAndroidDialog();
}

function callFromActivity(msg) {
alert(msg);
var oldHTML = document.getElementById("mytext");
alert(oldHTML);
var newHTML = "<span style='color:#ff0000'>" + msg + "</span>";
alert(newHTML);
document.getElementById("mytext").innerHTML = newHTML;
}

function changeColor() {
var oldHTML = document.getElementById("mytext").innerHTML;
var newHTML = "<span style='color:#ff0000'>" + oldHTML + "</span>";
document.getElementById("mytext").innerHTML = newHTML;
}

function displayAlert() {
<![CDATA[
window.alert("I am here!");
]]>
}

</script>

</body>
</html>


None of the functions (like ChangeColor etc.) work when rendered on Chrome/Safari browser. Renaming the same file to
*.html
results in all the functions working. I have read a lot of material which has caused me to:

1. Try the
CDATA
tag and put everything in the function into it.

2. Change the mime-type to text/html.

All of this to no avail. Can anyone tell me why this is happening and how I can run javascript functions from within xhtml?

Answer

With .xhtml extension, Chrome (WebKit) will assume the media type as application/xhtml+xml. With .html, the media type is text/html.

Now application/xhtml+xml is a lot less flexible than text/html and your file has invalid markup. When processed as text/html, the browser plays nice. When the type is application/xhtml+xml, it's not so gentle.

To put it shortly, to work as .xhtml you have to make your file valid. There are a lot of mistakes in it (you may check them later here), the necessary are:

  • Change the <script language="javascript"> to <script type="text/javascript">.
  • Remove the <![CDATA[ and ]]> from displayAlert() and place them right after/before the script tags as comments (//):

    <script type="text/javascript">
    //<![CDATA[
    ...
    //]]>
    </script>
    
  • Finally, there are no onClick attributes for XHTML. They are onclick (all lowercase). So change them in your inputs.

  • Just so everything is valid, wrap the inputs in a div tag.

Final XHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta content="text/html;charset=UTF-8" />
<title>My HTML</title>
</head>
<body>
<h1>MyHTML</h1>
<p id="mytext">Hello World! This is a test.</p>
<div>
<input type="button" value="Alert" onclick="displayAlert()" />
<input type="button" value="Say hello" onclick="showAndroidToast('Hello Android!')" />
<input type="button" value="Open Dialog" onclick="openAndroidDialog()" />
<input type="button" value="Add highlight" onclick="changeColor()" />
</div>
<script type="text/javascript">
//<![CDATA[
   function showAndroidToast(toast) {
       JSInterface.showToast(toast);
   }

   function openAndroidDialog() {
       JSInterface.openAndroidDialog();
   }

   function callFromActivity(msg) {
        alert(msg);
        var oldHTML = document.getElementById("mytext");
        alert(oldHTML);
        var newHTML = "<span style='color:#ff0000'>" + msg + "</span>";
        alert(newHTML);
        document.getElementById("mytext").innerHTML = newHTML;
   }

   function changeColor() {
        var oldHTML = document.getElementById("mytext").innerHTML;
        var newHTML = "<span style='color:#ff0000'>" + oldHTML + "</span>";
        document.getElementById("mytext").innerHTML = newHTML;
   }

   function displayAlert() {

        window.alert("I am here!");

    }
//]]>
</script>

</body>
</html> 
Comments