1. Trang chủ
  2. » Công Nghệ Thông Tin

DHTML Utopia Modern Web Design Using JavaScript & DOM- P10 pps

20 344 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 507,21 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

While typing “k,” “i,” “n” in a standard drop-down will result in a jump to the first list entry beginning with “k,” then the first beginning with “i,” then the first beginning with “n,”

Trang 1

ing country names Some have worked around the problem of locating particular countries in these long lists by putting the more frequently-selected countries at the top,13 but this is hardly an ideal solution

It is possible to press the key that corresponds with the initial letter of an entry

in the list in order to jump to that entry; repeatedly hitting that key will move between list entries that begin with that letter This suggests an improvement: perhaps instead of keypresses triggering initial-letter searches only, they should accumulate into a string, which is matched as a whole While typing “k,” “i,” “n”

in a standard drop-down will result in a jump to the first list entry beginning with “k,” then the first beginning with “i,” then the first beginning with “n,” this could be changed so that those keypresses jump the selection to the first entry containing the string “kin.” That would probably be the United Kingdom (or the Kingdom of Tonga!), in the countries example

Functionality very similar to this is actually already present in both Safari and

Firefox Both of those browsers let you type a series of letters to match the start

of an entry in a drop-down list This example takes this feature a step further by searching for the string anywhere in the list item And it works in Internet Explorer

to boot! Unfortunately, Safari does not support handling keyboard events on drop-down lists with JavaScript As a result, the enhancement we will undertake

in this section will not apply to that browser

A number of further enhancements also suggest themselves: the current accumu-lated string should be displayed somewhere so that the user can see what they’ve entered, similar to Firefox’s “type-ahead find” feature It should also be possible,

as with type-ahead find, to press Backspace to remove the most recently-added

letter from the accumulated string Finally, after a period without typing, the accumulated string should be reset to blank to allow typing from scratch Here’s an example HTML file containing the countries list:

File: typeahead.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

<title>Type-ahead drop-down lists</title>

<script type="text/javascript" src="typeahead.js"></script>

13

Sometimes, developers place just one country at the top—the United States—leaving UK residents such as myself, and other non-Americans, to scroll through the ridiculously long list Hmph (Australi-ans don’t mind—Ed.)

Chapter 6: Forms and Validation

Trang 2

</head>

<body>

<h1>Type-ahead drop-down lists</h1>

<form action="">

<p>

<select name="country">

<option value="AFG">Afghanistan</option>

<option value="ALB">Albania</option>

<option value="DZA">Algeria</option>

… <option value="ZAR">Zaire</option>

<option value="ZMB">Zambia</option>

<option value="ZWE">Zimbabwe</option>

</select>

</p>

</form>

</body>

</html>

The associated JavaScript should attach an event listener to each select element

in the document Browsers offer three events for handling pressed keys: keyup,

keydown, and keypress As we saw in Chapter 3, despite being the best-supported

of these properties, keypress is nonstandard, and a little limited In particular,

in some browsers it does not fire for “control” keys such as Backspace, which is

required by this script We’ll therefore use keydown for this script

In summary, we’ll create a library object as follows:

File: typeahead.js

var tADD = { addEvent: function(elm, evType, fn, useCapture) { … }, init: function() { … },

addKey: function(e) { … } }

tADD.addEvent(window, 'load', tADD.init, false);

This is mostly standard setup As only a single listener is required, we’ll put it all

in typeahead.js There’s nothing else in that file Here’s the init method:

File: typeahead.js (excerpt)

init: function() {

if (!document.getElementsByTagName) return;

var selects = document.getElementsByTagName('select');

for (var i = 0; i < selects.length; i++) { tADD.addEvent(selects[i], 'keydown', tADD.addKey, false);

Type-Ahead Drop-Down Lists

Trang 3

tADD.addEvent(selects[i], 'keypress',

function(e) { if (e) e.preventDefault(); }, false); }

},

This decorates all select elements with a keydown event listener and a keypress

event listener The keydown listener, addKey, will implement the type-ahead be-havior The keypress listener is in place for one reason only: the Firefox browser

will navigate to the previous page when the user types Backspace, even if the

keydown event listener calls preventDefault to cancel the event To prevent this, the keypress event must be cancelled by its own listener

Here’s the keydown event listener:

File: typeahead.js (excerpt)

