In: |
EventTarget.rb
|
Including this module gives your class instances the ability to dynamically register an arbitrary number of callback methods to be invoked when certain types of events are fired.
This module mimics the behavior of the W3C DOM2Events specification. (Notably different is the lack of event bubbling/capturing, and pre-specified subclasses of Event like "MutationEvent" or "MouseEvent".)
Events are specified by the type property of the EventTarget::Event class, and may be any symbol.
require 'EventTarget' class HTMLInput include EventTarget attr_reader :value, :name def value=( v ) @value = v evt = Event.new( :change, v ) dispatch_event( evt ) end def initialize( name ) @name = name end def to_s; %|<HTMLInput "#{@name}">|; end end class Calculator def initialize( name, formula ) @name = name @formula = formula end def update_result( ) @result = eval( @formula ) puts "#{@name} is now #{@result}" if $DEBUG end end total = Calculator.new( 'Total Price', '$price.value * $quantity.value' ) $price = HTMLInput.new( 'price' ) $price.value = 12.49 $price.add_event_listener( :change, &total.method( :update_result ) ) $quantity = HTMLInput.new( 'quantity' ) $quantity.value = 0 $quantity.add_event_listener( :change, &total.method( :update_result ) ) if $DEBUG yell_about_change = Proc.new{ |evt| puts "#{evt.target} changed @ #{evt.timestamp}; the new value is '#{evt.change}'.\n" } $price.add_event_listener( :change, &yell_about_change ) $quantity.add_event_listener( :change, &yell_about_change ) end $quantity.value = 3 #=> Total Price is now 37.47 #=> <HTMLInput "quantity"> changed @ Tue Sep 28 07:32:18 MDT 2004; the new value is '3'. $price.value = 9.99 #=> Total Price is now 29.97 #=> <HTMLInput "price"> changed @ Tue Sep 28 07:32:18 MDT 2004; the new value is '9.99'.
type: | A symbol specifying the Event type to watch for. |
callback: | The block to call when the specified event fires. |
This method registers a callback method to invoke whenever the receiving instance fires an event with the same type as the first parameter.
Callbacks are guaranteed to execute in the order they are registered on the instance.
If add_event_listener is called more than once with the same value for callback, the callback will only be invoked once whenever the event occurs; remove_event_listener is called first to remove existing registrations, and then the callback is added at the end of the invocation list.
If the callback block expects any arguments to be passed, the event object will be passed as the first (and only) argument.
foo.add_event_listener :change, { |evt| p evt.type } foo.add_event_listener :change, &bar.method( :hear_change )
evt: | The Event instance to fire. |
Fires off the supplied event for the instance, automatically invoking any callback methods which have been registered for the type set in the Event instance. If the callback method expects any arguments to be passed, evt will be passed as the first (and only) argument.
Note: This method automatically sets (overrides) the target and timestamp properties of the supplied event.
def check_for_messages @unread_messages.each{ |message| dispatch_event Event.new( :message_received, message ) } end
type: | A symbol specifying the Event type to watch for. |
callback: | The Proc or Method to call when the specified event fires. |
The opposite of add_event_listener, this removes the specified callback from the invocation list. Because a callback can only be registered once for a specific event type, calling this method once ensures that the callback will not be invoked for the event type, no matter how many times it may have been registered.