Using JavaScript on the Client

Using JavaScript on the Client

The JavaScript language can be used independently of the browser. There are JavaScript interpreters for managing operating system components, interacting with COM objects, and automating server administration tasks. To use JavaScript in the browser, there are a few considerations you should be aware of. First, you need to manage getting the script to the browser for a page effectively. As the amount of JavaScript you use grows, you will want to make use of the browser’s ability to cache scripts. You will also need to be aware of how the user’s interaction with a page while background operations are performed will affect their perceived performance of a page. In some conditions you want them to know that they are waiting for an action to be performed so they don’t become frustrated, and in other cases you want to ensure that the page is responsive while something happens transparently in the background. JavaScript resources can also be embedded directly in a DLL and don’t have to be deployed as text files on disk as you might be accustomed to doing.

Getting JavaScript to the Browser

Before diving into the fundamentals of the language, you should understand how JavaScript code gets to the browser as part of a web application. The HTML script tag is used to separate the script code from the markup so the browser will be able to distinguish the difference. Listing 3-1 shows the two methods for including JavaScript in a page. In the first example, the script code is included directly in the page within an HTML script element. The second example (the last line) defines the script code in a separate file and uses the src attribute of the script element in the page to provide the URL that the browser should use to retrieve the code.

Listing 3-1
Image from book

<script type="text/javascript">
alert("greetings");
</script>

<script type="text/javascript" src="scripts/code.js" ></script>
Image from book

It used to be common to include language ="javascript" in the script tag as well, but the language attribute has been deprecated in the latest HTML standards, although it is still accepted by most browsers at the present time. Multiple script tags can be included in the HTML source so you can have many different sections of script code in a single page. Any code that is not defined within a script function will be executed immediately when the page loads. The W3C standard includes the defer attribute to instruct the browser that it need not delay rendering of the HTML while the script is downloaded or parsed. This can be useful when you know that a particular piece of script code won’t need to run until after the page has been completely rendered. Be aware, however, that users will start interacting with the page as soon as it is rendered. Users don’t like waiting for page loads, and they certainly aren’t watching the animated browser icon to see if the browser is still busy loading part of the page that they cannot see. Therefore, the defer attribute is not commonly used.

If you use defer and the user performs actions in a partially rendered page, the code that tries to execute something from a deferred script before it is has finished loading will generate errors for the user. This is baffling to users, and the only recovery action is to load the page again. The error message they get is usually something vague about a function or variable being undefined. They don’t have any way to know that the undefined something may not have loaded yet, so they may even repeat the same process and get the same error. The safest approach is to include script references earlier in the page whenever possible and avoid using deferred loading. This will make it more likely that the browser has your script code when the user starts interacting with the page. Of course, even this isn’t a guarantee. To protect yourself from errors caused by early user interaction with a page, you can include a top-level piece of code to disable elements that might depend on load order. This way, you can avoid triggering the use of code that is still being fetched. For example, you can disable a Submit button in an HTML form to prevent the user from clicking it and needing some associated validation scripts before they are available.

Perceived Performance

If you allow users to interact with a page before all the script code has been downloaded, it will appear to them that the page is ready to be used. By temporarily disabling the postback, you can ensure safety and also allow users to enter their data on the page while the scripts continue loading in the background.

In addition to the perceived performance advantage, some applications also temporarily disable elements of the form that cause a postback in order to avoid a complication with a security feature of ASP.NET. Some controls can be registered for validation, and ASP.NET will round-trip the set of valid values set for that control. The possible values are hashed (a cryptographic signature is calculated on them and later validated after postback) and round-tripped along with the values so that the server can detect any attempt by malicious code to submit something other than the valid list of values. Because the set of authentic values has to be collected while the page is being rendered and may not be fully assembled until after the form has been fully rendered, the hashed data is included after the closing form ele-ment. When a specific web form is fairly large or complex, the set of validation values can also be large, so it is possible for the user to interact with the form and submit it before the browser receives the validation data. The browser would then be unable to submit the set of valid values back to the server, and the user will see an error when the page is posted back on the server and the validation values are missing. So, to prevent this scenario, you can disable the postback until you’re sure that the browser has received all of the validation values.

In Listing 3-2 (from Enable.htm), the Submit button is disabled initially in the HTML markup. The script element contains a function to enable the Submit button along with a line of script for attaching the function to the window’s onload event. Thus, the button will be disabled initially and then enabled after the whole page has been loaded.

Listing 3-2
Image from book

<html xmlns=http://www.w3.org/1999/xhtml >
<head>
<title>Example</title>
</head>
<body>
<form action="enable.htm" id="theForm">
<script type="text/javascript">
function enableSubmit() {
    var elt = document.getElementById('submitButton');
    alert("enabling form now");
    elt.disabled = false;
}
window.onload = enableSubmit;
</script>
<input type="submit" id="submitButton" value="go" disabled="disabled"  />
</form>
</body>
</html>
Image from book

Notice that I only disabled the Submit button. My first inclination would be to disable the entire form and have everything in it disabled, but that would not be portable to all the browsers. In a real application with several elements that might cause a postback, you would have to initially disable all of them and then enable them during the onload event.

There isn’t a limit to the number of script tags allowed on a page, but browsers typically open only one or two channels back to the server for scripts and images, so it appears as though the page is loading slowly. You can improve the perceived performance of page loading by using several script tags to contain your JavaScript code so that the browser can download multiple scripts simultaneously. This may not complete the overall load any faster, but it can seem faster by allowing the user to start interacting with the page earlier.

Script Resources

One of the longstanding difficulties with the deployment of web applications to web servers is ensuring that the right versions of all the miscellaneous files are deployed. ASP.NET 2.0 added the ability to include JavaScript code as a text resource embedded in the compiled dll for an application. This allows you to create a web server control that includes the script files internally and can be deployed with only configuration entries and a single dll, ensuring that the correct script files will always be sent to the user and will not have to be maintained in a folder on the server! ASP.NET will then field requests for those script resources via its built-in Web Resource handler. If you view the source for just about any .aspx page, you will see references to WebResource.axd followed by querystring parameters used to retrieve the appropriate embedded resource. At first glance, it looks like a bunch of garbage, but if you extract one of those URL querystrings from a typical page’s source and paste it into your browser’s address window to request it separately, you will find that the proper resource is returned.

http://www.mysite.com/WebResource.axd?d=3843647524---
HJKAeoedaslathlmhueeuyr&amp;t=111205042031232968

The Web Resource handler is used for more than just JavaScript files; it can also be used for image files. Since the first version of ASP.NET did not have this functionality, some developers modified the standard ASP.NET JavaScript files themselves to obtain certain types of custom behaviors. To maintain functionality for those customizations when upgrading to the next release, ASP.NET will check for the existence of those external script files in an application and use them instead of the ones provided by Microsoft in System.Web.dll. However, this WebResource mechanism can still be used by your own web controls, regardless of whether it is used for the standard ASP.NET scripts used by all pages.