addKey: function(e) {

var t = window.event ? window.event.srcElement : e ?

e.target : null;

if (!t) return;

if (e && e.which) {

var code = e.which;

} else if (e && e.keyCode) {

var code = e.keyCode;

} else if (window.event && window.event.keyCode) {

var code = window.event.keyCode;

} else {

return;

}

var character = String.fromCharCode(code).toLowerCase();

if (t.timeout_key)

clearTimeout(t.timeout_key);

if (!t.keyword)

t.keyword = '';

if (code == 8) {

if (t.keyword != '')

t.keyword = t.keyword.substr(0, t.keyword.length - 1); } else if (code >= 32) {

t.keyword += character;

}

if (t.keyword == '') {

Chapter 6: Forms and Validation

Trang 4

window.status = t.keyword = '';

} else { window.status = 'Searching: ' + t.keyword;

t.timeout_key = setTimeout(

function() { window.status = t.keyword = ''; }, 5000);

var gotoIndex = t.selectedIndex;

for (var i = 0; i < t.options.length; i++) {

if (t.options[i].text.toLowerCase().indexOf(t.keyword) != -1) {

gotoIndex = i;

break;

} } setTimeout(function() { t.selectedIndex = gotoIndex; }, 1); }

if (window.event) { window.event.cancelBubble = true;

window.event.returnValue = false;

} else if (e) { e.stopPropagation();

e.preventDefault();

} }

As described in Peter Paul Koch’s Event Properties summary14, the code of the pressed key is available from the keyCode or which properties of the event object (we get that object in the normal cross-browser way) Here’s the code that ensures that we have both an event object and a key at the end:

File: typeahead.js (excerpt)

var t = window.event ? window.event.srcElement : e ? e.target : null;

if (!t) return;

if (e && e.which) { var code = e.which } else if (e && e.keyCode) { var code = e.keyCode;

} else if (window.event && window.event.keyCode) { var code = window.event.keyCode;

14 http://www.quirksmode.org/

Type-Ahead Drop-Down Lists

Trang 5

} else {

return;

}

Next, we convert the supplied code into a lowercase character: the character is converted to lowercase because the search through the drop-down will be case-insensitive There are also serious browser issues with case-sensitive keystroke detection

File: typeahead.js (excerpt)

var character = String.fromCharCode(code).toLowerCase();

Below, setTimeout is used to implement the five-second string reset timer men-tioned; if a timer is currently running, we cancel it, because a key has just been pressed We don’t want the typed-in string cleared halfway through the user typing it, even if they are a bit slow

File: typeahead.js (excerpt)

if (t.timeout_key)

clearTimeout(t.timeout_key);

The accumulated string of characters will be stored in a property of the select

element named keyword This property is created by the code, using (again) JavaScript’s handy ability to attach arbitrary properties to objects If the property does not exist, it is created as an empty string:

File: typeahead.js (excerpt)

if (!t.keyword)

t.keyword = '';

The Backspace key has a keyCode of 8 If Backspace has been pressed, and some

letters have accumulated, we remove the last accumulated letter:

File: typeahead.js (excerpt)

if (code == 8) {

if (t.keyword != '')

t.keyword = t.keyword.substr(0, t.keyword.length - 1);

If a key other than Backspace was pressed, then we add the corresponding

character to the accumulated string (as long as the key isn’t a control character;

we don’t want to add a line feed if Enter is pressed).15

15 http://www.js-x.com/syntax/key_codes.php provides a table of keycodes, including those generated

by control characters.

Chapter 6: Forms and Validation

Trang 6

File: typeahead.js (excerpt)

} else if (code >= 32) { t.keyword += character;

}

Next, we set the message in the browser’s status bar to display the accumulated string, providing visual feedback to the user.16 If the accumulated string is empty (i.e if we’ve just backspaced away the last character), we empty the status bar

to match

File: typeahead.js (excerpt)

