[ Index ] |
|
Code source de PRADO 3.0.6 |
1 <com:TContent ID="body" > 2 3 <h1 id="6601">Developer Notes for prototype.js</h1> 4 This guide is based on the <a href="http://www.sergiopereira.com/articles/prototype.js.html"> 5 Developer Notes for prototype.js</a> by Sergio Pereira. 6 7 <h2 id="6603">What is that?</h2> 8 <p> 9 In case you haven't already used it, <a href="http://prototype.conio.net">prototype.js</a> is a 10 JavaScript library written by <a href="http://www.conio.net">Sam Stephenson</a>. 11 This amazingly well thought and well written piece of <b>standards-compliant</b> code takes a lot of 12 the burden associated with creating rich, highly interactive web pages that characterize the Web 2.0 off your back. 13 </p> 14 15 <p> 16 If you tried to use this library recently, you probably noticed that documentation is not one 17 of its strongest points. As many other developers before me, I got my head around prototype.js by 18 reading the source code and experimenting with it. I thought it would be nice to take notes while 19 I learned and share with everybody else. 20 </p> 21 <p> 22 As you read the examples and the reference, developers familiar with the Ruby 23 programming language will notice an intentional similarity between Ruby's 24 built-in classes and many of the extensions implemented by this library. 25 </p> 26 27 28 <h2 id="6604">Using the <tt>$()</tt> function</h2> 29 <p> 30 The <tt>$()</tt> function is a handy shortcut to the all-too-frequent <tt>document.getElementById()</tt> function 31 of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument. 32 </p> 33 34 <p> 35 Unlike the DOM function, though, this one goes further. You can pass more than one id and 36 <tt>$()</tt> will return an <tt>Array</tt> object with 37 all the requested elements. The example below should illustrate this. 38 </p> 39 <com:TTextHighlighter Language="javascript" CssClass="source"> 40 <com:TClientScript UsingClientScripts="prado" /> 41 <div id="myDiv"> 42 <p>This is a paragraph</p> 43 </div> 44 45 <div id="myOtherDiv"> 46 <p>This is another paragraph</p> 47 </div> 48 49 <input type="button" value=Test1 onclick="test1();" /> 50 <input type="button" value=Test2 onclick="test2();" /> 51 52 <script type="text/javascript"> 53 /*<![CDATA[*/ 54 function test1() 55 { 56 var d = $('myDiv'); 57 alert(d.innerHTML); 58 } 59 60 function test2() 61 { 62 var divs = $('myDiv','myOtherDiv'); 63 for(i=0; i<divs.length; i++) 64 { 65 alert(divs[i].innerHTML); 66 } 67 } 68 /*]]>*/ 69 </script> 70 </com:TTextHighlighter> 71 <p> 72 Another nice thing about this function is that you can pass either the <tt>id</tt> string or the element object itself, 73 which makes this function very useful when creating other functions that can also take either form of argument. 74 </p> 75 76 <h2 id="6605">Using the <tt>$F()</tt> function</h2> 77 78 <p> 79 The <tt>$F()</tt> function is a another welcome shortcut. It returns the value of any field input control, 80 like text boxes or drop-down lists. The function can take as argument either the element <tt>id</tt> or the element object itself. 81 </p> 82 <com:TTextHighlighter Language="javascript" CssClass="source"> 83 <input type="text" id="userName" value="Joe Doe" /> 84 <input type="button" value=Test3 onclick="test3();" /> 85 86 <script type="text/javascript"> 87 /*<![CDATA[*/ 88 function test3() 89 { 90 alert($F('userName')); 91 } 92 /*]]>*/ 93 </script> 94 </com:TTextHighlighter> 95 96 <h2 id="6606">Using the <tt>$A()</tt> function</h2> 97 98 <p> 99 The <tt>$A()</tt> function converts the single argument it receives 100 into an <tt>Array</tt> object. 101 </p> 102 <p> 103 This function, combined with the extensions for the Array class, 104 makes it easier to convert or copy any enumerable list into an 105 <tt>Array</tt> object. One suggested use is to convert DOM 106 <tt>NodeLists</tt> into regular arrays, which can be traversed 107 more efficiently. See example below. 108 </p> 109 110 <com:TTextHighlighter Language="javascript" CssClass="source"> 111 <select id="lstEmployees" size="10" > 112 <option value="5">Buchanan, Steven</option> 113 <option value="8">Callahan, Laura</option> 114 <option value="1">Davolio, Nancy</option> 115 </select> 116 117 <input type="button" value="Show the options" onclick="showOptions();" /> 118 119 <script type="text/javascript"> 120 /*<![CDATA[*/ 121 function showOptions() 122 { 123 var someNodeList = $('lstEmployees').options; 124 var nodes = $A(someNodeList); 125 126 nodes.each(function(node) 127 { 128 alert(node.nodeName + ': ' + node.innerHTML); 129 }); 130 } 131 /*]]>*/ 132 </script> 133 </com:TTextHighlighter> 134 135 <h2 id="6607">Using the <tt>$H()</tt> function</h2> 136 <p> 137 The <tt>$H()</tt> function converts 138 objects into enumerable Hash objects that 139 resemble associative arrays. 140 </p> 141 <com:TTextHighlighter Language="javascript" CssClass="source"> 142 function testHash() 143 { 144 //let's create the object 145 var a = 146 { 147 first: 10, 148 second: 20, 149 third: 30 150 }; 151 152 //now transform it into a hash 153 var h = $H(a); 154 alert(h.toQueryString()); 155 156 //displays: first=10&second=20&third=30 157 } 158 </com:TTextHighlighter> 159 160 <h2 id="6608">Enumerating... Wow! Damn! Wahoo!</h2> 161 <p> 162 We are all familiar with for-loops. You know, create yourself an array, populate it with 163 elements of the same kind, create a loop control structure (for, foreach, while, repeat, etc,) 164 access each element sequentially, by its numeric index, and do something with the element. 165 </p> 166 <p> 167 When you come to think about it, almost every time you have an array in your code it 168 means that you'll be using that array in a loop sooner or later. Wouldn't it be nice 169 if the array objects had more functionality to deal with these iterations? Yes, it would, 170 and many programming languages provide such functionality in their arrays or equivalent 171 structures (like collections and lists.) 172 </p> 173 174 <p> 175 Well, it turns out that prototype.js gives us the Enumerable 176 object, which implements a plethora of tricks for us to use when dealing with iterable data. 177 The prototype.js library goes one step further and extends the 178 <tt>Array</tt> class with all the methods of <tt>Enumerable</tt>. 179 </p> 180 181 <a name="Loops"></a> 182 <h3 id="6617">Loops and iterator</h3> 183 <p> 184 In standard javascript, if you wanted to sequentially display the elements of an array, 185 you could very well write something like this. 186 </p> 187 <com:TTextHighlighter Language="javascript" CssClass="source"> 188 <script type="text/javascript"> 189 /*<![CDATA[*/ 190 function showList() 191 { 192 var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg']; 193 for(i=0; i < simpsons.length; i++) 194 { 195 alert(simpsons[i]); 196 } 197 } 198 /*]]>*/ 199 </script> 200 201 <input type="button" value="Show List" onclick="showList();" /> 202 </com:TTextHighlighter> 203 <p> 204 With our new best friend, prototype.js, we can rewrite this loop like this. 205 </p> 206 207 <com:TTextHighlighter Language="javascript" CssClass="source"> 208 function showList() 209 { 210 var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg']; 211 simpsons.each( function(familyMember) 212 { 213 alert(familyMember); 214 }); 215 } 216 </com:TTextHighlighter> 217 <p> 218 You are probably thinking "big freaking deal...just a weird syntax for the same old thing." 219 Well, in the above example, yes, there's nothing too earth shattering going on. After all, 220 there's not much to be changed in such a drop-dead-simple example. But 221 keep reading, nonetheless. 222 </p> 223 <p> 224 Before we move on. Do you see this function that is being passed as an argument 225 to the <tt>each</tt> method? Let's start referring to it as an 226 <b>iterator</b> function. 227 </p> 228 229 <h3 id="6618">Your arrays on steroids</h3> 230 231 <p> 232 Like we mentioned above, it's very common for all the elements in your array to be of 233 the same kind, with the same properties and methods. Let's see how we can take advantage 234 of iterator functions with our new souped-up arrays. 235 </p> 236 <p> 237 Finding an element according to a criteria. 238 <p> 239 <com:TTextHighlighter Language="javascript" CssClass="source"> 240 <script type="text/javascript"> 241 /*<![CDATA[*/ 242 function findEmployeeById(emp_id) 243 { 244 var listBox = $('lstEmployees') 245 var options = $A(listBox.options); 246 var opt = options.find( function(employee) 247 { 248 return (employee.value == emp_id); 249 }); 250 251 alert(opt.innerHTML); //displays the employee name 252 } 253 /*]]>*/ 254 </script> 255 256 <select id="lstEmployees" size="10" > 257 <option value="5">Buchanan, Steven</option> 258 <option value="8">Callahan, Laura</option> 259 <option value="1">Davolio, Nancy</option> 260 </select> 261 262 <input type="button" value="Find Laura" onclick="findEmployeeById(8);" /> 263 </com:TTextHighlighter> 264 265 <p> 266 Now let's kick it up another notch. See how we can filter out 267 items in arrays, then retrieve just a desired member from each 268 element. 269 <p> 270 <com:TTextHighlighter Language="javascript" CssClass="source"> 271 <script type="text/javascript"> 272 /*<![CDATA[*/ 273 function showLocalLinks(paragraph) 274 { 275 paragraph = $(paragraph); 276 var links = $A(paragraph.getElementsByTagName('a')); 277 278 //find links that do not start with 'http' 279 var localLinks = links.findAll( function(link) 280 { 281 var start = link.href.substring(0,4); 282 return start !='http'; 283 }); 284 285 //now the link texts 286 var texts = localLinks.pluck('innerHTML'); 287 288 //get them in a single string 289 var result = texts.inspect(); 290 alert(result); 291 } 292 /*]]>*/ 293 </script> 294 295 <p id="someText"> 296 This <a href="http://othersite.com/page.html">text</a> has 297 a <a href="#localAnchor">lot</a> of 298 <a href="#otherAnchor">links</a>. Some are 299 <a href="http://wherever.com/page.html">external</a> 300 and some are <a href="#someAnchor">local</a> 301 </p> 302 <input type=button value="Find Local Links" 303 onclick="showLocalLinks('someText')" /> 304 </com:TTextHighlighter> 305 <p> 306 It takes just a little bit of practice to get completely addicted to this syntax. 307 Next we will go through the available functions with the following example. 308 </p> 309 <h1 id="6602">Enumerable Functions</h1> 310 The sample data for the following examples. 311 <com:TTextHighlighter Language="javascript" CssClass="source"> 312 var Fixtures = 313 { 314 Products: 315 [ 316 {name: 'Basecamp', company: '37signals', type: 'Project Management'}, 317 {name: 'Shopify', company: 'JadedPixel', type: 'E-Commerce'}, 318 {name: 'Mint', company: 'Shaun Inman',type: 'Statistics'} 319 ], 320 321 Artist: 322 [ 323 'As I Lay Dying', 324 '36 Crazyfist', 325 'Shadows Fall', 326 'Trivium', 327 'In Flames' 328 ], 329 330 Numbers: [0, 1, 4, 5, 98, 32, 12, 9] 331 }; 332 333 var F = Fixtures; 334 </com:TTextHighlighter> 335 336 <h2 id="6609"><tt>Enumerable.each</tt> function</h2> 337 <p>I used to find myself writing a lot of for loops. Although, 338 Prototype does not by any means eliminate the need to do for-loops, 339 it does give you access to what I consider to be a cleaner, easier to read method in each. 340 <com:TTextHighlighter Language="javascript" CssClass="source"> 341 for(var i = 0; i < F.Numbers.length; i++) 342 { 343 Logger.info(F.Numbers[i]); 344 } 345 </com:TTextHighlighter> 346 <p> 347 The <tt>each</tt> function allows us to iterate over these objects Ruby style. 348 </p> 349 <com:TTextHighlighter Language="javascript" CssClass="source"> 350 F.Numbers.each(function(num) 351 { 352 Logger.info(num); 353 }); 354 355 //Output 356 0 357 1 358 4 359 5 360 98 361 32 362 12 363 9 364 </com:TTextHighlighter> 365 366 <p>The <tt>each</tt> function takes one argument, an <b>iterator</b> function. 367 This iterator is invoked once for every item in the array, and that item 368 along with the optional index is passed to the iterator. So if 369 we also needed the index we could do something like the code below. 370 </p> 371 372 <com:TTextHighlighter Language="javascript" CssClass="source"> 373 F.Numbers.each(function(num, index) 374 { 375 Logger.info(index + ": " + num); 376 }); 377 378 //Output 379 0: 0 380 1: 1 381 2: 4 382 3: 5 383 4: 98 384 5: 32 385 6: 12 386 7: 9 387 </com:TTextHighlighter> 388 389 <h2 id="6610">Hash key/value pairs</h2> 390 <p>Hashes can be created by wrapping an Object (associative array) in 391 <tt>$H()</tt> and can have their key/value pairs exposed.</p> 392 393 <com:TTextHighlighter Language="javascript" CssClass="source"> 394 $H(F.Products[0]).each(function(product) 395 { 396 Logger.info(product.key + ": " + product.value); 397 }); 398 399 //Outputs 400 name: Basecamp 401 company: 37signals 402 type: Project Management 403 </com:TTextHighlighter> 404 <p> 405 We can also directly access the keys and values of a Hash without iterating over it. 406 </p> 407 <com:TTextHighlighter Language="javascript" CssClass="source"> 408 $H(F.Products[1]).keys(); 409 //Outputs name,company,type 410 411 $H(F.Products[1]).values(); 412 //Outputs Shopify,JadedPixel,E-Commerce 413 </com:TTextHighlighter> 414 415 <h2 id="6611"><tt>Enumerable.collect</tt> function</h2> 416 417 <p>The <tt>collect</tt> function allows you to iterate over an <tt>Array</tt> and return the 418 results as a new array. Each item returned as a result of the iteration will be 419 pushed onto the end of the new array.</p> 420 <com:TTextHighlighter Language="javascript" CssClass="source"> 421 var companies = F.Products.collect(function(product) 422 { 423 return product.company; 424 }); 425 426 Logger.info(companies.join(', ')); 427 428 // Outputs 429 // 37signals, JadedPixel, Shaun Inman 430 </com:TTextHighlighter> 431 432 <p>You can even join on the end of the block.</p> 433 <com:TTextHighlighter Language="javascript" CssClass="source"> 434 return F.Products.collect(function(product) 435 { 436 return product.company; 437 }).join(', '); 438 </com:TTextHighlighter> 439 440 <h2 id="6612"><tt>Enumerable.include</tt> function</h2> 441 442 <p>The <tt>include</tt> function allows you to check if a value is included in an array 443 and returns true or false depending on if a match was made. Assuming I put 444 up a form asking the user to name some artist in my iTunes playlist, 445 we could do something like the code below. Prime candidate for some conditional madness. 446 </p> 447 <com:TTextHighlighter Language="javascript" CssClass="source"> 448 return F.Artists.include('Britney Spears'); // returns false 449 </com:TTextHighlighter> 450 451 <h2 id="6613"><tt>Enumerable.inject</tt> function</h2> 452 453 <p>The <tt>inject</tt> function is good for getting a collective sum from an array of 454 values. For instance, to add up all the numbers. 455 </p> 456 <com:TTextHighlighter Language="javascript" CssClass="source"> 457 var score = F.Numbers.inject(0, function(sum, value) 458 { 459 return sum + value; 460 }); 461 462 Logger.info(score); 463 //Output 161 464 </com:TTextHighlighter> 465 466 <p>The first argument to <tt>inject</tt> is just an initial value that 467 would be added to the sum, so if we added 1 instead of 0, the output would be 162.</p> 468 469 <h2 id="6614"><tt>Enumerable.findAll</tt> function</h2> 470 <p> 471 When given an Array, the <tt>findAll</tt> function will return an array of 472 items for which the iterator evaluated to true. Basically, it allows you to 473 build a new array of values based on some search criteria. 474 If we wanted to find all products whose type was “E-Commerce†475 we could do something like the code below. 476 </p> 477 <com:TTextHighlighter Language="javascript" CssClass="source"> 478 var ecom = F.Products.findAll(function(product) 479 { 480 return product.type == 'E-Commerce'; 481 }); 482 483 Logger.info(ecom[0].company + " produces " + ecom[0].name); 484 485 //Outputs 486 JadedPixel produces Shopify 487 </com:TTextHighlighter> 488 489 <p>Note that even if only one match is made, just as in this case, 490 the result is still returned as an array. In that case, 491 <tt>ecom.company</tt> would return <tt>undefined</tt>.</p> 492 493 <h2 id="6615"><tt>Enumerable.detect</tt> function</h2> 494 <p>Unlike the <tt>findAll</tt> function, the <tt>detect</tt> function will only 495 return the first item for which the expression inside 496 the iterator is true. So, if we wanted to find the first number that 497 was greater than 5 we’d do something like the code below. 498 </p> 499 <com:TTextHighlighter Language="javascript" CssClass="source"> 500 var low = F.Numbers.detect(function(num) 501 { 502 return num > 5 503 }); 504 505 Logger.info(low); 506 //Outputs 98 507 </com:TTextHighlighter> 508 509 <p>Even though, there are other numbers above 5 in our array, detect 510 only gives us the first match back.</p> 511 512 <h2 id="6616"><tt>Enumerable.invoke</tt> function</h2> 513 514 <p>The <tt>invoke</tt> function allows us to pass a method as a string and 515 have that method invoked. For instance, if we wanted to sort 516 our array of artists we’d do something like this:</p> 517 518 <com:TTextHighlighter Language="javascript" CssClass="source"> 519 [F.Artists].invoke('sort') 520 //Outputs 36 Crazyfist,As I Lay Dying,In Flames,Shadows Fall,Trivium 521 </com:TTextHighlighter> 522 523 <p>Why not just use <tt>F.Artists.sort</tt>? Well, for the example above 524 we could do just that, but here is where <tt>invoke</tt> shines.</p> 525 526 <com:TTextHighlighter Language="javascript" CssClass="source"> 527 [F.Artists, F.Letters].invoke('sort'); 528 //Outputs 36 Crazyfist,As I Lay Dying,In Flames,... 529 </com:TTextHighlighter> 530 <p>So we invoked sort for each sub-array. Note that the code below will not work.</p> 531 532 <com:TTextHighlighter Language="javascript" CssClass="source"> 533 F.Artists.invoke('sort'); 534 </com:TTextHighlighter> 535 536 <p>The reason this will not work is because it is taking each item 537 in that array and trying to apply sort to it, thus if we wrote it outright, 538 it would look something like this:</p> 539 540 <com:TTextHighlighter Language="javascript" CssClass="source"> 541 "36 Crazy Fists".sort(); 542 </com:TTextHighlighter> 543 <p>We could however do something like this:</p> 544 545 <com:TTextHighlighter Language="javascript" CssClass="source"> 546 F.Artists.invoke('toLowerCase'); 547 //Outputs 36 crazyfist,as i lay dying,in flames,shadows ... 548 </com:TTextHighlighter> 549 550 <p> 551 Now, what about passing arguments to the <tt>invoke</tt> function? 552 The first argument passed to <tt>invoke</tt> is the method to be invoked, 553 and any other arguments beyond that will be passed as arguments to the invoked method.</p> 554 555 <com:TTextHighlighter Language="javascript" CssClass="source"> 556 F.Artists.invoke('concat', " is awesome ") 557 //Outputs 558 36 Crazyfist is awesome ,As I Lay Dying is awesome ,... 559 </com:TTextHighlighter> 560 561 </com:TContent>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |