Citation Type. Has PDF. Publication Type. More Filters. Design and implementation of an ahead-of-time compiler for PHP. View 1 excerpt, cites methods. Applying best practices in web site redesign: the Queens College Libraries experience. OCLC Syst. A user using a Web application generates HTTP traffic which can be captured and logged to be used for further analysis such as finding potential security holes.
This document provides a method to … Expand. View 1 excerpt, cites background. Information dissemination is essential for every organization that needs to increase its visibility.
Show and hide more. Table of contents Product information. Is the JavaScript unobtrusive? Chapter 7: Creating Markup on the Fly document. Chapter Animated Slideshow What is animation? Practical animation Refining the animation Final touches What's next?
Also, DOM Level 1 is more portable. While the older methods deal specifically with web documents, DOM methods can be used on any markup. Save the function in a text file with the extension. You can call the file anything you want, but I like to name them after the functions they contain.
I would call the file showPic. Create a directory called scripts and save the showPic. Now I need to point the image gallery document to the JavaScript file. As it stands, the function will never be invoked.
I need to add the behavior to the links in my list. Event handlers Event handlers are used to invoke some JavaScript when a certain action happens.
If you want some behavior to be triggered when the user moves their cursor over an element, you use the onmouseover event handler. For my image gallery, I want to add a behavior when the user clicks on a link. The event han- dler for this is onclick. When I place the onclick event handler in a link, I want to send that link to the showPic function as the argument.
You can put as many JavaScript statements as you like between the quotes, as long as they are separated with semicolons. The function will be invoked, but the default behavior for clicking on a link will also be invoked. I need to stop the default behavior from being invoked.
Let me explain a bit more about how event handling works. When you attach an event handler to an element, you can trigger JavaScript statements with the event. The JavaScript can return a result that is then passed back to the event handler. For example, you can attach some JavaScript to the onclick event of a link so that it returns a Boolean value of true or false. It was the basis for all those rollover scripts that have proven so popular.
Every link in my list has a title attribute. To do that, I need to introduce some new DOM properties. We can use getElementsByTagName to get at the body element. Firstly, you can find out exactly how many children the body element has. Add this line to the end of the code: window.
You will be greeted with an alert dialog containing the total number of children of the body element. The result may surprise you. Introducing the nodeType property Looking at the structure of the gallery. Yet, when we invoke the countBodyChildren function, we get a much higher figure. This is because elements are just one type of node. The childNodes property returns an array containing all types of nodes, not just element nodes.
It will bring back all the attribute nodes and text nodes as well. In fact, just about everything in a document is some kind of node. Even spaces and line breaks are inter- preted as nodes and are included in the childNodes array. That explains why the result produced by countBodyChildren is so high. Fortunately, we can use the nodeType property on any node in a document.
The nodeType property is called like this: node. Element nodes have a nodeType value of 1. Their nodeType values are 1, 2, and 3 respectively. Attribute nodes have a nodeType value of 2. Text nodes have a nodeType value of 3. This means that you can target specific types of nodes in your functions. For instance, you could create a function that only affects element nodes. Adding a description in the markup To improve the image gallery function, I want to manipulate a text node.
I want to replace its value with a value taken from an attribute node the title attribute in a link. First, I need to have somewhere to put the text. To achieve this, I need to update the showPic function. Introducing the nodeValue property If you want to change the value of a text node, there is a DOM property called nodeValue that can be used to get and set the value of a node: node. You can test this with an alert statement: alert description. The nodeValue of the paragraph element itself is empty.
What you actually want is the value of the text within the paragraph. The text within the paragraph is a different node. This text is the first child node of the paragraph. Therefore, you want to retrieve the nodeValue of this child node. Introducing firstChild and lastChild There is a shorthand way of writing childNodes[0].
Whenever you want to get the value of the first node in the childNodes array, you can use firstChild: node. The Document Object Model also provides a corresponding lastChild property: node. If you wanted to access this node without using the lastChild property, you would have to write node. In the case of the description paragraph, only one child node exists. I can use either description. The nodeValue method is very versatile. It can be used to retrieve the value of a node, but it can also be used to set the value of a node.
Update the value of the first child node of the description object with the value of text. Clicking on a link to an image now produces two results. All of my images are there, too, but if you want to have some fun with this script, try using your own pictures. On the surface, this JavaScript image gallery probably appears to be a complete success. Unobtrusive JavaScript: separating structure from behavior. Right from its inception, seasoned program- mers treated it with skepticism.
The convoluted origin of the name JavaScript certainly did not help see Chapter 1. With a name like JavaScript, it was inevitably compared to the Java programming language and found lacking. Programmers who were expecting to find the power of Java were disappointed by the sim- plicity of the first iterations of JavaScript. Despite a superficial lexical similarity, JavaScript was a much simpler language.
Most importantly, where Java is very object-oriented, JavaScript was usually written in a procedural way. JavaScript can also be used in an object-oriented fashion, but the stigma remains.
Designers who made quick progress in learning HTML would have been brought up short by objects, functions, arrays, variables, and the other building blocks of JavaScript. The fact that programmers were insisting that JavaScript was laughably simple probably increased the frustration felt by web designers trying to grapple with the language. Nonetheless, the fact that JavaScript was effectively the only way of adding real-time inter- activity in web pages ensured that it would be widely adopted.
Unfortunately, in many cases, the way that JavaScript was implemented only served to increase the scorn and resentment designers and programmers felt for the language. A technology that people can use speedily and easily will probably be adopted very quickly.
However, there is likely to be a correspondingly low level of quality control. Anybody can learn the basics of HTML in a short space of time and create a web page very quickly. Browser manufacturers have to accept this state of affairs by making their software very forgiving and unfussy. Much of the code in browser software is dedicated to handling ambiguous use of HTML and trying to second-guess how authors want their web pages to be rendered. In practice, only a small frac- tion of those documents are made of well-formed, valid markup.
Nonetheless, there is a lot of very bad JavaScript out there on the Web. Many web designers wanted to reap the benefits of using JavaScript for adding spice to their web pages without spending the time to learn the language.
Many websites and books appeared offering self-contained functions that could be easily added to web pages. Cutting and pasting was the order of the day.
On the surface, they accomplished their tasks and added extra interactivity to web pages. In most cases, how- ever, little thought was given to how these pages behaved when JavaScript was disabled. Poorly implemented scripts sometimes had the effect of inadvertently making JavaScript a requirement for navigating a website. From an accessibility viewpoint, this was clearly a problem.
There are just bad uses of a technology. Many people today associate Flash with annoying splash pages, overlong download times, and unintuitive navigation.
None of these things are intrinsic to Flash. One of the great strengths of Flash is its ability to create light, compressed vector images and movies.
But once it became the norm for Flash sites to have bloated splash intro movies, the trend was hard to reverse. Similarly, JavaScript can and should be used to make web pages more usable. Yet it has a reputation for decreasing the usability and accessibility of websites. The problem is one of both inertia and momentum. If a technology is used in a thought- less way from very early on and that technology is then quickly adopted, it becomes very hard to change those initial bad habits.
Nobody stopped to ask why it was necessary. JavaScript suffered a similar fate. The code has been copied and pasted. The functions have spread far and wide across the Web, but nobody has ever ques- tioned whether they could have been better. Question everything Whenever you use JavaScript to alter the behavior of your web pages, you should question your decisions. First and foremost, you should question whether the extra behavior is really necessary.
JavaScript has been misused in the past to add all sorts of pointless bells and whistles to websites. You can use scripts that move the position of the browser window or even cause the browser window to shake. Most notoriously of all, there are scripts that cause ad-containing pop-up windows to appear when a page loads. The really nefarious scripts cause these newly spawned win- dows to appear under the current browser window. Some people dealt with the problem by disabling JavaScript entirely.
The browser manufacturers themselves took steps to deal with the problem by offering built-in pop-up blockers. Pop-under windows are the epitome of JavaScript abuse. Ostensibly, they are supposed to solve a problem: how to deliver advertising to users. In practice, they only increase user frustration. The onus was on the user to close these windows, something that often turned into an unhappy game of whack-a-mole.
User-centric web design is on the increase. Any other approach is, in the long term, doomed to failure. Or maybe the browser supports JavaScript but it has been disabled perhaps after being exposed to one too many pop-under windows. This is called graceful degradation.
This can be quite a useful feature. Many e-commerce websites will have links to terms of service or delivery rates from within the checkout process. Rather than having the user leave the current screen, a pop-up window can display the relevant information without interrupting the shopping experience. JavaScript uses the open method of the window object to create new browser windows. The method takes three arguments: window. The first argument is the URL for the document you want to open in a new window.
If this is missing, an empty browser window will be created. The second argument is the name that you can give this newly created window.
You can use this name in your code to communicate with your newly created window. The final argument accepted by the method is a comma-separated list of features that you want your new window to have. These include the size of the window width and height and aspects of the browser chrome that you want to enable or disable including toolbars, menu bar, location, and so on. The method is purely concerned with the browsing environment in this case, the window object. What matters is how I use it.
Real protocols are used to send packets of information between computers on the Internet. A pseudo-protocol is a non-standard take on this idea. The javascript: pseudo-protocol is supposed to be used to invoke JavaScript from within a link. Older browsers, however, will attempt to follow the link and fail. Even in browsers that understand the pseudo-protocol, the link becomes useless if JavaScript has been disabled.
In short, using the javascript: pseudo-protocol is usually a very bad way of referencing JavaScript from within your markup. The same technique will work for the popUp function.
If you use an onclick event handler from within a link to spawn a new window, then the href attribute might seem irrelevant. In some browsers, this will simply lead to the top of the current document. The real work is done by the onclick attribute. This technique is just as bad as using the javascript: pseudo-protocol. If JavaScript is disabled, the link is useless. Who cares?
Is it really worth making sure that your site works for this kind of user? Imagine a visitor to your website who browses the Web with both images and JavaScript disabled. But this visitor is important. All the major search engines have programs like this. Right now, very few searchbots understand JavaScript.
The word this can be used to refer to the current element. This is a classic example of graceful degradation. The most obvious problem is the need to insert JavaScript into the markup whenever you want to open a window. It would be far better if all the JavaScript, including the event handlers, were contained in an external file. The lessons of CSS Earlier I referred to both JavaScript and Flash as examples of technologies that were often implemented badly in the wild, anarchic days when they were first unleashed.
We can learn a lot from the mistakes of the past. There are other technologies that were implemented in a thoughtful, considered manner right from their inception. We can learn even more from these. Cascading Style Sheets are a wonderful technology. The great advantage of CSS is that you can separate the structure of a web document the markup from the design the CSS.
You could just add style attrib- utes in almost every element of your web document, for example. But the real benefits of CSS become apparent when all your styles are contained in external files. Perhaps as a result of the trauma caused by badly implemented Flash and JavaScript, web designers used CSS in a thoughtful, constructive way from day one. The separation of structure and style makes life easier for everyone.
If your job is writing content, you no longer have to worry about messing up the design. If your job is creating the design for a site, you can now concen- trate on controlling colors, fonts, and positioning using external style sheets without touching the content. A great advantage of this separation of structure and style is that it guarantees graceful degradation. Browsers that are capable of interpreting CSS will display the web pages in all their styled glory. Older browsers, or browsers with CSS disabled, will still be able to view the content of the pages, in a correctly structured way.
Marking up content correctly is the first and perhaps the most important step in creating a website. Once the content has been marked up, you can dictate how the content should look by using CSS. The instructions in the CSS form a presentation layer. This layer can then be draped over the structure of the markup.
Applying layers of extra information like this is called progressive enhancement. Web pages that are built using progressive enhancement will almost certainly degrade gracefully.
Where CSS contain information about presentation, JavaScript code contains information about behavior. Ideally, this behavior layer should be applied in the same way as the presentation layer. CSS work best when they are contained in external files, separate from the markup. Imagine you had a hun- dred documents with the warning class peppered throughout. Now suppose you wanted to change how warnings are displayed.
What works for the presentation layer will also work for the behavior layer. The functions that do all the work are contained in external files. The problem lies with inline event handlers. Using an attribute like onclick in the markup is just as inefficient as using the style attribute. It would be much better if we could use a hook, like class or id, to tether the behavior to the markup without intermingling it.
You can attach an event to an element in an external JavaScript file: element. The tricky part is figuring out which elements should have the event attached. Make an array of all the links in the document. Loop through this array. This is unobtrusive JavaScript. Because the document is incomplete, the model of the document is also incomplete.
I need to execute the code once the document has finished loading. Fortunately, the com- plete loading of a document is an event with a corresponding event handler.
The document loads within the browser window. The document object is a property of the window object. When the onload event is triggered by the window object, the document object then exists. This way I know that the Document Object Model will be working: window. However, there are degrees of JavaScript support. Most browsers support JavaScript to some degree, and most modern browsers have excel- lent support for the Document Object Model.
Older browsers, however, might not be able to understand DOM methods and properties. So even if a user visits your site with a browser that supports some JavaScript, some of your scripts may not work. The simplest solution to this problem is to quiz the browser on its level of JavaScript sup- port. If you wrap a method in an if statement, the statement will evaluate to either true or false, depending on whether the method exists. This is called object detection. Methods, like almost everything else in JavaScript, can be treated as objects.
Seeing as the function is ending pre- maturely, it makes sense that the Boolean value being returned is false. This is how it would look in a test for getElementById: if! It uses getElementsByTagName, so I want to be sure that the browser under- stands that method: window. This is assuring backwards compatibility.
There is another technique that was very popular during the dark days of the browser wars. Browser sniffing involves extracting information provided by the browser vendor. In the- ory, browsers supply information readable by JavaScript about their make and model.
For one thing, the browsers sometimes lie. For historical reasons, some browsers report themselves as being a different user-agent. Other browsers allow the user to change this information at will. As the number of different browsers being used increases, browser-sniffing scripts become more and more complex. They need to test for all possible combinations of vendor and version number in order to ensure that they work cross-platform.
This is a Sisyphean task that can result in extremely convoluted and messy code. If a new version is released, these scripts will need to be updated. Thankfully, the practice of browser sniffing is being replaced with the simpler and more robust technique of object detection. In Chapter 5, we talked about good coding practices.
The answers to these questions can affect the usability and accessibility of your web pages. A quick recap In Chapter 4, I put together a script for switching out the src attribute of an image, effec- tively making a single-page image gallery. Does it degrade gracefully? If JavaScript is disabled, the user can still view all the images in the gallery. The user sees the image as a new page instead of simply changing part of the existing page.
It would be a very different story if I had chosen to use the javascript: pseudo-protocol. The image gallery passes the first test. Is the JavaScript unobtrusive?
In this case, the answer is a resounding no. There are a few different ways I could do this. Adding a class to each link is almost as cumbersome as adding inline event handlers. All the links have one thing in common.
They are contained within a list. Adding the event handler Now I need to write a short little function to attach the behavior for the onclick event. Check whether this browser understands getElementById. Set the onclick event so that when the link is clicked: The link is passed to the showPic function. You might prefer to put the return statement on its own line: if!
Whether you do these tests on single or multiple lines is entirely up to you. Use whichever one you find easiest to follow. But that could change in the future. It all comes back to the importance of the separa- tion of content from behavior.
One of its doctrines states that functions should have a single point of entry and a single exit point. I am violating this principle by having multiple return false statements at the beginning of my function. These are all exit points. According to a principle of structured program- ming, there should only ever be one exit point. In theory, I agree with this principle. In practice, it could make code very difficult to read. Instead of writing out document. There are some words that are reserved by JavaScript.
Avoid using words like alert, var, and if. Because I now have the variable gallery at my disposal, I can simply write this: gallery. I have put safety checks in place, and I have assigned variables. Looping the loop I want to loop through all the individual elements in the links set. The loop will be executed for each element in links, and the counter will be incremented by one. Using the name i for incrementing variables is a programming convention in many languages.
The length property contains the total number of elements in an array. So, if links contains four elements, then the loop will be executed as long as i is less than four. As soon as its value is no longer less than links. If links contains four elements, the loop will stop once the value of i equals four. The loop will have run four times. Remember that i began with a value of zero.
Actually, it would be more correct to refer to links as a node list rather than an array. It is a set of nodes. Each node in the set has its own properties and methods. This is how I attach a behavior for that method: links[i]. It is a way of creating a function on the fly. In this case, the function is created when the onclick event handler is triggered, Whatever state- 6 ments I put in next will be executed when the link is clicked.
The value of links[i] will change as the value of i increases. It begins as links[0] and, if there are four elements in the links set, it will finish as links[3]. It refers to the element that is currently having the onclick method attached to it. I need to cancel the default behavior. This is how it looks: links[i]. Share the load I need to execute the prepareGallery function in order to attach the onclick events. If the JavaScript is executed before the document has finished loading, the Document Object Model will be incom- plete.
I want to execute the function only when the page has finished loading. When the page loads, an event is triggered. This event is onload and it is attached to the window object. If I attach the prepareGallery function to this event, then everything will go smoothly: window.
What if I want to exe- cute both of them when the page loads? If I attach them, one after the other, to the onload event, only the last specified function will actually be executed: window. On the face of it, you would think that an event handler can hold only one instruction. It takes a single argument: the name of the function that you want to execute when the page loads.
If there is already a function attached, add the new function after the existing instructions. No matter how many individual functions I want to execute when the page loads, I just need to add a single line for each one. For the prepareGallery function, this might be overkill. After all, only one function needs to be executed when the page loads. The showPic function is being called from prepareGallery.
Two things are happening in this function. The first action is the real task of the function. The second action is a nice added extra. The script no longer assumes the existence of elements in the markup. In this situation, it would be better to follow the link in the browser than have nothing happen at all. The problem lies with the prepareGallery function. It makes the assumption that the showPic function will work fine, and it cancels the default action: links[i]. If the function is unsuccessful, I want it to return true.
To do this, I just need to change my first test. If showPic returns true, the link will be followed by the browser. They may have grown in size, but they now assume much less about the markup. I can still see some assumptions being made in the showPic function that I may need to tackle. It will return a value of false if there is no title attribute, because the value of whichpic. I can save some space by simply writing: if whichpic.
As a simple fallback, I could set the value of text to be empty if there is no title attribute: if whichpic. This is called a ternary operator. Two possible values for the variable text are provided after the question mark. The first value will be assigned if getAttribute "title" returns a value. If I wanted to be really thorough, I could introduce checks for just about everything. I could run a further check, using the nodeName property, to verify this: if placeholder.
There are further checks I could introduce. I can use the nodeType property for this test. If you recall, text nodes have a nodeType value of 3: if description.
They are intended to account for situations where the markup might be beyond your control. That said, these kinds of decisions need to be made on a case-by-case basis. Keyboard access There is one last piece of fine-tuning that often arises with any scripts that are attached to the onclick event handler.
When the link is clicked, the showPic function is executed. But remember, not everybody navigates using a mouse. Instead, they are likely to navigate using a keyboard.
You can use the TAB key on your keyboard to move from link to link. There is an event handler specifically for the action of pressing any key on the keyboard. It is called onkeypress. If I want to execute the same behavior for onkeypress as onclick, I could simply duplicate the instructions: links[i].
By keeping all your functions and event handlers in external files, you can change them without tinkering with the markup. You can always revisit your scripts and refine them, knowing that those refinements will automatically be applied to every web page that ref- erences the JavaScript file. If I were still using inline event handlers, I would have needed to make a lot of changes to my markup as the JavaScript functionality changed.
Suppose I wanted to add the onkeypress event handler. This event handler is quite problematic. It is triggered whenever a key is pressed. In some browsers, that includes the TAB key! That means that a user navigating with a keyboard can never tab past a link if a function associated with onkeypress returns false.
0コメント