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

Practical prototype and scipt.aculo.us part 23 pptx

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

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 92,9 KB

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

Nội dung

I find that the DOM approach works best when creating HTML programmatically— when the structure or content of the inserted markup isn’t the same every time—because building long strings

Trang 1

I find that the DOM approach works best when creating HTML programmatically— when the structure or content of the inserted markup isn’t the same every time—because building long strings in JavaScript isn’t my idea of a fun afternoon For simpler cases, innerHTMLis easier and faster Figure out the balance you’re comfortable with

The first three methods we’ll deal with—update,replace, and insert—don’t force you

to pick one approach or the other All three can accept either a markup string or a node.

Using update

Element#updatechanges the contents of an element Think of it as a thin wrapper around

innerHTML—just as assigning to the innerHTMLproperty will erase whatever was there before, updatewill discard the original contents of the element, replacing it with what you’ve given

// HTML (before):

<p id="foo"><b>narf</b></p>

// JavaScript:

$('foo').update('<span>thud</span>');

// HTML (after):

<p id="foo"><span>thud</span></p>

It boasts several advantages over innerHTML:

• As explained, it can take a DOM node or a string

• The convenient “automatic script evaluation” you were introduced to in Chapter 4 also applies to Element#update Any scriptelements in the inserted markup will be removed; the code inside them will be extracted and evaluated after the element has been updated

• It gracefully handles some special cases where Internet Explorer tends to choke For instance, most table elements have read-only innerHTMLproperties, as do odd-balls like coland select

Let’s try a DOM node instead of an HTML string:

var span = document.createElement('span');

span.appendChild(document.createTextNode('thud'));

$('foo').update(span);

$('foo').innerHTML; //-> "<span>thud</span>"

Trang 2

Using replace

Element#replaceis nearly identical to its brother update, but can be used to replace an

ele-ment (and all its descendants) instead of just changing its contents

CHAINING

Prototype’s augmentation of DOM node instance methods opens the door to method chaining: a

syntac-tic shortcut that makes lines of code read like sentences

Many of the methods in this chapter—specifically those that do not need to return other values—

will return the elements themselves Consider this code:

$('foo').addClassName('inactive');

$('foo').hide();

Because both addClassNameand updatereturn the element itself, this code can be simplified:

$('foo').addClassName('active').hide();

Chaining method calls like this—joining them in a line, each acting upon the return value of the

last—can increase code clarity when used judiciously In this example, we’ve also optimized the code,

removing a redundant call to $to re-fetch the element

Look out for methods that do not return the original element Consider Element#wrap, which

returns the new created parent node:

$('foo').wrap('div');

$('foo').addClassName('moved');

// wrong:

$('foo').wrap('div').addClassName('moved');

We’ve changed the meaning of the code by accident: instead of adding a class name to the

ele-ment with an ID of foo, we’re now adding it to the divthat was created and returned by wrap

Reversing the order of the method calls preserves our intent:

// right:

$('foo').addClassName('moved').wrap('div');

Similarly, note that Element#replacewill return the original element, but that element has been

replaced and is no longer a part of the DOM tree If you want to work with the content that has replaced

it, you’ll need to obtain that reference some other way

Trang 3

// HTML (before):

<div id="foo"><span>thud</span></div>

// JavaScript:

$('foo').replace('<p id='foo'><b>narf</b></p>');

// HTML (after):

<p id="foo"><b>narf</b></p>

The new content occupies the same position in the document as its predecessor So replaceis a way to remove an element, keep a finger on its spot in the DOM tree, and then insert something else at that spot

Using insert

Element#insertappends content to an element without removing what was there before

We flirted with insertin Chapter 4, so the syntax will be familiar to you:

// HTML (before):

<div id="foo"><span>thud</span></div>

// JavaScript:

$('foo').insert("<span>honk</span>", 'top');

// HTML (after):

<div id="foo"><span>honk</span><span>thud</span></div>

The second argument is the position of insertion—either before,after,top, or bottom This argument will default to bottomif omitted

// equivalent in meaning:

$('foo').insert("<span>honk</span>", 'bottom');

$('foo').insert("<span>honk</span>");

A more robust syntax can be used to insert several things at once Instead of a string, pass an object as the first argument—the keys are insertion positions and the values are HTML strings

Trang 4

