Quick Guide to Prototype

来源:百度文库 编辑:神马文学网 时间:2024/04/30 01:20:42
JavaScript’s increasing popularity throughout the web makes it moreimportant than ever to make sure our client side code is implementedwith a nice mix of stability, speed, and reusability. One of the bestways for accomplishing this is to use a simple library and syntax touse as a foundation for every project. Thankfully,Sam Stephenson created an amazing library of functions that we can rely on calledPrototype.js to ease our JavaScript development practices.

After our readerspointed out in an previous feature that our frequent use ofPrototypesyntax was making things a bit confusing, we decided it would be bestto create a quick reference page for the library to help ease thelearning curve for a lot of developers out there. The followingtutorial will explain the most common methods used in Particletreeprojects with simple examples of how to implement them. This guide ismeant to be used hand-in-hand with the more exhaustiveunofficial Prototype documentation by Sergio Pereira, and thescript.aculo.us documentation wiki, which I highly recommend every serious JavaScript / Prototype developer read.
Getting Started
After you havedownloaded the files and placed them in your preferred directory, all you need to do is include them in your html document like so:

Boom. JavaScript just got 10x easier to develop. Now, let’s looks at some of the cool new weapons you just acquired.
Note - This tutorial is based off of version 1.3.1.
$() Function
The most used and convenient function, $(), provides aneasy way of getting a handle on a DOM element. Normally, if you wouldlike to access an element in the DOM, it would look like this:
node = document.getElementById("elementID");
Using $(), we can shorten it up.
node = $("elementID");
Other than being short and sweet, the $() function is also more powerful than document.getElementById() because the ability to retrieve multiple elements is built into the function.
allNodes = $("firstDiv", "secondDiv");for(i = 0; i < allNodes.length; i++) {alert(allNodes[i].innerHTML);}
In this example, we see the $() function now returning an array of our elements, which can then be accessed with a simple for loop.
Form Helper Functions
Yes, not only are forms a pain in the ass from an HTML and CSSperspective, but also on the JavaScript side of things. Prototype.jsprovides useful and creative functions that make dealing with formsalmost fun.
The $F() function returns the value of the form element or ID passed in. If we put together the following HTML fields:

