Приглашаем посетить
Культура (cult-news.ru)

Programming the Anchor Element

Programming the Anchor Element

The HTML Anchor element serves a dual purpose: to specify links for navigating to URLs and to specify bookmarks within the document. An Anchor element acts as a link if its HREF attribute is defined, and it acts as a bookmark if its NAME attribute is defined:

<A HREF="http://www.insideDHTML.com#Chapter2"><!-- Link --></A>
<A NAME="Chapter2"><!-- Bookmark --></A>

The document's all collection references all of the Anchor elements. The document has two additional collections that separately reference the links and the bookmarks. Links are exposed through the links collection, and bookmarks are exposed through the anchors collection. A single Anchor element can appear in both collections if both a NAME and an HREF attribute are specified.

Both the href and the name properties can be changed through code, so the anchor object can dynamically switch collections. For example, if an anchor with an empty href is assigned a string, it is automatically added to the links collection and is also automatically rendered as a link on the screen. Regardless of the type of anchor and the collections it is in, the anchor object exposes the same set of properties, methods, and events.


NOTE: From here on, anchors specified as <A NAME=> are referred to as bookmarks and anchors specified as <A HREF=> are referred to as links to disambiguate the two types of anchors. These links are different from the Link element discussed in the section "Programming the Link Element" later in this chapter. The <LINK> tag defines the Link element.

The href Property

The anchor object has a number of properties that contain portions of the URL exposed by the href property. The protocol, hostname, port, pathname, search, and hash properties reference the individual parts of the URL, and the host property contains both host name and port information. These properties, which also belong to the location object, are described in Chapter 4, "The Browser Window."

Anchors and the Base HREF

An interesting relationship exists between relatively specified HREF values and the object model. A relative HREF is a URL that does not start explicitly with // (for example, href="goHere.htm"). All relative HREFs are prefixed with a default location. Unless otherwise specified, the default location is the location of the current document. You can use the Base element to change the default location. For relative URLs assigned to attributes, the default location is added when the document is parsed. For relative URLs assigned to properties by scripts, the default location is not added until the URL is referenced. The following code illustrates these points:

<HTML>
   <HEAD>
      <TITLE>Base HREF Demo</TITLE>
      <BASE HREF="http://scotti/">
   </HEAD>
   <BODY>
      <A HREF="page1.htm">page 1</A>
      <A HREF="http://ji/page2.htm">page 2</A>
      <SCRIPT LANGUAGE="JavaScript">
         alert(document.links[0].href); // http://scotti/page1.htm
         alert(document.links[1].href); // http://ji/page2.htm
         document.links[0].href = "newpage.htm";
         alert(document.links[0].href); // newpage.htm
      </SCRIPT>
   </BODY>
</HTML>

Script-Specified HREF Attribute

The HREF attribute of an Anchor element may be alternatively specified as a line of code to execute rather than as a URL. This technique is useful when a frame is to contain a short string because it reduces the number of necessary round-trips with the server. For example, when the user clicks on the following anchor, a simple document that displays the string Hello, world! is created:

<A HREF="JavaScript:'Hello, world!'">

The protocol is the language name followed by a colon, and the pathname is the rest of the string. The href property itself contains the entire string with appropriate escape sequences (such as %20 for each space).

Script-specified HREF attributes execute after the onclick event stops firing. Also, since the HREF attribute is not an event, the event object is not available at the time the script-specified HREF executes.


NOTE: Take care when using VBScript for script-specified HREF attributes. Netscape Navigator recognizes only the JavaScript language and will display a navigation error if VBScript is specified.

Events on the Anchor Element

The Anchor element supports a set of standard events that indicate when the user clicks on, moves the mouse over, or types in an anchor. The events that can originate with the Anchor element depend on whether the anchor is a link or a bookmark. If the Anchor element cannot act as a source for the event, it will never be defined as srcElement if the event bubbles.


Event Source
onblur Link anchors
onclick All anchors
ondblclick All anchors
onfocus Link anchors
onkeydown Link anchors
onkeypress Link anchors
onkeyup Link anchors
onmousedown All anchors
onmousemove All anchors
onmouseout All anchors
onmouseover All anchors
onmouseup All anchors

However, through event bubbling, the Anchor element can receive the event from a child event (such as an image in the anchor) even if it does not explicitly support it. The preceding table lists the events for which each type of anchor can act as the source. All events can be defined as attributes on the element, through the <SCRIPT FOR= EVENT= > syntax or through properties of the Anchor element. To be a source for focus and keyboard events, an element must be able to receive the focus. Anchors that are links can receive the focus; bookmarks cannot.

The default result of clicking on a link is a jump to the anchor. This action can be overridden to customize how a page handles a link. The following code cancels the default action of a specific link:

<A HREF="foo.htm#100" ONCLICK="event.returnValue = false;">

If you want compatibility with other browsers, return the value directly:

<A HREF="foo.htm#100" ONCLICK="return false;">

More generically, anchors can be overridden at the document level by handling the document's onclick event, as shown in the following code. This technique works because the standard events, except onblur and onfocus, bubble up the document's hierarchy chain.

<SCRIPT FOR="document" EVENT="onclick()" LANGUAGE="JavaScript">
   // Event object contains global information for the event handler.
   if ("A" == event.srcElement.tagName) {
      event.returnValue = false;
      // Write custom handler code for the anchor.
   }
</SCRIPT>

The event sequence defines the ondblclick event to follow the onclick event. The only way to determine whether a link received a double click is to override the default action of the single click because the event sequence is fixed. There is no way to write an event handler for a link that performs a default action for a click event and a different action for the double click because the link already navigates to the targeted link before the ondblclick event fires. Therefore, the usefulness of an ondblclick event on a link is fairly limited, and most interactions with anchors are accomplished using the onclick event.

Customizing Links to Target Multiple Frames

One technique for adding custom behavior to an anchor is to define a few new attributes on the Anchor element. This technique for simulating subclassing was introduced in Chapter 8, "Scripts and Elements." This section demonstrates how to augment the traditional behavior of anchors. The simple example presented here implements the basics for a much-requested feature of HTML and framesets—the ability to target multiple frames with a single anchor. This example demonstrates how authors can add their own functionality to a page, without having to wait for the browser to add the support.

The following code adds two user-defined attributes to the Anchor element: mhref and mtarget. Both attributes take a semicolon-delimited list of values—for mhref, a list of URLs, and for mtarget, a list of destinations for these URLs. When the user clicks on an anchor, the code first checks whether the anchor has these special attributes and, if it does, the code overrides the default behavior of following a single link with the custom linking code.

<HTML>
   <HEAD>
      <TITLE>Targeting Multiple Frames</TITLE>
      <SCRIPT LANGUAGE="JavaScript">
         function checkElementTree(el, strTag) {
            /* This simple function walks up the tree from the element
               el and looks for any element with the tag strTag.
               The first matching element found is returned. */
            while ("HTML" != el.tagName) {
               if (strTag == el.tagName)
                  return el;
               el = el.parentElement;
            }
            return null;
         }

         function multiJump() {
            // Find the anchor.
            var el = checkElementTree(event.srcElement, "A");
            if (null != el) { // Found an anchor.
               // Check whether it is a multitarget anchor.
               if ((null != el.getAttribute("mhref")) &&
                     (null != el.getAttribute("mtarget"))) {
                  event.returnValue = false;
                  var mhref = new Array();
                  var mtarget = new Array();
                  // Parse attributes into arrays.
                  mhref = el.getAttribute("mhref").split("; ");
                  mtarget =
                     el.getAttribute("mtarget").split("; ");
                  /* Be sure there are an equal number
                     of targets and URLs. */
                  if (mtarget.length == mhref.length)
                     for (var intLoop = 0; intLoop < mtarget.length;
                           intLoop++)
                        if (null != parent[mtarget[intLoop]])
                           parent[mtarget[intLoop]].location.href =
                              mhref[intLoop];
               }
            }
         }
      </SCRIPT>
   </HEAD>
   <BODY ONCLICK="multiJump();">
      <A HREF="#"
            mhref="http://www.microsoft.com; http://www.netscape.com"
            mtarget="left; right">
         Browser Web sites
      </A>
   </BODY>
</HTML>

This code works only for frames that are siblings to the frame containing it. To make this code work for frames that exist anywhere in the frameset hierarchy, you must write code that simulates the searching algorithm used by the browser to search the hierarchy of windows.

Subclassing elements with user-defined attributes is one of the most powerful ways to take advantage of Dynamic HTML. It lets you easily customize elements, without having to hard-code the customizations into HTML or the scripting language. Custom attributes can be defined for identifying new behavior, and the code can look for these identifiers and process the elements accordingly.

Pseudo-Classes for Anchors

Style sheets provide a technique for defining styles for the three states of a link: visited, not visited, and active. These states can each have a different style, which you set using pseudo-classes in CSS. Pseudo-classes provide a technique for improving user interactivity without requiring any code. See Chapter 1, "Overview of HTML and CSS," or the CSS specification at the W3C Web site for more information about pseudo-classes and the CSS language.

Beyond using the pseudo-class, no property is currently exposed to the scripting language for directly determining whether a link has been visited. Therefore, there is no simple way to conditionally script links based on whether they have been visited.

Removing Anchors

Simply assigning an empty string to either the href or the name property does not remove an Anchor element from the document. However, this technique will remove the element from the links or anchors collection, respectively. (The element will always remain in the all collection.)

An Anchor element and its contents can be completely removed from the document by using the outerHTML or outerText properties. To remove the influence of the anchor but leave the contents, the TextRange object can be used. The following code demonstrates how to manipulate TextRange. Don't worry if you do not understand this code. The TextRange object and its methods are discussed in detail in Chapter 14, "User Selection and Editing Operations."

<SCRIPT LANGUAGE="JavaScript">
   function removeAnchor(aElement) {
      // The anchor to remove is passed as an argument.
      // Create a TextRange object.
      var tr = aElement.parentTextEdit.createTextRange();
      // Locate the Anchor element in the textRange.
      tr.moveToElementText(aElement);
      // Execute a command to remove the Anchor element.
      tr.execCommand("Unlink", false);
   }
</SCRIPT>

[Содержание]