if (t.keyword == '') { window.status = '';

} else { window.status = 'Searching: ' + t.keyword;

Set a timeout to blank the accumulated string in five seconds’ time Note the use

of an anonymous function for simplicity

File: typeahead.js (excerpt)

t.timeout_key = setTimeout(

function() { window.status = t.keyword = ''; }, 5000);

Finally, we’ll iterate through the list entries in the drop-down until one that contains the accumulated string is found If one is found, we set it as the selected entry If not, we set the selected entry to remain as the currently selected entry

In either case, we set the selected entry after a tiny delay, because Mozilla browsers will do their own type ahead navigation immediately after this event listener runs (there is currently no way to prevent it), so our selection assignment must come

in after that

File: typeahead.js (excerpt)

var gotoIndex = t.selectedIndex;

for (var i = 0; i < t.options.length; i++) {

if (t.options[i].text.toLowerCase().indexOf(t.keyword) != -1) {

gotoIndex = i;

break;

}

16 This may not work in all browsers: the browser status bar has been so misused for hiding URLs or for scrolling messages that manipulation of its contents from JavaScript is now sometimes disabled

by default.

Type-Ahead Drop-Down Lists

Trang 7

}

setTimeout(function() { t.selectedIndex = gotoIndex; }, 1);

Like many DHTML enhancements, this is a simple improvement over the existing in-browser functionality, and degrades neatly to doing nothing in browsers that

do not support it

The script does have the disadvantage that it’s not necessarily very discoverable; the only hint that a given drop-down list is using this new, more-usable method

of finding items is that the status bar changes to display the accumulated string, and, as noted, this may not take effect in some browsers On public Websites, therefore, this script won’t cause a problem, but it may not enhance usability as much as you might have expected On an intranet, or some other environment

in which users can undergo training that includes a description of how the en-hanced drop-down works, this feature can seriously improve the usability of long drop-down lists It may also be possible to display a tooltip, rather than a status bar message, when the user scrolls through the list with the keys, which would make the new behavior more apparent That’s an exercise for you to try for yourself!

Summary

In this chapter, we’ve seen the ways that DHTML can enhance form-filling, one

of the most common activities in any Web application We’ve seen how to im-plement the regular expression-based validation of form fields through DOM techniques We’ve also learned how to make life easier on developers by integrat-ing that validation with the equivalent validation that must be completed on the server There’s no need to write the same code twice in two languages

We then looked at enhancing individual form widgets to work in more complex ways, or to emulate more useful widgets from client-side applications Those en-hancements help overcome some limitations of Web browsers’ rather basic form implementations We also highlighted work that others have already done in this area Finally, a new technique was presented for enhancing the use of large drop-down lists

Chapter 6: Forms and Validation

Trang 8

Advanced Concepts and Menus

7

Why didn’t you bring something more advanced? Show me a piece of future technology.

—Dr Silberman, The Terminator

In this chapter, we’ll explore a DHTML idea that seems quite complex: a multi-level animated menu These menus abound on the Web—in fact, some firms do

a roaring trade selling code to generate DHTML menus for use in Website nav-igation But, as it turns out, such menus aren’t complex at all

The principles of unobtrusive DHTML and the power of the DOM mean that the actual code required to create a multi-level animated navigation system can

be quite short; nevertheless, advanced concepts are at work in such systems Understanding these concepts is a key aspect of large-scale DOM programming

A multi-level animated menu is a big project, so let’s see what we’re aiming for Figure 7.1 shows the menu we’re about to develop

Normally, the menu shows only the two leftmost menu items visible in the figure

In the figure, the user has moused over the second of those two items (DHTML Tutorials), causing a submenu to show The user then moused over the first item

in the submenu (By Simon Willison) to reveal the rightmost submenu The top of this final menu is level with that of the middle one because the first item of the middle menu was chosen

Trang 9

Without further ado, let’s start development! There’s quite a lot of code involved, but we’ll step through it one small piece at a time

Figure 7.1 The goal: a multi-level menu.

Creating Menu Content

The first step is to create the raw HTML content; then, we’ll bash it into shape with some CSS styling

Create Semantic Menu Content

As we’ve seen through earlier chapters, laying out HTML so that it’s semantically correct makes dealing with the code much simpler We want the menus to appear

as shown in Figure 7.1, which means that, like most other navigation systems, each level of this menu must contain either links or submenus The ideal way to lay out this kind of multi-level menu is to use the unordered list tag, <ul> So, first, let’s lay out the menu

File: menu-stage-1.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

"http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

<title>Client-side form validation</title>

<base href="http://www.sitepoint.com/">

</head>

<body>

Chapter 7: Advanced Concepts and Menus

Trang 10

<ul class="slidingmenu">

<li>

<a href="http://www.sitepoint.com/">SitePoint articles</a> <ul>

<li><a href="article/search-engine-spam-techniques"

>Latest Search Engine Spam Techniques</a></li>

<li><a href="article/free-web-design-apps"

>Free Web Design Apps You Can't Live Without!</a> </li>

<li><a href="article/securing-apache-2-server-ssl"

>Securing Your Apache 2 Server with SSL</a></li>

</ul>

</li>

<li>

<a href="subcat/javascript">DHTML Tutorials</a>

<ul>

<li>

<a href="articlelist/345">By Simon Willison</a>

<ul>

<li><a href="article/rounded-corners-css-javascript" >Rounded Corners with CSS and JavaScript</a>

</li>

<li><a href="article/bookmarklets"

>Better Living Through Bookmarklets</a></li>

<li><a href="article/simple-tricks-usable-forms"

>Simple Tricks for More Usable Forms</a></li> </ul>

</li>

<li><a href="article/smooth-scrolling-javascript"

>My tutorial</a></li>

<li><a href="article/behaved-dhtml-case-study"

>By Aaron Boodman</a>

<ul>

<li><a href="article/behaved-dhtml-case-study"

>Well-Behaved DHTML: A Case Study</a></li>

</ul>

</li>

</ul>

</li>

</ul>

</body>

</html>

Create Semantic Menu Content

Ngày đăng: 03/07/2014, 06:20

TỪ KHÓA LIÊN QUAN