We can then access the values in the form easily by using the $F() function.
$F("textfield"); // returns the value of the text input$F("areafield"); // returns the value of the textarea$F("selectfield"); // returns the selected value of the select$F("checkfield"); // returns undefined if not checked, or the value
The ability to get a value regardless of the control makesprocessing forms incredibly easy in most circumstances. There are onlytwo drawbacks I could find with this function: 1) there is no easy wayof accessing the selected value of a radio group (only the individualvalue of a single radio element) and 2) it is not possible to pass inmultiple ID’s, like you can with the $() function.
*Another function, Form.getElements() will return an array of every form element, regardless of the type.
allNodes = Form.getElements("myform");for(i = 0; i < allNodes.length; i++) {//do something to each form field}
In this example, we’re getting every element from a form with the id of myform. If you want to add an onclick effect, or a help window popup to each form field, you can loop through as shown above.
The next method we will look at is Form.serialize().When building an Ajax request, you often need to format your own poststring to pass the data. When the form is submitted, that string isbuilt. serialize() makes the process easy.
allNodes = Form.serialize("myform");// returns field1=value1&field2=value2&field3=value3 and so on...
Building the string for us helps out, but what makes the method evennicer is that it is not biased towards the type of field. We saw beforethat $F() had some problems with radio groups, but serialize()processes all of the values correctly for any type of field. These arenot the only form methods available, so go check out theSergio’s documentation for the rest.
getElementsByClassName
Why getElementsByClassName()is not already built intoJavaScript is beyond me, but it’s not and so Prototype had added to itto the arsenal as an extension of the document object. It behavesexactly like document.getElementsByTagName(), the only difference being that it checks for className.
allNodes = document.getElementsByClassName("red");for(i = 0; i < allNodes.length; i++) {alert(allNodes[i].innerHTML);}
An array is returned containing all elements that match the givenclassName. This will also work with elements that have multipleclassNames, which is nice. getElementsByClassName() hasbecome a function used in nearly every project around here, mainly toattach DOM events so I suggest every developer give it a try.
Element Helper Functions
The Element Object provides a load of helper functions (increasingwith each release) that assist in common DOM manipulation practices.Some of these functions create no new ease, while others simplify 10+lines of code into one call. Let’s take a look at some examples.
Retrieving the height of an element without the helper:
$("first").offsetHeight
And now with the helper:
Element.getHeight("first")
In this case, the helper arguably provides no benefit. Now, what ifwe wanted to remove a className from an element? Here is the long way(taken from the Prototype.js source code):
element = $(element);if (!element)return;var newClassName = ‘‘;var a = element.className.split(‘ ‘);for (var i = 0; i < a.length; i++) {if (a[i] != className) {if (i > 0)newClassName += ‘ ‘;newClassName += a[i];}}element.className = newClassName;
And now with the helper function:
Element.removeClassName("elementID", "red");
Nice, eh? Unlike the first example, most of the helper functionssave a lot of time and effort by making common tasks easy. And for thesake of consistency, it may be best just to use the Element syntaxthroughout the project. For a full list of helper functions and how touse them, check outSergio’s Prototype documentation.
Try.these Function
Try.these() is a great function for helping developerscreate code that will work regardless of the different JavaScriptimplementations across browsers. Instead of doing object or browserdetection on your own, this function will attempt to execute one pathof code until it encounters an error, and then switch to the next path.
return Try.these(function() {alert("first");jkgjhgjhg //intentional erroralert("firsterror");return 1;},function() {alert("second");return 2;});
In the example above, the first path will stop executing at theintentional error. Knowing that, it is important to be cautious withour code because everything before the error will get executed, we mustbe careful not to execute code twice (once in each try). Overall, Try.these() is not a function we use often around here, but it is nice to know it exists and how it functions.
Ajax Support
There is no shortage of Ajax support functions in this library, andI would like to give you a look at how we primarily create Ajaxapplications with the help of Prototype.js. Taken from thedocumentation, we can see a normal Ajax request can be made as follows:
var myAjax = new Ajax.Request(url,{method: ‘post‘, parameters: data, onComplete: ajax_response});
Where method is post or get, parameters is the name/value pairedquery string, and onComplete is the function that should be called wheneverything is finished. Once the core functionality is understood, itis easy to make repetitive Ajax calls by creating our own functionsthat utilize the library. First, a simple function to process the Ajaxrequest.
function ajax_request(url, data) {var myAjax = new Ajax.Request(url,{method: ‘post‘, parameters: data, onComplete: ajax_response});}
And after the request is finished, send it over to ajax_response().
function ajax_response(originalRequest) {if(!bHasRedirect) {//process originalRequest.responseText;}else {bHasRedirect = false;ajax_request(originalRequest.responseText, "");}}
After you make an Ajax request, the response is always sent to ajax-response(). From there, another Ajax request will be made if bHasRedirect is set to true (a global variable), and if not then the proper code will be executed based on a global array of functions and originalRequest.responseText() (the return value).
PeriodicalExecuter
Once the PeriodicalExecuter object is initialized, it repeatedlycalls a desired function at a given interval. This comes in handy whenyou wish to auto update an Ajax portion of your site.
function periodicalUpdate() {new PeriodicalExecuter(refreshNews, 10);}function refreshNews() {//Ajax code to grab news and update DOM}
The PeriodicalExecuter constructor expects the function to call asits first parameter, and the time interval as its second. Don’t getconfused with the time though - the common setInterval() is handled with milliseconds, but in this function we’re dealing with seconds.Also note that while this example assumes Ajax is involved, it canupdate the page for any reason. Prototype.js also has aAjax.PeriodicalUpdater class that can ease the process when dealingsolely with Ajax.
Additional Enhancements
While I can’t cover every single function or method thatPrototype.js offers, it is still important to emphasize some of theones not covered here (all of which can be found in the documentation).
observe - This method functions likeaddEvent(), and should be used to unobtrusively attach events to the DOM.
User Interaction - You can find built in globals, such as KEY_TABto evaluate what key presses the user is making. Additionally, you canfind out the coordinates of the mouse, and if it has been clicked.
Class Creation - Why stop with what Prototype.jsprovides? Using the same syntax and functions, we can build our ownclasses to keep things consistent. Adding a constructor and additionalmethods has never been easier. Lookup Class.create() in the documentation.
Wrap It Up
Is it acceptable to use public code/libraries when you do not knowthe author and do not intimately understand what happens behind thescenes? My answer is yes, as long as you thoroughly test the code andtrust the person/community that is behind the development of it. In thecase of Prototype.js, trust is built from two sources. First,Ruby on Railshas integrated prototype support. Since Ruby on Rails has a respectabledeveloper base, it is likely that many bugs have been found and ironedout to make Prototype.js more stable. Second, the developerworks for 37signals, who happen to employ thecreatorof Ruby on Rails. Not only do I trust the development practices of thecompany, but I trust that Prototype.js will continue to be tested andimproved upon. Given that, and testing within my own projects, Iconfidently use this library in nearly all my projects.
Prototype.js more than doubles the functionality listed in thistutorial, and it is definitely worth checking out. If you’re scared ofthe file size (it’s 30k as of this writing), remember that you canalways take out classes that you don’t use (minus the few that havedependencies) and/or compress your JavaScript files with PHP beforeserving them out to your user. Also, once you have tried a few of themethods, the rest are easy to learn, so the learning curve is veryminimal. Basically, there is no excuse not to give it a try. Theexamples shown above are how we handle things at Particletree, andshould not be used without testing. Remember, this is meant to be anintroduction to Prototype.js, so always reference and give credit totheunofficial Prototype documentation and thescript.aculo.us documentation wikifor all of the hard work put in to find out the various methods. Asalways, if you find any mistakes or possible improvements, please pointthem out.