// HTML (before):

<div id="foo"><span>thud</span></div>

// JavaScript:

$('foo').insert({ top: "<span>honk</span>", bottom: "<span>narf</span>" });

// HTML (after):

<div id="foo"><span>honk</span><span>thud</span><span>narf</span></div>

The positions beforeand afterare similar to topand bottom, respectively, but you

insert the new elements outside the boundaries of the given element—as siblings, rather

than children

// HTML (before):

<div id="foo"><span>thud</span></div>

// JavaScript:

$('foo').insert({ before: "<span>honk</span>", after: "<span>narf</span>" });

// HTML (after):

<span>honk</span><div id="foo"><span>thud</span></div><span>narf</span>

Using remove

In the DOM API, you must remove an element by calling the removeChildmethod on its

parent:

// to remove "foo"

$('foo').parentNode.removeChild($('foo'));

Prototype adds Element#removein order to circumvent this annoyance:

$('foo').remove();

Note that removing an element from the document doesn’t make it vanish; it can

be reappended somewhere else, or even modified while detached But a detached node

won’t respond to calls to $or document.getElementById(since the node is no longer in

the document), so make sure you preserve a reference to the node by assigning it to a

variable

Trang 5

// to remove "foo" and append it somewhere else

var foo = $('foo');

foo.remove();

$('new_container').appendChild(foo);

The readAttribute and writeAttribute Methods

Prototype’s readAttributeand writeAttributemethods are used to get and set attributes

on elements

“Aren’t these superfluous?” you ask “Doesn’t the DOM give us getAttributeand setAttribute?” Yes, it does, and browsers also expose attributes as properties of their object representations—a holdover from the pre-DOM days So, for instance, the href attribute of a link can be fetched with $('foo').getAttribute('href')or even

$('foo').href

But these approaches have compatibility problems Internet Explorer, in particular, exhibits a host of bugs in this area, thwarting our attempts to get identical behavior from all major browsers Element#readAttributeand Element#writeAttributeare wrappers that ensure identical behavior

Using readAttribute

Let’s look at some examples of surprising getAttributebehavior in Internet Explorer: // HTML:

<label id="username_label" class="required" for="username">

<input type="text" id="username" name="username"

disabled="disabled" />

</label>

<a id="guidelines" href="/guidelines.html">Username guidelines</a>

// JavaScript:

var label = $('username_label');

label.getAttribute('class'); //-> null

label.getAttribute('for'); //-> null

var input = $('username');

input.getAttribute('disabled'); //-> true

var link = $('guidelines');

link.getAttribute('href'); //-> "http://www.example.com/guidelines.html"

Trang 6

The labelelement has classand forattributes set, but Internet Explorer returns null

for both The inputtag has a disabledattribute with a value of “disabled” (in accordance

with the XHTML spec), but Internet Explorer doesn’t return the literal value—it returns a

Boolean And the aelement points to an absolute URL on the same server, but Internet

Explorer gives us the “resolved” version when we ask for its href

In all three cases, we’re expecting the literal value that was set in the markup—that’s

how getAttributeis supposed to work, and that’s how the other browsers do it When it

was released, Internet Explorer 6 had the best DOM support of any browser, incomplete

as it was; now, six years later, bugs like these make Internet Explorer the slowpoke of the

bunch

In nearly all cases, the value we want is hidden somewhere—we’ve just got to find it

Prototype does the heavy lifting for you

var label = $('username_label');

label.readAttribute('class'); //-> "required"

label.readAttribute('for'); //-> "username"

var input = $('username');

input.readAttribute('disabled'); //-> "disabled"

var link = $('guidelines');

link.readAttribute('href'); //-> "/guidelines.html";

Use readAttributeanywhere you’d use getAttribute It’s safer

Using writeAttribute

As you may expect, writeAttributelets you set attribute values safely in all browsers,

suc-ceeding where Internet Explorer’s setAttributefails:

label.setAttribute('class', 'optional'); // fails

label.writeAttribute('class', 'optional'); // succeeds

But that’s not all It adds a major syntactic time-saver for writing multiple attributes

at once—simply pass an object literal full of attribute names and values

input.writeAttribute('id', 'user_name');

label.writeAttribute({

title: 'Please choose a username.',

'class': 'optional',

'for': 'user_name'

});

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