<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    鷹翔宇空

    學習和生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
    原文引自:http://encytemedia.com/blog/articles/2005/12/07/prototype-meets-ruby-a-look-at-enumerable-array-and-hash

    Encytemedia

    A LOOK AT SOFTWARE DEVELOPMENT, DESIGN, AND OTHER RANDOM BITS.

    Working With Events In Prototype

    February 08, 2006

    Events drive interaction for almost everything and the web is no exception. In the style of my last article on Prototype, lets take a code-heavy look at how Prototype lets us work with events.

    NOTE: This article uses Prototype 1.5.0_pre0

    Basic event handling

    The syntax for working with events looks like the code below.

    Event.observe(element, name, observer, [useCapture]);

    Assuming for a moment that we want to observe when a link was clicked, we could do the following:

    // <a id="clicker" href="http://foo.com">Click me</a>
    Event.observe('clicker', 'click', function(event){ alert('clicked!');});

    If we wanted to get the element that fired the event, we'd do this:

    Event.observe('clicker', 'click', function(event){ alert(Event.element(event));});

    Observing keystrokes

    If we wanted to observe keystrokes for the entire document, we could do the following:

    Event.observe(document, 'keypress', function(event){ if(event.keyCode == Event.KEY_TAB) alert('Tab Pressed');});

    And lets say we wanted to keep track of what has been typed into your snazzy live-search box:

    Event.observe('search', 'keypress', function(event) { Element.update('search-results', $F(Event.element(event)));});

    Prototype defines properties inside the event object for some of the more common keys, so feel free to dig around in Prototype to see which ones those are.

    A final note on keypress events; If you'd like to detect a left click you can use Event.isLeftClick(event).

    Getting the coordinates of the mouse pointer

    Drag and drop, dynamic element resizing, games, and much more all require the ability to track the X and Y location of the mouse. Prototype makes this fairly simple. The code below tracks the X and Y position of the mouse and spits out those values into an input box named mouse.

       Event.observe(document, 'mousemove', function(event){$('mouse').value = "X: " + Event.pointerX(event) + "px Y: " + Event.pointerY(event) + "px";});

    If we wanted to observe the mouse location when it was hovering over a certain element, we'd just change the document argument to the id or element that was relevant.

    Stopping Propagation

    Event.stop(event) will stop the propagation of an event but there is a bug in Safari 2.0.3 that causes this to behave unexpectedly. Ryan from Particletree has posted an in-depth article on Event.stop with a workaround for Safari.

    The good news is that this bug is fixed in the Webkit version of Safari. You can check out this test in Safari 2.0.3 and Webkit to see the results of both.

    Events, Binding, and Objects

    Everything has been fairly straight forward so far, but things start getting a little tricker when you need to work with events in and object-oriented environment. You have to deal with binding and funky looking syntax that might take a moment to get your head around.

    Lets look at some code so you can get a better understanding of what I'm talking about.

    EventDispenser = Class.create();
    EventDispenser.prototype = {
      initialize: function(list) {
        this.list = list;
    
        // Observe clicks on our list items     
        $$(this.list + " li").each(function(item) {
          Event.observe(item, 'click', this.showTagName.bindAsEventListener(this));
        }.bind(this));
    
        // Observe when a key on the keyboard is pressed. In the observer, we check for 
        // the tab key and alert a message if it is pressed.
        Event.observe(document, 'keypress', this.onKeyPress.bindAsEventListener(this));
    
        // Observe our fake live search box.  When a user types something into the box, 
        // the observer will take that value(-1) and update our search-results div with it.
        Event.observe('search', 'keypress', this.onSearch.bindAsEventListener(this));
    
        Event.observe(document, 'mousemove', this.onMouseMove.bindAsEventListener(this));
      },
    
    
      // Arbitrary functions to respond to events
      showTagName: function(event) {
        alert(Event.element(event).tagName);
      },
    
    
      onKeyPress: function(event) {
        var code = event.keyCode;
        if(code == Event.KEY_TAB) alert('Tab key was pressed');
      },
    
      onSearch: function(event) {
        Element.update('search-results', $F(Event.element(event)));
      },
    
      onMouseMove: function(event) {
        $('mouse').value = "X: " + Event.pointerX(event) + "px Y: " + Event.pointerY(event) + "px";
      }
    
    }

    Whoa! What's going on here? Well, we've defined our a custom class EventDispenser. We're going to be using this class to setup events for our document. Most of this code is a rewrite of the code we looked at earlier except this time, we are working from inside an object.

    View a live example of our document ?

    Looking at the initialize method, we can really see how things are different now. Take a look at the code below:

        // Observe clicks on our list items     
        $$(this.list + " li").each(function(item) {
          Event.observe(item, 'click', this.showTagName.bindAsEventListener(this));
        }.bind(this));

    We've got iterators, binding and all sorts of stuff going on. Lets break down what this chunk of code is doing.

    First we are hunting for a collection of elements based on it's css selector. This uses the new Prototype selector function $$. After we've found the list items we are dealing with we send those into an each iteration where we will add our observers.

    Event.observe(item, 'click', this.showTagName.bindAsEventListener(this));

    Now looking at the code above, you'll notice the bindAsEventListener function. This takes the method before it showTagName and treats it as the method that will be triggered when, in this case, someone clicks one of our list items.

    You'll also notice we pass this as an argument to the bindAsEventListener function. This simply allows us to reference the object in context EventDispenser inside our function showTagName.

    NOTE: If you prefer the jargon packed explanation of bindAsEventListener, see the Script.aculo.us wiki.

    Moving on, you'll see bind(this) attached to our iterator function. This really has nothing to do with events, it is only here to allow me to use this inside the iterator. If we didn't use bind(this), I couldn't reference the method showTagName inside the iterator.

    Ok, so we'll move on to looking at our methods that actually get called when an event occurs. Since we've been dealing with showTagName, lets look at it.

      showTagName: function(event) {
        alert(Event.element(event).tagName);
      }

    As you can see, this function accepts one argument--the event. In order for us to get the element which fired the event we need to pass that argument to Event.element. Now we can manipulate it at will.

    This covers the most confusing parts of our code. The text above is also relevant to the remaining parts of our code. If there is anything about this you don't understand, feel free to say so.

    Removing Event Listeners

    This one threw me for a loop the first time I tried to use it. I tried something similar to what I did in the Event.observe call with the exception of using stopObserving, but nothing seemed to change. In other words, the code below does NOT work.

    $$(this.list + " li").each(function(item) {
      Event.stopObserving(item, 'click', this.showTagName);
    }.bind(this));

    What's the deal here? The reason this doesn't work is because there is no pointer to the observer. This means that when we passed this.showTagName in the Event.observe method before hand, we passed it as an anonymous function. We can't reference an anonymous function because it simply doesn't have a pointer.

    So how do we get the job done? All we need to do is give the observing function a pointer, or the jargon free version: Set a variable that points to this.showTagName. Ok, lets change our code a bit.

    this.showTagObserver = this.showTagName.bindAsEventListener(this);
    
    // Observe clicks on our list items     
    $$(this.list + " li").each(function(item) {
      Event.observe(item, 'click', this.showTagObserver);
    }.bind(this));

    Now we can remove the event listeners from our list like this:

    $$(this.list + " li").each(function(item) {
      Event.stopObserving(item, 'click', this.showTagObserver);
    }.bind(this));

    One final note on removing event listeners. If you have an instance where you want to simply remove all observes in one big swoop, you can use unloadCache.

    Event.unloadCache();

    Summing Up

    That pretty much sums up events in Prototype. If you find any errors, please let me know. The great thing about writing articles such as this is that I also learn so much in the process and develop a deeper understanding of what I'm writing about. For instance, I found out the removing event listeners bit while I was writing this article. If you've got anything you'd like to contribute, feel free to chime in. Until next time, Happy Prototyping!

    Related Reading

    posted on 2006-02-11 14:04 TrampEagle 閱讀(470) 評論(0)  編輯  收藏 所屬分類: opensource
    主站蜘蛛池模板: 无码国产精品一区二区免费式影视 | 夜夜嘿视频免费看| 亚洲视频在线观看不卡| 久久久久久免费一区二区三区 | 伊人久久大香线蕉亚洲五月天 | 一级毛片全部免费播放| 婷婷久久久亚洲欧洲日产国码AV| CAOPORN国产精品免费视频| av在线亚洲欧洲日产一区二区| 免费大片av手机看片高清| 亚洲精品国产电影| 两性色午夜视频免费网| 自拍偷自拍亚洲精品被多人伦好爽| xxxx日本在线播放免费不卡| 337p日本欧洲亚洲大胆裸体艺术| 十八禁视频在线观看免费无码无遮挡骂过| 中文字幕一精品亚洲无线一区| 免费av一区二区三区| 亚洲视频一区二区在线观看| 69成人免费视频| 国产亚洲精品AAAA片APP| 亚洲国产一区明星换脸| 成av免费大片黄在线观看| 亚洲AV无码一区东京热久久| 亚洲综合免费视频| 亚洲精品天堂成人片AV在线播放 | 亚洲中文字幕久久精品无码APP | 一级特级aaaa毛片免费观看| 久久被窝电影亚洲爽爽爽| 1000部拍拍拍18勿入免费视频软件| 中文文字幕文字幕亚洲色| 亚洲精品无码久久毛片| 午夜老司机永久免费看片| 亚洲中文字幕无码久久| 国产成人精品亚洲精品| 国产精品久久免费| 黄页免费视频播放在线播放| 精品国产综合成人亚洲区| 成人免费午夜无码视频| 特级做a爰片毛片免费看| 亚洲欧洲免费视频|