Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<com:TContent ID="body" >
2
<h1 id="6701">DOM Events and Javascript</h1>
3
 
4
<h2 id="6702">Basic event handling</h2>
5
 
6
<p id="840735" class="block-content">The syntax for working with events looks like the code below.</p>
7
 
8
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840254">
9
Event.observe(element, name, observer, [useCapture]);
10
</com:TTextHighlighter>
11
 
12
<p id="840736" class="block-content">Assuming for a moment that we want to observe when a link was clicked,
13
we could do the following:</p>
14
 
15
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840255">
16
// &lt;a id="clicker" href="http://foo.com"&gt;Click me&lt;/a&gt;
17
Event.observe('clicker', 'click', function(event)
18
{
19
    alert('clicked!');
20
});
21
</com:TTextHighlighter>
22
 
23
<p id="840737" class="block-content">If we wanted to get the element that fired the event, we'd do this:</p>
24
 
25
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840256">
26
Event.observe('clicker', 'click', function(event)
27
{
28
    alert(Event.element(event));
29
});
30
</com:TTextHighlighter>
31
 
32
<h2 id="6703">Observing keystrokes</h2>
33
 
34
<p id="840738" class="block-content">If we wanted to observe keystrokes for the entire document, we could do the following:</p>
35
 
36
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840257">
37
Event.observe(document, 'keypress', function(event)
38
{
39
    if(Event.keyCode(event) == Event.KEY_TAB)
40
        alert('Tab Pressed');
41
});
42
</com:TTextHighlighter>
43
 
44
<p id="840739" class="block-content">And lets say we wanted to keep track of what has been typed :</p>
45
 
46
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840258">
47
Event.observe('search', 'keypress', function(event)
48
{
49
    Element.update('search-results', $F(Event.element(event)));
50
});
51
</com:TTextHighlighter>
52
 
53
<p id="840740" class="block-content">Prototype defines properties inside the event object for some
54
of the more common keys, so feel free to dig around in Prototype to
55
see which ones those are.</p>
56
 
57
<p id="840741" class="block-content">A final note on keypress events; If you'd like to detect a
58
left click you can use <tt>Event.isLeftClick(event)</tt>.</p>
59
 
60
<h2 id="6704">Getting the coordinates of the mouse pointer</h2>
61
 
62
<p id="840742" class="block-content">Drag and drop, dynamic element resizing, games, and
63
much more all require the ability to track the X and Y location of
64
the mouse. Prototype makes this fairly simple. The code below tracks
65
the X and Y position of the mouse and spits out those values into
66
an input box named mouse.</p>
67
 
68
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840259">
69
Event.observe(document, 'mousemove', function(event)
70
{
71
    $('mouse').value = "X: " + Event.pointerX(event) +
72
                       "px Y: " + Event.pointerY(event) + "px";
73
});
74
</com:TTextHighlighter>
75
 
76
<p id="840743" class="block-content">If we wanted to observe the mouse location when it was
77
hovering over a certain element, we'd just change the document argument to
78
the id or element that was relevant.</p>
79
 
80
<h2 id="6705">Stopping Propagation</h2>
81
 
82
<p id="840744" class="block-content"><tt>Event.stop(event)</tt> will stop the propagation of an event .</p>
83
 
84
<h2 id="6706">Events, Binding, and Objects</h2>
85
 
86
<p id="840745" class="block-content">Everything has been fairly straight forward so far, but things
87
start getting a little trickier when you need to work with events in
88
and object-oriented environment. You have to deal with binding and funky
89
looking syntax that might take a moment to get your head around.</p>
90
 
91
<p id="840746" class="block-content">Lets look at some code so you can get a better understanding of what I'm talking about.</p>
92
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840260">
93
EventDispenser = Class.create();
94
EventDispenser.prototype =
95
{
96
  initialize: function(list)
97
  {
98
    this.list = list;
99
 
100
    // Observe clicks on our list items
101
    $$(this.list + " li").each(function(item)
102
    {
103
        Event.observe(item, 'click', this.showTagName.bindEvent(this));
104
    }.bind(this));
105
 
106
    // Observe when a key on the keyboard is pressed.
107
    // In the observer, we check for
108
    // the tab key and alert a message if it is pressed.
109
    Event.observe(document, 'keypress', this.onKeyPress.bindEvent(this));
110
 
111
    // Observe our fake live search box.  When a user types
112
    // something into the box, the observer will take that
113
    // value(-1) and update our search-results div with it.
114
    Event.observe('search', 'keypress', this.onSearch.bindEvent(this));
115
 
116
    Event.observe(document, 'mousemove', this.onMouseMove.bindEvent(this));
117
  },
118
 
119
  // Arbitrary functions to respond to events
120
  showTagName: function(event)
121
  {
122
    alert(Event.element(event).tagName);
123
  },
124
 
125
  onKeyPress: function(event)
126
  {
127
    var code = event.keyCode;
128
    if(code == Event.KEY_TAB)
129
        alert('Tab key was pressed');
130
  },
131
 
132
  onSearch: function(event)
133
  {
134
    Element.update('search-results', $F(Event.element(event)));
135
  },
136
 
137
  onMouseMove: function(event)
138
  {
139
    $('mouse').value = "X: " + Event.pointerX(event) +
140
                "px Y: " + Event.pointerY(event) + "px";
141
  }
142
}
143
</com:TTextHighlighter>
144
<p id="840747" class="block-content">Whoa! What's going on here? Well, we've defined our a
145
custom class <tt>EventDispenser</tt>. We're going to be using this class
146
to setup events for our document. Most of this code is a
147
rewrite of the code we looked at earlier except this time, we
148
are working from inside an object.</p>
149
 
