- 浏览: 148094 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
zhang964761032:
学习学习
不可直译的英语 -
illu:
这个很高端。。。
凉皮的做法 -
cindylu520:
我不回答你,你往话里带我。小样。
The lost lady 败犬女 -
lujinan858:
那你是败犬中得胜犬还是胜犬中的败犬呢?嘿嘿
The lost lady 败犬女 -
dunhuacc12:
能给个学习英语的网站么?你这些题是在哪里弄的啊? 最近想补补 ...
20100316英语学习
最近在学习这个,就在网上google了一下这方面的资料,转载了老外对这个的解读(1.5版本),同时也上传了prototype的1.5 和 1.6 两个版本,希望感兴趣的朋友一起分享。
What is that?
In case you haven't already used it, prototype.js is a JavaScript library initially written by Sam Stephenson. This amazingly well thought and well written piece of standards-compliant code takes a lot of the burden associated with creating rich, highly interactive web pages that characterize the Web 2.0 off your back.
When I first started trying to use this library, a few years ago, I noticed that the documentation was definitely not one of its strongest points. As many other developers before me, I got my head around prototype.js by reading the source code and experimenting with it. I thought it would be nice to take notes while I learned and share with everybody else.
I'm also offering an un-official reference for the objects, classes, functions, and extensions provided by this library.
As you read the examples and the reference, developers familiar with the Ruby programming language will notice an intentional similarity between Ruby's built-in classes and many of the extensions implemented by this library. That's not surprising since prototype.js is a spinoff and is directly influenced by the requirements of the Ruby on Rails framework.
As far as browser support goes, prototype.js tries to support Internet Explorer (Windows) 6.0+, Mozilla Firefox 1.5+, Apple Safari 1.0+, and Opera 9+. Supporting these browsers also cause some other browsers that share their rendering engines to be supported as well, like Camino, Konqueror, IceWeasel, Netscape 6+, SeaMonkey, etc.
Related article
Advanced JavaScript guide.
<!-- ************************************************************************************************************************************* -->
The utility functions
The library comes with many predefined objects and utility functions. The obvious goal of these functions is to save you a lot of repeated typing and idioms.
Using the $() function
The $() function is a handy shortcut to the all-too-frequent document.getElementById() function of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument.
Unlike the DOM function, though, this one goes further. The returned element object will be augmented with some extra methods. These extra methods simplify many tasks, like hiding/showing the element, getting its size, scrolling to the element, etc. You can get a \list of the methods that are added to the returned element object in the reference for the Element.Methods object. Furthermore, if the element is a form it will also receive copies of the utility methods from Form.Methods and if the element is a form field (input, select, or textarea) it will additionally receive copies of the utility methods from Form.Element.Methods.
<html> <head> <title> Test Page </title> <script src="prototype.js"></script> <script> function test(){ var d = $('myDiv'); alert(d.innerHTML); d.hide(); d.show(); d.addClassName('active'); } </script> </head> <body> <div id="myDiv"> <p>This is a paragraph</p> </div> <div id="myOtherDiv"> <p>This is another paragraph</p> </div> <input type="button" value="Test $()" onclick="test();"/><br/> </body> </html>
Because many of the new methods added to the element return the element itself, you can chain the method calls to make more compact code:
//change the text, the CSS class, and make the element visible $('messageDiv').update('Your order was accepted.').addClassName('operationOK').show();
Another nice thing about this function is that you can pass either the id string or the element object itself, which makes this function very useful when creating other functions that can also take either form of argument.
<!--****************************************************************************-->
Using the $$() function
The $$() function will help you a lot if you consistently separate CSS from the content wireframe. It parses one or more CSS filtering expressions, analogous to the ones used to define CSS rules, and returns the elements that match these filters.
It's so easy to use it's ridiculous. Check this out.
<script> function test$$(){ /* in case CSS is not your forte, the expression below says 'find all the INPUT elements that are inside elements with class=field that are inside a DIV with id equal to loginForm.' */ var f = $$('div#loginForm .field input'); var s = ''; for(var i=0; i<f.length; i++){ s += f[i].value + '/'; } alert(s); // shows: "joedoe1/secret/" //now passing more than one expression f = $$('div#loginForm .field input', 'div#loginForm .fieldName'); s = ''; for(var i=0; i<f.length; i++){ s += ( f[i].value ? f[i].value : f[i].innerHTML ) + '/'; } alert(s); //shows: "joedoe1/secret/User name:/Password:/" } </script> <div id='loginForm'> <div class='field'> <span class='fieldName'>User name:</span> <input type='text' id='txtName' value='joedoe1'/> </div> <div class='field'> <span class='fieldName'>Password:</span> <input type='password' id='txtPass' value='secret' /> </div> <input type='submit' value='login' /> </div> <input type=button value='test $$()' onclick='test$$();' />
A quick note on performance. The current implementation of the $$() function in prototype.js is not regarded as particularly efficient. If you plan on traversing deep and complex HTML documents using this function frequently, you may want to consider other freely available implementations, possibly simply substituting the $$() function itself.
<!-- *************************************************************************-->
Using the $F() function
The $F() function is another welcome shortcut. It returns the value of any field input control, like text boxes or drop-down lists. The function can take as argument either the element id or the element object itself.
<script> function test3() { alert( $F('userName') ); } </script> <input type="text" id="userName" value="Joe Doe"><br/> <input type="button" value="Test3" onclick="test3();"><br/>
Using the $A() function
The $A() function converts the single argument it receives into an Array object.
This function, combined with the extensions for the Array class, makes it easier to convert or copy any enumerable list into an Array object. One suggested use is to convert DOM NodeLists into regular arrays, which can be traversed more efficiently. See example below.
<script> function showOptions(){ var someNodeList = $('lstEmployees').getElementsByTagName('option'); var nodes = $A(someNodeList); nodes.each(function(node){ alert(node.nodeName + ': ' + node.innerHTML); }); } </script> <select id="lstEmployees" size="10" > <option value="5">Buchanan, Steven</option> <option value="8">Callahan, Laura</option> <option value="1">Davolio, Nancy</option> </select> <input type="button" value="Show the options" onclick="showOptions();" >
Using the $H() function
The $H() function converts objects into enumerable Hash objects that resemble associative arrays.
<script> function testHash() { //let's create the object var a = { first: 10, second: 20, third: 30 }; //now transform it into a hash var h = $H(a); alert(h.toQueryString()); //displays: first=10&second=20&third=30 } </script>
Using the $R() function
The $R() function is simply a short hand to writing new ObjectRange(lowerBound, upperBound, excludeBounds).
Jump to the ObjectRange class documentation for a complete explanation of this class. In the meantime, let's take a look at a simple example that also shows the usage of iterators through the each method. More on that method will be found in the Enumerable object documentation.
<script> function demoDollar_R(){ var range = $R(10, 20, false); range.each(function(value, index){ alert(value); }); } </script> <input type="button" value="Sample Count" onclick="demoDollar_R();" />
Using the Try.these() function
The Try.these() function makes it easy when you want to, ahem, try different function calls until one of them works. It takes a number of functions as arguments and calls them one by one, in sequence, until one of them works, returning the result of that successful function call.
In the example below, the function xmlNode.text works in some browsers, and xmlNode.textContent works in the other browsers. Using the Try.these() function we can return the one that works.
<script> function getXmlNodeValue(xmlNode){ return Try.these( function() {return xmlNode.text;}, function() {return xmlNode.textContent;} ); } </script>
Tricked out strings
Strings are powerful objects. Prototype.js takes that power and elevates it by another level of magnitude.
<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
String substitutions
When it comes string substitutions JavaScript already has the methods like String.Replace, which even works with regular expressions, but it's still not as flexible as the alternative introduced by prototype.js.
Meet the new String.gsub method. With this method you can not only find and replace a fixed string or a regular expression pattern, but you also have much more control over the replacement process. You can, for example, use a string template to instruct the method on how you would like the found elements to be transformed (rather than simply replaced.)
The example below searches for words containing 't' and replaces the portion that comes after the 't' with 'tizzle', in a lame shot at being funny. In case the example is not very clear, the regular expression we chose has a capture group declaration: the \w+ enclosed in parenthesis. We can get the value captured by this group using #{1} in the replacement template string.
In our example we are capturing what comes before the 't' and appending 'tizzle' to it. If we had more capture groups in the regular expression, we would get the values with #{2}, #{3}, and so on.
<script> function talkLikeYouKnowSomething(){ var s = 'prototype string extensions can help you'; var snoopdogfy = /\b(\w+)t\w+\b/; var snooptalk = s.gsub(snoopdogfy, '#{1}tizzle' ); alert(snooptalk); // shows: "prototizzle stizzle extizzle can help you" } </script>
Let's not stop there. The substitution we have just made is not all that powerful because we are limited to pattern matching and substitutions. What if we could operate on the matches with custom logic to produce the desired substitution vaues? We can do that if we pass a function as the second argument to gsub. The function will receive an array with the matched text (index 0) and any capture group values (index 1 to N.)
<script> function scamCustomers(){ var prices = 'book1 $12.5, magazine $5.50, pencil $1.20'; var priceFinder = /\$([0-9\.]+)/; var r = prices.gsub(priceFinder, jackUp); alert(r);//shows: "book1 $13.75, magazine $6.05, pencil $1.32" } function jackUp(matches){ //increases the prices by 10% var price = parseFloat(matches[1]); return '$' + Math.round(110 * price)/100; } </script>
String templates
As you increase the amount of JavaScript code in your applications, increasingly you'll find yourself with collections of objects of the same type and that you need to list or present in a formatted way.
It's not rare to find code in your applications that loops through a list of objects, building a string based on the object properties and some fixed formatting elements. Prototype.js comes with the Template class, which aims at helping you with exactly this type of scenarios.
The example below shows how to format a list of items in a shopping cart in multiple HTML lines.
<script> function printCart(){ //creating a sample cart var cart = new Object(); cart.items = [ ]; //putting some sample items in the cart cart.items.push({product: 'Book 123', price: 24.50, quantity: 1}); cart.items.push({product: 'Set of Pens', price: 5.44, quantity: 3}); cart.items.push({product: 'Gift Card', price: 10.00, quantity: 4}); //here we create our template for formatting each item var itemFormat = new Template( 'You are ordering #{quantity} units ' + 'of #{product} at $#{price} each' ); var formatted = ''; for(var i=0; i<cart.items.length; i++){ var cartItem = cart.items[i]; formatted += itemFormat.evaluate(cartItem) + '<br/>\n'; } alert(formatted); /* SHOWS: You are ordering 1 units of Book 123 at $24.5 each<br/> You are ordering 3 units of Set of Pens at $5.44 each<br/> You are ordering 4 units of Gift Card at $10 each<br/> */ } </script>
For a more complete list of new methods, see the String extensions reference.
<!-- ************************************************************************************************************************************* -->
The Ajax object
The utility functions mentioned above are nice but, let's face it, they are not the most advanced type of thing, now are they? You could probably have done it yourself and you may even have similar functions in your own scripts. But those functions are just the tip of the iceberg.
I'm sure that your interest in prototype.js is driven mostly by its AJAX capabilities. So let's explain how the library makes your life easier when you need to perform AJAX logic.
The Ajax object is a pre-defined object, created by the library to wrap and simplify the tricky code that is involved when writing AJAX functionality. This object contains a number of classes that provide encapsulated AJAX logic. Let's take a look at some of them.
<!-- ***************************************************************************-->
Using the Ajax.Request class
If you are not using any helper library, you are probably writing a whole lot of code to create a XMLHttpRequest object and then track its progress asynchronously, then extract the response and process it. And consider yourself lucky if you do not have to support more than one type of browser.
To assist with AJAX functionality, the library defines the Ajax.Request class.
Let's say you have an application that can communicate with the server via the url http://yourserver/app/get_sales?empID=1234&year=1998, which returns an XML response like the following.
<?xml version="1.0" encoding="utf-8" ?> <ajax-response> <response type="object" id="productDetails"> <monthly-sales> <employee-sales> <employee-id>1234</employee-id> <year-month>1998-01</year-month> <sales>$8,115.36</sales> </employee-sales> <employee-sales> <employee-id>1234</employee-id> <year-month>1998-02</year-month> <sales>$11,147.51</sales> </employee-sales> </monthly-sales> </response> </ajax-response>
Talking to the server to retrieve this XML is pretty simple using an Ajax.Request object. The sample below shows how it can be done.
<script> function searchSales() { var empID = $F('lstEmployees'); var y = $F('lstYears'); var url = 'http://yourserver/app/get_sales'; var pars = 'empID=' + empID + '&year=' + y; var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: showResponse }); } function showResponse(originalRequest) { //put returned XML in the textarea $('result').value = originalRequest.responseText; } </script> <select id="lstEmployees" size="10" onchange="searchSales()"> <option value="5">Buchanan, Steven</option> <option value="8">Callahan, Laura</option> <option value="1">Davolio, Nancy</option> </select> <select id="lstYears" size="3" onchange="searchSales()"> <option selected="selected" value="1996">1996</option> <option value="1997">1997</option> <option value="1998">1998</option> </select> <br/><textarea id="result" cols=60 rows=10 ></textarea>
Can you see the second parameter passed to the constructor of the Ajax.Request object? The parameter {method: 'get', parameters: pars, onComplete: showResponse} represents an anonymous object in literal notation (a.k.a. JSON). What it means is that we are passing an object that has a property named method that contains the string 'get', another property named parameters that contains the querystring of the HTTP request, and an onComplete property/method containing the function showResponse.
There are a few other properties that you can define and populate in this object, like asynchronous, which can be true or false and determines if the AJAX call to the server will be made asynchronously (the default value is true.)
This parameter defines the options for the AJAX call. In our sample, we are calling the url in the first argument via a HTTP GET command, passing the querystring contained in the variable pars, and the Ajax.Request object will call the showResponse function when it finishes retrieving the response.
As you may know, the XMLHttpRequest reports progress during the HTTP call. This progress can inform four different stages: Loading, Loaded, Interactive, or Complete. You can make the Ajax.Request object call a custom function in any of these stages, the Complete being the most common one. To inform the function to the object, simply provide property/methods named onXXXXX in the request options, just like the onComplete from our example. The function you pass in will be called by the object with two arguments, the first one will be the XMLHttpRequest (a.k.a. XHR) object itself and the second one will be the evaluated X-JSON response HTTP header (if one is present). You can then use the XHR to get the returned data and maybe check the status property, which will contain the HTTP result code of the call. The X-JSON header is useful if you want to return some script or JSON-formatted data.
Two other interesting options can be used to process the results. We can specify the onSuccess option as a function to be called when the AJAX call executes without errors and, conversely, the onFailure option can be a function to be called when a server error happens. Just like the onXXXXX option functions, these two will also be called passing the XHR that carried the AJAX call and the evaluated X-JSON header.
Our sample did not process the XML response in any interesting way. We just dumped the XML in the textarea. A typical usage of the response would probably find the desired information inside the XML and update some page elements, or maybe even some sort of XSLT transformation to produce HTML in the page.
There's also another form of event callback handling available. If you have code that should always be executed for a particular event, regardless of which AJAX call caused it to happen, then you can use the new Ajax.Responders object.
Let's suppose you want to show some visual indication that an AJAX call is in progress, like a spinning icon or something of that nature. You can use two global event handlers to help you, one to show the icon when the first call starts and another one to hide the icon when the last one finishes. See example below.
<script> var myGlobalHandlers = { onCreate: function(){ Element.show('systemWorking'); }, onComplete: function() { if(Ajax.activeRequestCount == 0){ Element.hide('systemWorking'); } } }; Ajax.Responders.register(myGlobalHandlers); </script> <div id='systemWorking'><img src='spinner.gif'>Loading...</div>
For more complete explanations, see the Ajax.Request reference and the options reference.
<!-- ****************************************************************************-->
Using the Ajax.Updater class
If you have a server endpoint that can return information already formatted in HTML, the library makes life even easier for you with the Ajax.Updater class. With it you just inform which element should be filled with the HTML returned from the AJAX call. An example speaks better than I can write.
<script> function getHTML() { var url = 'http://yourserver/app/getSomeHTML'; var pars = 'someParameter=ABC'; var myAjax = new Ajax.Updater( 'placeholder', url, { method: 'get', parameters: pars }); } </script> <input type="button" value="GetHtml" onclick="getHTML()"/> <div id="placeholder"></div>
As you can see, the code is very similar to the previous example, with the exclusion of the onComplete function and the element id being passed in the constructor. Let's change the code a little bit to illustrate how it is possible to handle server errors on the client.
We will add more options to the call, specifying a function to capture error conditions. This is done using the onFailure option. We will also specify that the placeholder only gets populated in case of a successful operation. To achieve this we will change the first parameter from a simple element id to an object with two properties, success (to be used when everything goes OK) and failure (to be used when things go bad.) We will not be using the failure property in our example, just the reportError function in the onFailure option.
<script> function getHTML() { var url = 'http://yourserver/app/getSomeHTML'; var pars = 'someParameter=ABC'; var myAjax = new Ajax.Updater( {success: 'placeholder'}, url, { method: 'get', parameters: pars, onFailure: reportError }); } function reportError(request) { alert('Sorry. There was an error.'); } </script> <input type="button" value="GetHtml" onclick="getHTML()"/> <div id="placeholder"></div>
If your server logic returns JavaScript code along with HTML markup, the Ajax.Updater object can evaluate that JavaScript code. To get the object to treat the response as JavaScript, you simply add evalScripts: true; to the list of properties in the last argument of the object constructor. But there's a caveat. Those script blocks will not be added to the page's script. As the option name evalScripts suggests, the scripts will be evaluated. What's the difference, you may ask? Lets assume the requested URL returns something like this:
<script language="javascript" type="text/javascript"> function sayHi(){ alert('Hi'); } </script> <input type="button" value="Click Me" onclick="sayHi()"/>
In case you've tried it before, you know it doesn't work. The reason is that the script block will be evaluated, and evaluating a script like the above will not create a function named sayHi. It will do nothing. To create this function we need to change our script to create the function. See below.
<script language="javascript" type="text/javascript"> sayHi = function(){ alert('Hi'); }; </script> <input type="button" value="Click Me" onclick="sayHi()"/>
Note that in the previous example we did not use the var keyword to declare the variable. Doing so would have created a function object that would be local to the script block (at least in IE). Without the var keyword the function object is scoped to the window, which is our intent.
For more complete explanations, see the Ajax.Updater reference and the options reference.
<!-- ***************************************************************************-->
What are all those "?" and squares?
So you went and wrote some quick test scripts to update your pages using the Ajax.Updater object and it all worked fine. Life was good until you ran your scripts against real data. All of a sudden the updated text was displayed with question marks or unprintable character symbols where the non-English characters should be.
Your first suspect is prototype.js, Of course, it seemed too easy to be true. But don't blame the library just yet. Ask yourself how much you really understand character encoding, code pages, and how the browser deals with it. If you have a positive answer then I bet you are on your way to fix the problem. If you are among the other 80% (another useless, imprecise author's estimate) of web developers that take character encoding for granted, keep reading.
I won't pretend to be an authority on the topic, much less give you a complete explanation of how this is best handled. Instead you go straight to the solution that I use and provide hints on how this could be fixed in your own scenario.
Simply put, the solution revolves around the following statement: Serve what the browser is expecting you to serve. If we are going to update the page with text that contains Unicode/UTF-8 characters then we better make the browser aware of that.
Let's start with the simple case when you are just updating the page with text from a static HTML file that resides on your server. When you created that file, depending on which text editor you employed, it is very possible that the file was saved in ANSI (or better said, non-Unicode) format. This is the default for many text editors, especially source code editors, because the file size will be smaller and it's rather unusual to edit source code with Unicode characters in it.
Suppose you have the following file named static-content.html on your server. You saved this file saved in ANSI format.
<div> Hi there, José. Yo no hablo español. </div>
Your main page updates itself using something like the snippet below.
<script> function updateWithFile(){ var url = 'static-content.html'; var pars = ''; var myAjax = new Ajax.Updater( 'placeholder', url, {method: 'get', parameters: pars}); } </script> <div id="placeholder">(this will be replaced)</div> <input id="btn" value="Test With Static File" onclick="updateWithFile()" type="button"/>
When you click the button the static file is retrieved but the non-English characters are replaced by question marks or some other symbol. The displayed text will look similar to "Hi there, Jos?. Yo no hablo espa?ol." or "Hi there, Jos?Yo no hablo espa?", depending on your browser.
In this case, the solution is straightforward, simply save the static file in an appropriate format. Let's save it in UTF-8 and run the script again (any decent text editor will have an option in the Save As dialog.) You should now see the correct text (if not, your browser may have cached the old version, try using a different file name.)
If the HTML that you are serving is not static, if it is being dynamically generated by some application framework (like ASP.NET, PHP, or even Perl,) make sure the code that generates this HTML is producing the text in the appropriate encoding and code page, and include in the HTTP response headers one header that informs this. Each platform has a different way to achieve this, but they are very similar.
For example, in ASP.NET you can set this globally in your web.config file and the default configuration is good enough to avoid this problem in the first place. You should already have the following section in your web.config.
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
In classic ASP 3.0 you can fix this problem using the following code.
Response.CodePage = 65001 Response.CharSet = "utf-8"
In PHP the syntax to add the response header looks like this.
<?php header('Content-Type: text/html; charset=utf-8'); ?>
In any case, your ultimate goal is to have the following HTTP header sent with your response.
Content-Type: text/html; charset=utf-8
We used UTF-8 in our examples above, but if you need a different setting you can easily change.
Enumerating... Wow! Damn! Wahoo!
We are all familiar with for loops. You know, create yourself an array, populate it with elements of the same kind, create a loop control structure (for, foreach, while, repeat, etc,) access each element sequentially, by its numeric index, and do something with the element.
When you come to think about it, almost every time you have an array in your code it means that you'll be using that array in a loop sooner or later. Wouldn't it be nice if the array objects had more functionality to deal with these iterations? Yes, it would, and many programming languages provide such functionality in their arrays or equivalent structures (like collections and lists.)
Well, it turns out that prototype.js gives us the Enumerable object, which implements a plethora of tricks for us to use when dealing with iterable data. The prototype.js library goes one step further and extends the Array class with all the methods of Enumerable.
Loops, Ruby-style
In standard javascript, if you wanted to sequentially display the elements of an array, you could very well write something like this.
<script> function showList(){ var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Maggie']; for(i=0;i<simpsons.length;i++){ alert(simpsons[i]); } } </script> <input type="button" value="Show List" onclick="showList();" />
With our new best friend, prototype.js, we can rewrite this loop like this.
function showList(){ var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Maggie']; simpsons.each( function(familyMember){ alert(familyMember); }); }
You are probably thinking "big freaking deal...just a weird syntax for the same old thing." Well, in the above example, yes, there's nothing too earth shattering going on. After all, there's not much to be changed in such a drop-dead-simple example. But keep reading, nonetheless.
Before we move on. Do you see this function that is being passed as an argument to the each method? Let's start referring to it as an iterator function.
Your arrays on steroids
Like we mentioned above, it's very common for all the elements in your array to be of the same kind, with the same properties and methods. Let's see how we can take advantage of iterator functions with our new souped-up arrays.
Here's how to find an element according to criteria.
<script> function findEmployeeById(emp_id){ var listBox = $('lstEmployees') var options = listBox.getElementsByTagName('option'); options = $A(options); var opt = options.find( function(employee){ return (employee.value == emp_id); }); alert(opt.innerHTML); //displays the employee name } </script> <select id="lstEmployees" size="10" > <option value="5">Buchanan, Steven</option> <option value="8">Callahan, Laura</option> <option value="1">Davolio, Nancy</option> </select> <input type="button" value="Find Laura" onclick="findEmployeeById(8);" />
Now let's kick it up another notch. See how we can filter out items in arrays, and then retrieve just a desired member from each element.
<script> function showLocalLinks(paragraph){ paragraph = $(paragraph); var links = $A(paragraph.getElementsByTagName('a')); //find links that do not start with 'http' var localLinks = links.findAll( function(link){ //we'll just assume for now that external links // do not have a '#' in their url return link.href.indexOf('#') >= 0; }); //now the link texts var texts = localLinks.pluck('innerHTML'); //get them in a single string var result = texts.inspect(); alert(result); } </script> <p id="someText"> This <a href="http://othersite.com/page.html">text</a> has a <a href="#localAnchor">lot</a> of <a href="#otherAnchor">links</a>. Some are <a href="http://wherever.com/page.html">external</a> and some are <a href="#someAnchor">local</a> </p> <input type="button" value="Find Local Links" onclick="showLocalLinks('someText')"/>
It takes just a little bit of practice to get completely addicted to this syntax. Take a look at the Enumerable and Array references for all the available functions.
<!-- ************************************************************************************************************************************* --><!-- Translators: please ignore and remove this book reference stuff -->
Books I strongly recommend
Some books are just too good not to pass the word forward. The following books have helped me a lot learning the new skills required to adequately create AJAX applications and also consolidate the skills I though I already mastered. I think a good book is money well-spent, that keep paying for itself for a long time.
Reference for prototype.js Extensions to the JavaScript classes One of the ways the prototype.js library adds functionality is by extending the existing JavaScript classes. Extensions for the Object class
extend(destination, source) | static | destination: any object, source: any object | Provides a way to implement inheritance by copying all properties and methods from source to destination. |
inspect(targetObj) | static | targetObj: any object | Returns a human-readable string representation of targetObj. It defaults to the return value of toString if the given object does not define an inspect instance method. |
keys(targetObj) | static | targetObj: any object | Returns an Array with the names of all the properties and methods of given object. |
values(targetObj) | static | targetObj: any object | Returns a Array with the values of all the properties and methods of given object. |
clone(targetObj) | static | targetObj: any object | Returns a shallow copy of targetObj. |
Extensions for the Number class
olorPart() | instance | (none) | Returns the hexadecimal representation of the number. Useful when converting the RGB components of a color into its HTML/CSS representation. |
succ() | instance | (none) | Returns the next number. This function is used in scenarios that involve iterations. |
times(iterator) | instance | iterator: a function object conforming to Function(index) | Calls the iterator function repeatedly passing the current index in the index argument. |
The following sample will display alert message boxes from 0 to 9.
<script> function demoTimes(){ var n = 10; n.times(function(index){ alert(index); }); /*************************** * you could have also used: * (10).times( .... ); ***************************/ } </script> <input type="button" value="Test Number.times()" onclick="demoTimes()"/>
Extensions for the Function class
bind(object [, arg1 [, arg2 [...]]]) | instance | object: the object that owns the method | Returns an instance of the function pre-bound to the function(=method) owner object. The returned function will use the same arguments as the original one (arg1, arg2, ... etc). |
bindAsEventListener(object [, arg1 [, arg2 [...]]]) | instance | object: the object that owns the method | Returns an instance of the function pre-bound to the function(=method) owner object. The returned function will have the current event object as its first argument followed optionally any other arguments passed after the object argument. |
Let's see one of these extensions in action.
<input type="checkbox" id="myChk" value="1"/> Test? <script> //declaring the class var CheckboxWatcher = Class.create(); //defining the rest of the class implementation CheckboxWatcher.prototype = { initialize: function(chkBox, message) { this.chkBox = $(chkBox); this.message = message; //assigning our method to the event this.chkBox.onclick = this.showMessage.bindAsEventListener(this, ' from checkbox'); }, showMessage: function(evt, extraInfo) { alert(this.message + ' (' + evt.type + ')' + extraInfo); } }; var watcher = new CheckboxWatcher('myChk', 'Changed'); </script>
Extensions for the String class
camelize() | instance | (none) | Converts a hyphen-delimited-string into a camelCaseString. This function is useful when writing code that deals with style properties, for example. |
capitalize() | instance | (none) | Converts the first character to upper case. |
dasherize() | instance | (none) | Replaces underscores '_' with dashes '-'. |
escapeHTML() | instance | (none) | Returns the string with any HTML markup characters properly escaped |
evalScripts() | instance | (none) | Evaluates each <script /> block found in the string. |
extractScripts() | instance | (none) | Returns an Array object containing all the <script /> blocks found in the string. |
gsub(pattern, replacement) | instance | pattern: string or regular expression being searched. replacement: simple string, template string, or Function(strings[]) to produce the replacements. | Returns a string that results from finding (or matching) the pattern string (or regular expression) in the current string and replacing it with the replacement string or the result of calling the replacement function passing an array with the strings that matched the pattern, including eventual regular expression groupings. When the replacement is a string, it can contain special templating tokens like #{n}, where n is the index of a grouping in the regular expession. #{0} will be replaced by the entire match, #{1} the first grouping, #{2} the second, and so on. |
parseQuery() | instance | (none) | Same as toQueryParams(). |
scan(pattern, replacement) | instance | pattern: string or regular expression being searched. replacement: Function(strings[]) to iterate over the matches. | Provides a way to iterate over matched patterns in the string and operate on them. The pattern argument can be a string or a RegExp but a RegExp is evidently more useful. Similarly, the replacement argument can be a string or a function but it probably only makes sense to pass in a function to be able to produce anything useful. |
strip() | instance | (none) | Returns the string without any leading or trailing white spaces. |
stripScripts() | instance | (none) | Returns the string with any <script /> blocks removed |
stripTags() | instance | (none) | Returns the string with any HTML or XML tags removed |
sub(pattern, replacement [, count]) | instance | pattern: string or regular expression being searched. replacement: string, or Function(strings[]) to produce the replacements. count: number or replacements to perform - defaults to 1. | Very similar to gsub but only performs a limited number of replacements, specified by the count parameter. |
toArray() | instance | (none) | Splits the string into an Array of its characters. |
toQueryParams() | instance | (none) | Splits a querystring into an associative Array indexed by parameter name (more like a hash). |
truncate(length [, truncation]) | instance | length: maximum length of the resulting string. truncation: string used to replace the last characters of the resulting string - defaults to '...' | Used to produce a string of a known maximum length. In case the string needs to be truncated to maintain the maximum length, the text given in the truncation argument is used to replace the last few characters. (e.g.: var s='123456790'; alert(s.truncate(5)); //displays '12...' ) |
underscore() | instance | (none) | Converts a CamelizedStringValue into a uderscore_formatted_string. (e.g.: var s='Namespace::MyClass123'; alert(s.underscore()); //displays 'namespace/my_class123' ). This function seems to be directly target at supporting Ruby on Rails functionality. |
unescapeHTML() | instance | (none) | The reverse of escapeHTML() |
<!-- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
Extensions for the Array class
To start off, Array extends Enumerable, so all the handy methods defined in the Enumerable object are available. Besides that, the methods listed below are also implemented.
clear() | instance | (none) | Empties the array and returns itself. |
compact() | instance | (none) | Returns the array without the elements that are null or undefined. This method does not change the array itself |
first() | instance | (none) | Returns the first element of the array. |
flatten() | instance | (none) | Returns a flat, one-dimensional version of the array. This flattening happens by finding each of the array's elements that are also arrays and including their elements in the returned array, recursively. |
indexOf(value) | instance | value: what you are looking for. | Returns the zero-based position of the given value if it is found in the array. Returns -1 if value is not found. |
inspect() | instance | (none) | Overridden to return a nicely formatted string representation of the array with its elements. |
last() | instance | (none) | Returns the last element of the array. |
reverse([applyToSelf]) | instance | applyToSelf: indicates if the array itself should also be reversed. | Returns the array in reverse sequence. If no argument is given or if the argument is true the array itself will be changed. Otherwise it will remain unchanged. |
shift() | instance | (none) | Returns the first element and removes it from the array, reducing the array's length by 1. |
without(value1 [, value2 [, .. valueN]]) | instance | value1 ... valueN: values to be excluded if present in the array. | Returns the array excluding the elements that are included in the list of arguments. This method does not change the array itself. |
Let's see some of these methods in action.
<script> var A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; alert(A.inspect()); // "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']" var B = A.without('e','f'); alert(B.inspect()); // "['a', 'b', 'c', 'd', 'g', 'h']" alert(A.inspect()); // did not change A: "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']" A.push(null); A.push('x'); A.push(null); A.push('y'); alert(A.inspect()); // "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', null, 'x', null, 'y']" A = A.compact(); alert(A.inspect()); // "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y']" var e = A.shift(); alert(e); // "a" alert(A.inspect()); // "['b', 'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y']" alert(A.indexOf('c')); // 1 alert(A.first()); // 'b' alert(A.last()); // 'y' A.clear(); alert(A.inspect()); // "[]" A = ['a', 'b', 'c']; B = A.reverse(false); alert(B.inspect()); // "['c', 'b', 'a']" alert(A.inspect()); // A left untouched: "['a', 'b', 'c']" A.reverse(true); alert(A.inspect()); // "['c', 'b', 'a']" A = ['a', 'b', ['c1','c2','c3'] , 'd', ['e1','e2'] ]; B = A.flatten(); alert(B.inspect()); // "['a','b','c1','c2','c3','d','e1','e2']" alert(A.inspect()); // unchanged: "['a','b',['c1','c2','c3'],'d',['e1','e2']]" </script>
Extensions for the document DOM object
getElementsByClassName(className [, parentElement]) | instance | className: name of a CSS class associated with the elements, parentElement: object or id of the element that contains the elements being retrieved. | Returns all the elements that are associated with the given CSS class name. If no parentElement id given, the entire document body will be searched. |
<!-- ***********************************************************************************-->
Extensions for the Event object
KEY_BACKSPACE | Number | 8: Constant. Code for the Backspace key. |
KEY_TAB | Number | 9: Constant. Code for the Tab key. |
KEY_RETURN | Number | 13: Constant. Code for the Return key. |
KEY_ESC | Number | 27: Constant. Code for the Esc key. |
KEY_LEFT | Number | 37: Constant. Code for the Left arrow key. |
KEY_UP | Number | 38: Constant. Code for the Up arrow key. |
KEY_RIGHT | Number | 39: Constant. Code for the Right arrow key. |
KEY_DOWN | Number | 40: Constant. Code for the Down arrow key. |
KEY_DELETE | Number | 46: Constant. Code for the Delete key. |
observers: | Array | List of cached observers. Part of the internal implementation details of the object. |
element(event) | static | event: an Event object | Returns element that originated the event. |
isLeftClick(event) | static | event: an Event object | Returns true if the left mouse button was clicked. |
pointerX(event) | static | event: an Event object | Returns the x coordinate of the mouse pointer on the page. |
pointerY(event) | static | event: an Event object | Returns the y coordinate of the mouse pointer on the page. |
stop(event) | static | event: an Event object | Use this function to abort the default behavior of an event and to suspend its propagation. |
findElement(event, tagName) | static | event: an Event object, tagName: name of the desired tag. | Traverses the DOM tree upwards, searching for the first element with the given tag name, starting from the element that originated the event. |
observe(element, name, observer, useCapture) | static | element: object or id, name: event name (like 'click', 'load', etc), observer: function(evt) to handle the event, useCapture: if true, handles the event in the capture phase and if false in the bubbling phase. | Adds an event handler function to an event. |
stopObserving(element, name, observer, useCapture) | static | element: object or id, name: event name (like 'click'), observer: function that is handling the event, useCapture: if true handles the event in the capture phase and if false in the bubbling phase. | Removes an event handler from the event. |
_observeAndCache(element, name, observer, useCapture) | static | Private method, do not worry about it. | |
unloadCache() | static | (none) | Private method, do not worry about it. Clears all cached observers from memory. |
Let's see how to use this object to add an event handler to the load event of the window object.
<script> Event.observe(window, 'load', page_loaded, false); function page_loaded(evt) { Event.observe('parent_node', 'click', item_clicked, false); } function item_clicked(evt){ var child = Event.element(evt); alert('The child node with id=' + child.id + ' was clicked'); Event.stop(evt); //avoid another call related to 'parent_node' itself } </script> ... <div id="parent_node"> <div id="child1">First</div> <div id="child2">Second</div> <div id="child3">Third</div> </div>
New objects and classes defined by prototype.js
Another way the library helps you is by providing many objects that implement both support for object oriented designs and common functionality in general.
<!-- *********************************************************************************** -->
The PeriodicalExecuter object
This object provides the logic for calling a given function repeatedly, at a given interval, using a timer.
[ctor](callback, interval) | constructor | callback: a function that will be passed the PeriodcalExecuter object itself as the only argument, interval: number of seconds | Creates one instance of this object that will call the function repeatedly. |
- prototype-1.5.1.2.rar (20.8 KB)
- 下载次数: 1
- prototype-1.6.0.3.rar (28 KB)
- 下载次数: 0
发表评论
-
一个使用方便的用于跳转后保持滚动条位置的JS
2011-11-29 14:49 868function ScrollHolder() { // ... -
JS 打印方法小结
2011-08-15 14:27 1234JS 实现打印网页中的部分内容: <script la ... -
星级点评效果
2011-08-12 12:21 685var sArray = new Object; s ... -
IE与Firefox在JavaScript上的7个不同句法
2010-05-21 10:57 639尽管那需要用长串的、沉闷的不同分支代码来应付不同浏览器的日子已 ... -
JS动态创建表格
2010-05-19 19:54 1514目标:生成一个2000*5的表格,每个单元格的内容是行号+逗号 ... -
省市三级联动
2010-04-16 10:36 1968//省市三级菜单联动function Dsy() ... -
Js事件大全
2010-04-15 10:18 711一般事件 事件 浏览器支持 描述 onClick IE3|N2 ... -
让FF和IE离得更近
2010-02-06 11:04 642给FF添加了IE专有的属性和方法: ... -
event对象 参考手册
2010-02-06 10:55 659http://www.w3school.com.cn/html ... -
relatedTarget 事件属性
2010-02-06 10:54 1126定义和用法 relatedTarget 事件属性返回与事件的 ... -
__defineGetter__和__defineSetter__
2010-02-06 10:21 1479Getter是一种获取一个属性的值的方法,Setter是一种设 ... -
JavaScript prototype 属性
2010-02-06 10:11 624Definition and Usage定义与用法 The ... -
attachEvent与addEventListener区别
2010-02-06 09:52 1247element.addEventListener(type, ... -
js教程--从入门到精通
2010-01-28 09:39 759JavaScript是基于对象(object-based)的语 ...
相关推荐
### Prototype 1.3 源码解读 #### 前言 Prototype 是一个轻量级的 JavaScript 库,它简化了 DOM 操作,并提供了一系列便捷的方法来处理对象、数组等基本类型。版本 1.3 相对于之前的 1.2 版本有了不少改进与增强,...
【Prototype 源码解读】 Prototype 是一个 JavaScript 框架,主要目的是简化动态 Web 开发,通过面向对象的方式增强 JavaScript 的设计能力。这个框架由 Sam Stephenson 创建,并且遵循 MIT 许可协议,允许自由分发...
7. 其他实用工具:Prototype还包含了一些实用工具函数,如`Array.from()`, `String.camelize()`, `Number.toColorPart()`等,这些函数极大地提高了代码的可读性和效率。 在学习Prototype 1.4源码时,建议结合实际...
压缩包内包含的文件如下: 1.手册与教程: ...CSS 2.0样式表中文手册(推荐);...Prototype 1.4.0源码解读.txt; 4.prototype源码: prototype-1.5.1.2源码.js; prototype-1.6.0.2源码.js; Prototype 1.4.0源码.js.
代码如下:Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and ...
总的来说,Prototype 1.4.0通过提供一套丰富的API和面向对象的结构,极大地提升了JavaScript的开发效率和代码质量。它为开发者带来了更强大的工具,使得JavaScript可以更好地应对复杂的Web应用需求。尽管目前版本...
prototype.js不仅是一个有很大实用价值的js库,而且有很高的学习价值,所以我强烈建议B/S开发人员和对JS开发感兴趣的朋友去浏览一些它的源代码,其中有很多的珠玑,你绝对会觉得读它的源代码是一种享受,当然要读得...
以下是对Prototype 1.4的详细解读。 1. **对象原型和继承** - 在JavaScript中,对象的原型是一种机制,允许对象之间共享属性和方法。Prototype 1.4通过增强这种机制,提供了一种简洁的方式来实现类和继承。 - `...
"prototype.js 1.4.0 开发笔记中文版"很可能提供了针对该版本的详细解读和开发实践,对于学习和理解Prototype API 的具体用法和最佳实践非常有帮助。 综上所述,Prototype API 和 Scriptaculous 提供了丰富的...
Prototype.js的优雅设计使得其源代码读起来如同享受,即使对于初学者,也有很大的启发性。 在Prototype.js中,`$()`函数是一个核心的实用工具,它是`document.getElementById()`的简洁替代,可以快速获取页面上指定...
这使得开发者能够构建复杂的对象模型和模块化的代码结构。 六、API文档解读 在压缩包中的"Prototype-v1.6.0.chm"文件是Prototype 1.6.0的官方API文档,包含了详细的类、方法和函数介绍,是学习和查找Prototype库...
9. **样例和最佳实践**:手册中会包含大量的示例代码和最佳实践,帮助开发者掌握如何在实际项目中有效地使用Prototype.js。 通过学习《prototype.js 1.4版开发者手册》,开发者可以掌握这些高级技巧,提高开发效率...
代码解读 原型接口(Prototype):定义了一个克隆方法 clone(),返回一个 unique_ptr<Prototype>,用于复制自身。 使用虚析构函数确保派生类能够正确释放资源。 具体原型(Book 和 Magazine): Book 类包含书名和...
prototype.js不仅是一个有很大实用价值的js库,而且有很高的学习价值,所以我强烈建议B/S开发人员和对JS开发感兴趣的朋友去浏览一些它的源代码,其中有很多的珠玑,你绝对会觉得读它的源代码是一种享受,当然要读得...
- **社区资源**: 社区中有许多关于 1.3 版本的解读资料,但由于 1.4 版本进行了较大的扩展,因此建议寻找针对 1.4 版本的源代码解读资料,以便更好地理解新的特性和改进。 #### 五、与其他技术的比较 - **Ruby ...
《最新Prototype手册》详细解读 Prototype.js 是一个广泛使用的JavaScript库,它为浏览器环境提供了许多实用的功能,大大简化了JavaScript的开发。这份“最新Prototype手册”深入探讨了这个库的核心特性,旨在帮助...
《prototype.js源码解读》 Prototype.js 是一个广泛使用的 JavaScript 库,它的设计目标是扩展JavaScript的基本功能,提供更丰富的面向对象编程体验。通过阅读和理解Prototype.js的源码,可以深入了解JavaScript...
虽然缺乏官方完整文档,但网络上有许多关于 Prototype 使用和源码解读的文章,可以帮助开发者克服这一挑战。 总的来说,Prototype 是一个强大的 JavaScript 库,通过提供丰富的工具和接口,极大地简化了 AJAX 应用...