150
<p id="840748" class="block-content">Looking at the <tt>initialize</tt> method, we can really see how
151
things are different now. Take a look at the code below:</p>
152
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840261">
153
// Observe clicks on our list items
154
$$(this.list + " li").each(function(item)
155
{
156
    Event.observe(item, 'click', this.showTagName.bindEvent(this));
157
}.bind(this));
158
</com:TTextHighlighter>
159
 
160
<p id="840749" class="block-content">We've got iterators, binding and all sorts of stuff going on.
161
Lets break down what this chunk of code is doing.</p>
162
 
163
<p id="840750" class="block-content">First we are hunting for a collection of elements based on
164
it's CSS selector. This uses the Prototype selector function <tt>$$()</tt>.
165
After we've found the list items we are dealing with we send
166
those into an each iteration where we will add our observers.</p>
167
 
168
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840262">
169
Event.observe(item, 'click', this.showTagName.bindEvent(this));
170
</com:TTextHighlighter>
171
 
172
<p id="840751" class="block-content">Now looking at the code above, you'll notice the <tt>bindEvent</tt> function.
173
This takes the method before it <tt>showTagName</tt> and treats it as the
174
method that will be triggered when, in this case,
175
someone clicks one of our list items.</p>
176
 
177
<p id="840752" class="block-content">You'll also notice we pass this as an argument to the <tt>bindEvent</tt> function.
178
This simply allows us to reference the object in context <tt>EventDispenser</tt>
179
inside our function <tt>showTagName(event)</tt>. If the <tt>showTagName</tt> function
180
requires additional parameters, you can attach them to the later parameters of <tt>bindEvent</tt>. For example</p>
181
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840263">
182
this.showTagName.bindEvent(this, param1, param2);
183
 
184
//where the showTagName function is defined as
185
showTime : function (event, param1, param2) { ... }
186
</com:TTextHighlighter>
187
 
188
<p id="840753" class="block-content">Moving on, you'll see <tt>bind(this)</tt> attached to our iterator function.
189
This really has nothing to do with events, it is only here to allow me to
190
use <tt>this</tt> inside the iterator. If we did not use <tt>bind(this)</tt>, I could not
191
reference the method <tt>showTagName</tt> inside the iterator.</p>
192
 
193
<p id="840754" class="block-content">Ok, so we'll move on to looking at our methods that actually get
194
called when an event occurs. Since we've been dealing with <tt>showTagName</tt>, lets look at it.</p>
195
 
196
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840264">
197
showTagName: function(event)
198
{
199
    alert(Event.element(event).tagName);
200
}
201
</com:TTextHighlighter>
202
 
203
<p id="840755" class="block-content">As you can see, this function accepts one argument--the event.
204
In order for us to get the element which fired the event we need to
205
pass that argument to <tt>Event.element</tt>. Now we can manipulate it at will.</p>
206
 
207
<p id="840756" class="block-content">This covers the most confusing parts of our code. The text above is also
208
relevant to the remaining parts of our code. If there is anything about
209
this you don't understand, feel free to ask questions in the forum.</p>
210
 
211
<h2 id="6707">Removing Event Listeners</h2>
212
 
213
<p id="840757" class="block-content">This one threw me for a loop the first time I tried to use it.
214
I tried something similar to what I did in the <tt>Event.observe</tt>
215
call with the exception of using <tt>stopObserving</tt>, but nothing seemed
216
to change. In other words, the code below does <b>NOT</b> work.</p>
217
 
218
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840265">
219
$$(this.list + " li").each(function(item)
220
{
221
    Event.stopObserving(item, 'click', this.showTagName);
222
}.bind(this));
223
</com:TTextHighlighter>
224
 
225
<p id="840758" class="block-content">What's the deal here? The reason this does not work is because there
226
is no pointer to the observer. This means that when we passed <tt>this.showTagName</tt>
227
in the <tt>Event.observe</tt> method before hand, we passed it as an
228
anonymous function. We can't reference an anonymous function
229
because it simply does not have a pointer.</p>
230
 
231
<p id="840759" class="block-content">So how do we get the job done? All we need to do is give the
232
observing function a pointer, or the jargon free version: Set a variable
233
that points to <tt>this.showTagName</tt>. Ok, lets change our code a bit.</p>
234
 
235
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840266">
236
this.showTagObserver = this.showTagName.bindEvent(this);
237
 
238
// Observe clicks on our list items
239
$$(this.list + " li").each(function(item)
240
{
241
    Event.observe(item, 'click', this.showTagObserver);
242
}.bind(this));
243
</com:TTextHighlighter>
244
 
245
<p id="840760" class="block-content">Now we can remove the event listeners from our list like this:</p>
246
<com:TTextHighlighter Language="javascript" CssClass="source block-content" id="code_840267">
247
$$(this.list + " li").each(function(item)
248
{
249
    Event.stopObserving(item, 'click', this.showTagObserver);
250
}.bind(this));
251
</com:TTextHighlighter>
252
 
253
<div class="last-modified">$Id: Scripts2.page 1650 2007-01-24 06:55:32Z wei $</div></com:TContent>