Giter Club home page Giter Club logo

bean's Introduction

Bean

Bean is a small, fast, cross-platform, framework-agnostic event manager designed for desktop, mobile, and touch-based browsers. In its simplest form - it works like this:

bean.on(element, 'click', function (e) {
  console.log('hello');
});

Bean is included in Ender's starter pack, "The Jeesh". More details on the Ender interface below.

API

Bean has five main methods, each packing quite a punch.


on(element, eventType[, selector], handler[, args ])

bean.on() lets you attach event listeners to both elements and objects.

Arguments

  • element / object (DOM Element or Object) - an HTML DOM element or any JavaScript Object
  • event type(s) (String) - an event (or multiple events, space separated) to listen to
  • selector (optional String) - a CSS DOM Element selector string to bind the listener to child elements matching the selector
  • handler (Function) - the callback function
  • args (optional) - additional arguments to pas to the callback function when triggered

Optionally, event types and handlers can be passed in an object of the form { 'eventType': handler } as the second argument.

Examples

// simple
bean.on(element, 'click', handler);

// optional arguments passed to handler
bean.on(element, 'click', function(e, o1, o2) {
  console.log(o1, o2);
}, 'fat', 'ded');

// multiple events
bean.on(element, 'keydown keyup', handler);

// multiple handlers
bean.on(element, {
  click: function (e) {},
  mouseover: function (e) {},
  'focus blur': function (e) {}
});

Delegation

A String as the 3rd argument to on() will be interpreted as a selector for event delegation. Events for child elements will cause the element to be checked against the selector and the event to be fired if a match is found. The event behaves the same way as if you listened directly to the element it was fired on.

// event delegated events
bean.on(element, 'click', '.content p', handler);

// Alternatively, you can pass an array of elements.
// This cuts down on selector engine work, and is a more performant means of
// delegation if you know your DOM won't be changing:
bean.on(element, 'click', [el, el2, el3], handler);
bean.on(element, 'click', $('.myClass'), handler);

Notes

  • Prior to v1, Bean used add() as its primary handler-adding interface, it still exists but uses the original argument order for delegated events: add(element[, selector], eventType, handler[, args ]). This may be removed in future versions of Bean.

  • The focus, blur, and submit events will not delegate due to vagaries of the DOM model. This may be addressed in a future version of Bean.

Namespacing

Bean supports namespacing your events. This makes it much easier to target the handlers later when using off() or fire(), both of these methods match namespaced handlers in the same way.

To namespace an event just add a dot followed by your unique name identifier:

bean.on(element, 'click.fat.foo', fn);  // 1
bean.on(element, 'click.ded', fn);      // 2
bean.on(element, 'click', fn);          // 3

// later:
bean.fire(element, 'click.ded');        // trigger 2
bean.fire(element, 'click.fat');        // trigger 1
bean.off(element, 'click');             // remove 1, 2 & 3

// fire() & off() match multiple namespaces with AND, not OR:
bean.fire(element, 'click.fat.foo');    // trigger 1
bean.off(element, 'click.fat.ded');     // remove nothing

Notes

  • Prior to v1, Bean matched multiple namespaces in fire() and remove() calls using OR rather than AND.

one(element, eventType[, selector], handler[, args ])

bean.one() is an alias for bean.on() except that the handler will only be executed once and then removed for the event type(s).

Notes

  • Prior to v1, one() used the same argument ordering as add() (see note above), it now uses the new on() ordering.

off(element[, eventType[, handler ]])

bean.off() is how you get rid of handlers once you no longer want them active. It's also a good idea to call off on elements before you remove them from your DOM; this gives Bean a chance to clean up some things and prevents memory leaks.

Arguments

  • element / object (DOM Element or Object) - an HTML DOM element or any JavaScript Object
  • event type(s) (optional String) - an event (or multiple events, space separated) to remove
  • handler (optional Function) - the specific callback function to remove

Optionally, event types and handlers can be passed in an object of the form { 'eventType': handler } as the second argument, just like on().

Examples

// remove a single event handlers
bean.off(element, 'click', handler);

// remove all click handlers
bean.off(element, 'click');

// remove handler for all events
bean.off(element, handler);

// remove multiple events
bean.off(element, 'mousedown mouseup');

// remove all events
bean.off(element);

// remove handlers for events using object literal
bean.off(element, { click: clickHandler, keyup: keyupHandler })

Notes

  • Prior to Bean v1, remove() was the primary removal interface. This is retained as an alias for backward compatibility but may eventually be removed.

clone(destElement, srcElement[, eventType ])

bean.clone() is a method for cloning events from one DOM element or object to another.

Examples

// clone all events at once by doing this:
bean.clone(toElement, fromElement);

// clone events of a specific type
bean.clone(toElement, fromElement, 'click');

fire(element, eventType[, args ])

bean.fire() gives you the ability to trigger events.

Examples

// fire a single event on an element
bean.fire(element, 'click');

// fire multiple types
bean.fire(element, 'mousedown mouseup');

Notes

  • An optional args array may be passed to fire() which will in turn be passed to the event handlers. Handlers will be triggered manually, outside of the DOM, even if you're trying to fire standard DOM events.

setSelectorEngine(selectorEngine)

bean.setSelectorEngine() allows you to set a default selector engine for all your delegation needs.

The selector engine simply needs to be a function that takes two arguments: a selector string and a root element, it should return an array of matched DOM elements. Qwery, Sel, Sizzle, NWMatcher and other selector engines should all be compatible with Bean.

Examples

bean.setSelectorEngine(qwery);

Notes

  • querySelectorAll() is used as the default selector engine, this is available on most modern platforms such as mobile WebKit. To support event delegation on older browsers you will need to install a selector engine.

The Event object

Bean implements a variant of the standard DOM Event object, supplied as the argument to your DOM event handler functions. Bean wraps and fixes the native Event object where required, providing a consistent interface across browsers.

// prevent default behavior and propagation (even works on old IE)
bean.on(el, 'click', function (event) {
  event.preventDefault();
  event.stopPropagation();
});

// a simple shortcut version of the above code
bean.on(el, 'click', function (event) {
  event.stop();
});

// prevent all subsequent handlers from being triggered for this particular event
bean.on(el, 'click', function (event) {
  event.stopImmediatePropagation();
});

Notes

  • Your mileage with the Event methods (preventDefault etc.) may vary with delegated events as the events are not intercepted at the element in question.

Custom events

Bean uses methods similar to Dean Edwards' event model to ensure custom events behave like real events, rather than just callbacks.

For all intents and purposes, you can just think of them as native DOM events, which will bubble up and behave you would expect.

Examples

bean.on(element, 'partytime', handler);
bean.fire(element, 'partytime');

mouseenter, mouseleave

Bean provides you with two custom DOM events, 'mouseenter' and 'mouseleave'. They are essentially just helpers for making your mouseover / mouseout lives a bit easier.

Examples

bean.on(element, 'mouseenter', enterHandler);
bean.on(element, 'mouseleave', leaveHandler);

Object support

Everything you can do in Bean with an element, you can also do with an object. This is particularly useful for working with classes or plugins.

var inst = new Klass();
bean.on(inst, 'complete', handler);

//later on...
bean.fire(inst, 'complete');

Ender Integration API

If you use Bean with Ender its API is greatly extended through its bridge file. This extension aims to give Bean the look and feel of jQuery.

Add events

  • on - $(element).on('click', fn);
  • addListener - $(element).addListener('click', fn);
  • bind - $(element).bind('click', fn);
  • listen - $(element).listen('click', fn);

Remove events

  • off - $(element).off('click');
  • unbind - $(element).unbind('click');
  • unlisten - $(element).unlisten('click');
  • removeListener - $(element).removeListener('click');

Delegate events

  • on - $(element).on('click', '.foo', fn);
  • delegate - $(element).delegate('.foo', 'click', fn);
  • undelegate - $(element).undelegate('.foo', 'click');

Clone events

  • cloneEvents - $(element).cloneEvents('.foo', fn);

Custom events

  • fire / emit / trigger - $(element).trigger('click')

Special events

  • hover - $(element).hover(enterfn, leavefn);
  • blur - $(element).blur(fn);
  • change - $(element).change(fn);
  • click - $(element).click(fn);
  • dblclick - $(element).dblclick(fn);
  • focusin - $(element).focusin(fn);
  • focusout - $(element).focusout(fn);
  • keydown - $(element).keydown(fn);
  • keypress - $(element).keypress(fn);
  • keyup - $(element).keyup(fn);
  • mousedown - $(element).mousedown(fn);
  • mouseenter - $(element).mouseenter(fn);
  • mouseleave - $(element).mouseleave(fn);
  • mouseout - $(element).mouseout(fn);
  • mouseover - $(element).mouseover(fn);
  • mouseup - $(element).mouseup(fn);
  • mousemove - $(element).mousemove(fn);
  • resize - $(element).resize(fn);
  • scroll - $(element).scroll(fn);
  • select - $(element).select(fn);
  • submit - $(element).submit(fn);
  • unload - $(element).unload(fn);

Browser support

Bean passes our tests in all the following browsers. If you've found bugs in these browsers or others please let us know by submitting an issue on GitHub!

  • IE6+
  • Chrome 1+
  • Safari 4+
  • Firefox 3.5+
  • Opera 10+

Contributing

Bean uses BusterJS for its unit tests. npm install will install Buster and other required development dependencies for you and then you can simply point your browser at bean/tests/tests.html.

A Buster configuration file also exists so you can use buster-server to run a capture server to attach multiple browsers to and then buster-test to run the tests (if you don't have Buster installed globally, you can find the executables in node_modules/.bin/).

We're more than happy to consider pull requests, however major features that have not been previously discussed may risk being rejected. Feel free to open an issue on GitHub for discussion or questions.

Contributions should stick with Bean's coding style: comma-first, semicolon-free and two-space indenting. Non-trivial contributions should come with unit tests also, feel free to ask questions if you have trouble.

Running make will assemble the bean.js file in the root of the repository. Please be aware that any contributions to bean should be in src/bean.js or they will be lost!

Contributors

Special thanks to:

Licence & copyright

Bean is copyright © 2011-2012 Jacob Thornton and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

bean's People

Contributors

acusti avatar amccollum avatar bartsidee avatar benvinegar avatar bermi avatar calvein avatar cesutherland avatar ded avatar djanowski avatar fabiosantoscode avatar fat avatar jdalton avatar jfromaniello avatar joefiorini avatar mistersourcerer avatar njj avatar pdeszynski avatar robertberry-zz avatar rvagg avatar sean-lynch avatar syranez avatar valueof avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bean's Issues

enderjs wrong bean version?

current version of bean in the package.json is 0.4.1

but when I do "ender refresh"
it is still version 0.3.0

even when I do "ender remove bean" then "ender add bean"
I still get version 0.3.0
Is this normal?

my current ender-js version is 0.3.6

Doesn't clone delegated events

Whenever you clone a delegated event, it becomes a regular event on the delegated element.

This test demonstrates the behaviour:

https://github.com/benvinegar/bean/commit/cd545996d53cbc5bcf3f745f46c6af72203e5166

The offending line is here: https://github.com/fat/bean/blob/master/src/bean.js#L493. You can see that when events are copied, the delegation properties are lost.

I spent about an hour trying to come up with a patch for this, but it's kind of nasty. Would appreciate some advice/help.

Missing Support for DOM Level 2: handleEvent (Interface EventListener)

bean does not handle a neat pattern from the DOM Level 2 Events: Interface EventListener

It doesn't support handleEvent. I could just give a class instance to the event handler, I don't need to handle the scope.

Example:

class App
  constructor: ->  
    @element = $ '#app'
    @element.bind 'dblclick', this

  handleEvent: (event) ->
    switch event.type
      when 'dblclick' then @addEmptyChild event.pageX, event.pageY`

Custom event jQuery compatibility

Hello,

This is more a question than a real issue!

When trying to make a library I am working on compatible with both Jeesh and jQuery, I have run into a small quirk where custom events fire a callback with different arguments.

i.e. jQuery provides an event object as the first argument to the cb whereas bean strips it out (cf. CustomHandler slice call).

So my question is: what should I do in order to have full compatibility between jQuery and bean (is that even one of bean's goal?)?

Thanks!

Pierre

bind, unbind, bind (not binding)

I don't know what prompted me to do this. but this appeared to not work in Chrome (i didn't check any other browsers)

$('p').bind('click', function () {
  $(this).css('color', 'red');
});

// go click the p tag - it turns red

$('p').unbind('click');

// create a new listener
$('p').bind('click', function () {
  $(this).css('color', 'green');
});

// go click the p tag - it never turns green

"live"

Hi!

Do you plan to add (event bubbling?) functionality similar to jquery-live? So that one can assign event handlers to elements that don't yet exist.

TIA,
--Vladimir

Ability to add additional custom events

Can I access the customEvents object while using bean with ender? Goal is to provide something like mootools where you can add your own custom events with certain conditions. I would like to add my own event for enterkey pressed.

From MooTools Docs:

Element.Events.shiftclick = {
    base: 'click', // the base event type
    condition: function(event){ //a function to perform additional checks
        return (event.shift == true); // this means the event is free to fire
    }
};

General usage question

I've recently found Ender JS and decided to give it a try. I like the idea but the documentation leave a lot to be desired as with this, and other modules. In the ReadMe for bean there are references to "bean.add" , "bean.remove", ".fire" and so on. But in other tickets in this repo and at ender-js forum there are conflicting references, some to .emit or even to the native method, bind. So what is the proper use of this "Module" in and out of the ender context. I mean you have to assume that when you're pushing a package deal like ender, users will expect the parts to work together. For instance when using say bean.add(element, 'click') 'element' can not be qwery('some-hml-element collection') or a collection from jQuery. But something like qwery('some-hml-element')[0] will work. This should be documented as basic usage. Why not provide a simple, working, implementation like we find for jQuery, dojo, YUI, etc.

Im not trying to bust balls. Just provide my 2 cents as a user.

B | E

Proposal: adopt the `on()` standard

This is a request for comments on a bit of API breakage, I'd love to get feedback from Bean users on this, particularly if you use on().

on(), as it currently exists in the Ender bridge, is incompatible with the standard set by Prototype and adopted by jQuery.

I think the emerging on() standard is a good one and we should change Bean to conform to it. At least in the Ender bridge and perhaps in Bean proper. I suspect that since most jQuery users who are using Ender are probably using bind() or the other traditional jQuery style methods and since Bean's on() is not directly compatible with jQuery's it may not be getting much use.

Prototype's on() signature is: .on(element, eventName[, selector], handlerFn)

jQuery's on() signature is: .on(events [, selector] [, data], handlerFn)

Unfortunately, ours is (in Ender form): .on([selector ,] events, handlerFn) (note the order of selector and events)

I propose that we change Bean to this signature: .on(events [, selector], handlerFn) with the possibility of adding the jQuery data parameter in the future (I imagine it would be quite helpful, but perhaps you should just curry your handler).

This is a modified integrate() in the bridge that makes the change there:

    , integrate = function (method, type) {
        var _args = type ? [type] : []
        return function () {
          for (var args, i = 0, l = this.length; i < l; i++) {
            args = [this[i]].concat(_args, Array.prototype.slice.call(arguments, 0))
            if (args.length == 4) {
              args.push($)
              if (method == 'on') { // 'on' puts event type first, selector second
                var s = args[1]
                args[1] = args[2]
                args[2] = s
              }
            }
            b[!arguments.length && method == 'add' && type ?
              'fire' : method == 'on' ?
                'add' : method
            ].apply(this, args)
          }
          return this
        }
      }

// on: integrate('on')

It's a bit long and I think I'd rather see on() added to Bean proper, perhaps even encouraged as the primary interface for adding. The signature there would look something like: .on(element, events [,selector], handlerFn [, selectorEngine]).

I'm not sure where this leaves .off() though, it's a funny API although it's consistent with having an .on() I guess and we already have it in the bridge. Prototype doesn't bother with on(), you still use .stopObserving().

Incidentally, Prototype returns a special handler object that has start() and stop() methods that you can use to turn on and off the listener, so you don't really need an off().

Pass event object as first argument when listening to objects?

Hi

First of all, great work on Bean! I find myself using it all the time.

I am writing a bridge so I can switch between using the jQuery events API and Bean.
Everything goes fine except for events fired on objects. There is a difference in arguments passed to the callback function in jQuery and Bean and I am not sure which one has it right:

Setup:

var dummy = {};

Bean:

bean.add(dummy, 'message', function(message) {

    console.log(message); // (string) hello
});

bean.fire(dummy, 'message', ['hello']);

jQuery:

jQuery(dummy).on('message', function(message) {

    console.log(message); // (object) event
});

jQuery(dummy).trigger('message', ['hello']);

Custom events on window.document don't work in IE <= 8

Custom events set on window.document that are working in Safari/Chrome/Firefox and IE9 aren't working in IE7/8. There's obvious workarounds, but seems like you should be able to fire events on the document for app wide pub/sub patterns?

delegated custom events don't work

Compare

bean.add(document.getElementById('tests'), '.pass', 'click', function(e) { console.log('delegate click', e) }, qwery)

to

bean.add(document.getElementById('tests'), '.pass', 'mouseenter', function(e) { console.log('delegate mouseenter', e) }, qwery)

minor fix needed in README

in the section "object support" you have

var inst = new Klass(); 
bean.add(klass, 'complete', handler);

shouldn't that be adding the event to object "inst", not "klass"

bean.add(inst, 'complete', handler);

(or make the instance of Klass "klass" and not "inst")

commonjs integration with jeesh modules

at the moment ender takes care of attaching the methods so that the bean API can be used on the result of a bonzo call. Is it possible to export the function that does the attachment as well, so that people not using ender could attach bean to $ in a similar manner?

At the moment the following arbiter works fine with a commonjs bundler;

var domready = require('domready')
  , bean     = require('bean')
  , bonzo    = require('bonzo')
  , reqwest  = require('reqwest')
  , qwery    = require('qwery')

var $ = function (selector) {
  return bonzo(qwery(selector));
};
bonzo.setQueryEngine(qwery);

$.ready = domready;
$.ajax = reqwest;

// bean harder to attach

module.exports = $;

Unable to pass event object when firing a native key(up|down) event

Basically I'm trying to do this:

$("input").fire("keydown", {
  type: "keydown",
  keyCode: 191
});

If I read the code correctly it should fix the half-baked event I pass in as a second argument and then go through all the listeners and call the handler with the fixed event.

In practice fire() prepends the boolean false (line 517) to the arguments which then gets passed to the nativeHandler's handler (line 334) but the handler expects the argument "event" as the first argument, which now is always false and thus always fixes the wrong event object.

When I change the nativeHandler's handler to

handler = function (f, event)

then things work with no apparent side-effects.

What's the reason the false prepended?

Adding events to $(window) doesn't work

This might actually be a Bonzo thing, or just an Ender integration thing in general, but I found that if you add an event to $(window), say:

$(window).bind({
  blur: function() {
    ...
  }
})

then the event never gets fired. However, changing that to $([window]) works:

$([window]).bind({
  blur: function() {
    ...
  }
})

Idea: use replace() or similar to automatically preventDefault()

Many times you want to 'replace' the default handler. You do so by calling event.preventDefault(). This could be DRYed up a bit by something like replace(), which automatically prevents the default handler. One big advantage would be that if the given handler fails, the default handler is still prevented (so for instance if you have a bug in your code which triggers an exception, a link is not followed, a form is not submitted, etc.)

Something like:

replace: function(element, name, callback) {
  add(element, name, function(event) {
    try {
      callback.apply(this, arguments);
    }
    finally {
      event.preventDefault();
    }
  }
}

Thoughts?

Undelegate doesn't work as advertised

The API listed in the README is misleading. It says that I can do:

bean.undelegate(selector);

But calling this does absolutely nothing. On tracking it down, I found that delegate uses remove without any preprocessing. When I got to the remove function, it treated my selector as a an event. There was no logic differentiating a regular unbind (where the first element is an event name) and an undelegate.

indexOf

Hi!

Array.prototype.indexOf is absent in many elder JS engines, but is used heavily in bean's code to check, say, occurance in nativeEvents. Solution: (best) make underscore be the highest priority in jeesh and to reuse everywhere (bonzo also reinvents indexOf) already included _.indexOf; (good) make nativeEvents be a hash and avoid using indexOf at all to check for occurances.

I guess the rest of the code should also be made relaying on underscore, or an ES5 shim such as kriskowal/es5-shim.

TIA,
--Vladimir

Bean backbone context issue.

I am trying to get bean working with backbone I am having issues with context. Wondering if anyone knows whats going on.

in backbone its self see in the base view.

$(this.el).delegate(selector, eventName, this.handleEvent);

so I can utilize events object to create events in the extended view:
events: {
"click #leftArrow": "handleEvent",
"click #rightArrowDrag": "handleEvent"

    },

normally to get around the context issue I can do something like this.

var self = this;
$(this.el).bind("click", function(e){
self.handleEvent(e);
});

But since the event is being bound in the base view thats extended it will not inherit context I can fire the handler on the backbone view but I can call a instance of a method in the object other than the handler. If anyone knows how to get around this it would help me out a ton I waisted a ton of time on this issue today.

thanks :)

In IE8 passing custom arguments results in handler never being called

Consider the following code:

var obj = {};
bean.add(obj, 'myEvent', function (ev) {
  console.log('myEvent has been triggered');
});

bean.fire(obj, 'myEvent', [ { customKey: 'customValue' } ]);

The handler will never be called in IE8 because customHandler—when run in a non-W3C complaint environment—expects either event object with propertyName or nothing at all. I wanted to patch it myself but I don't really understand the event && event.propertyName == '_on' + type || !event part in the customHandler function.

Could you explain why do you care about event objects with that specific property or nothing at all? Can the !event part be changed to true?

add more browser events

was going to use some of these recently... but they didn't quite fully work. they fired my callback (as expected), but I didn't get back the proper event objects.

  • window.onpopstate
  • document.ononline
  • document.onoffline

Object support and custom events

Hi, we are looking at using bean to help normalize event management in our PhotoSwipe project - https://github.com/codecomputerlove/PhotoSwipe.

Unfortunately I'm having some issues I was wondering if you could help me out with?

  • When I fire an event for a object rather than a DOM element, the first argument in the callback function is not an event object. Is this by design?
  • I want to fire off events and pass values to associated handlers. Looking at the code it looks like the "fire" method accepts custom arguments that are relayed to any handler function. I've tried this and it seems that only the first argument array value is being passed.

Any help with these would be great or if I'm doing something bonkers then let me know :D

I've included some example code below:

var Foo = klass({

    foo: 0,

    initialize: function() {
        this.foo = 1;
    },

    getFoo: function () {
        return this.foo;
    },

    setFoo: function (x) {
        this.foo = x;
        return this.getFoo();
    }

});

var obj = new Foo();

bean.add(obj, 'doSomething', function(arg1, arg2){
    console.log(arguments);
    // For some reason we are missing an event argument
    // and arg2 has not been set.
});

bean.fire(obj, 'doSomething', ['val1', 'val2']);

triggering click on file input (Firefox)

I know pretty much all browsers have prevented setting the value of an HTML file input from JS, and I'd always assumed that they wouldn't let you trigger a click event on one (to open the native file picker), but while working on a global uploader for our app I discovered that, at least with jQuery, you can force the click and open the file picker as long as file input is not set to display:none—apparently it's OK if it's absolutely positioned out of the field of view.

Here's a jQuery version, where the file picker dialog can be triggered in current Chrome/Firefox/IE9: http://jsfiddle.net/DSARd/182/

Here's a bean (via jeesh) version, where it works in Chrome & IE9 but not Firefox:
http://jsfiddle.net/NkycS/2/

I'm about to look closely at the differences between how jQuery & Bean trigger events, but thought I'd log this as an issue just in case bean devs know offhand exactly why this is and can pull me out of the rabbit hole before I get lost down there.

(I am aware of the common alternate approach to custom file inputs, where you position a file input with its opacity set to 0 directly over some other element, but in my specific use case, triggering the click would be preferable for a couple reasons.)

Integration with Ender diminishes usefulness

I tried, maybe I failed and missed the obvious solution to this problem.

When building in Ender, an instance of bean is no longer accessible to use with the object support mentioned in the README. I use that pattern to quickly add events to my simple classes.

Therefor I use bonzo and bean as separat components … which is also not nice, since its hard to easily connect bonzo and bean without ender (like a simple bonzo.aug(bean)?).

delegate in Ender integration API doesn't work

$(element).delegate('.foo', fn);

According to the documentation the .add function expects a selector engine to be used for event delegation, but no selector engine is passed in the Ender integration API.

Event propagation doesn't stop

Event.stop() doesn't work, if handler was delegated, not added directly to element.

var handler = function(e){
   e.stop();
}

// event bubbling will be stopped:
bean.add(el, 'click', handler);
// event bubbling will NOT be stopped here:
bean.add(el, '.someclass sometag', 'click', handler);

I'm using bean without ender.js
e.stopPropagation() and e.preventDefault() don't work as well.

Bug?: namespaced listeners triggered by root space firing?

With code like this:

bean.add element, 'click.fat', fn
bean.add element, 'click.ded', fn
bean.add element, 'click', fn

//later...
bean.fire element, 'click.ded'

Should bean.fire element, 'click' invoke the listener bean.add element, 'click.fat'. If so what is the advantage of name-spacing? If not, then there is a bug because this is the behaviour I get.

Add a function who checks if an event is binded

Hey, first of all nice job !

I would like to know if it was possible to add a function wich would be called "has" and would check if a elem has a event. Something like :

bean.on(elem, "click", function () {});
console.log(bean.has(elem, "click")); // true
bean.off(elem, "click");
console.log(bean.has(elem, "click")); // false

If you want to do this, just add line > 540 :

, has = function (element, event) {
    return registry.has(element, event);
}

and line 716 :

        , has               : has    

Note that it would be great if that function has could return true to something like that :

bean.on(elem, "click", function() {});
console.log(bean.has(elem)); // true
console.log(bean.has(elem, "c"); // false
console.log(bean.has(elem, "click"); // true

Thanks !

fixEvent throws exception when setting e.target under firefox

I'm adding event listener like this

link.click((e) -> alert('clicked')

Under firefox 3.6.16 fixEvent in bean throws exception after link is clicked:

setting a property that has only a getter
at 'e.target = target && target.nodeType == 3 ? target.parentNode : target;'
in fixEvent method

But under chrome event function works as expected.

Normalize handler signature

To improve jQuery-compatibility and general consistency in the arguments passed to event handlers via different methods, I think that bean.fire() and .trigger() need modification. Consider:

(function ($) {
    var $html = $('html');

    function handler ()  {
        console.log(arguments);
    }

    $html.on('click', handler); // `handler` receives (eventData) when <html> is clicked
    $html.trigger('click');     // `handler` receives (eventData)

    // When triggered with extra params, bean omits the eventData, meaning
    // the line below sends just ('extra-0', 'extra-1') to `handler`.
    // In jQuery the line below sends (eventData, 'extra-0', 'extra-1')
    $html.trigger('click', ['extra-0', 'extra-1']);

}(ender)); // 2012-11-27 ender build jeesh

The arguments passed to handlers should be as normalized as possible between native / custom / triggers etc. The arguments[0] slot should be reserved for an eventData object. In situations without applicable eventData, it could be passed as null or (better) a simple object like:

{
    isBean: true, 
    isTrigger: true // jQuery includes this on triggers
}

cloned events fire in scope of original elements

ran into this today...

// create a regular event
bean.add(el1, 'click', function () {
  console.log(this)
})

// clone to el2, from el1
bean.clone(el2, el1)

// click on el2 and 'this' is el1
// :(

Memory Leak - removed elements

bean keeps a private reference to DOM elements in the collected variable, which is cleared on page unload. This reference is kept even after all listeners have been removed from the element.

mousewheel event is not handled correctly in webkit

I upgraded bean's version from 0.3.0 to 0.4.4 and noticed that my Scrollbar component doesn't work anymore.
as far as I can see event object passed to event handler contains neither correct value of delta property nor wheelDelta.

I tried to add event listener using native API and it worked fine.

Looks like bean's bug.

using within ender.js

Hi!

Wonder how do I add/fire events to a JS object (not DOM) when bean is the part ender.js?

TIA,
--Vladimir

counterpart to jQuery.live method?

I am using bean along with some other modules as a jQuery replacement, and I found myself missing the jQuery.live() method. Is there a counterpart in bean? If so, I could not find it in the docs. If not, how difficult would it be to add?

Change context with a function or with a variable

Hey; still another thing that would be great : make the dev able to change the context with a function or with a variable, exemple :

bean.on(elem, "click", function () {
    hey(this); // this => $(elem)
}, function () { // this => elem
    return $(this);
});

Another exemple :

bean.on(elem, "click", function () {
    hey(this); // variable name
}, variablename);

You can do this by adding a parameter, a property in RegEntry, and you add something like:

if (Object.prototype.toString.call(this.context) === "[object Function]") {
    this.context = this.context.call(this.elem);
}
// fire, cross-browserify function
callback.apply(this.context, additionalsArgs);

Thank you !

published to jamjs

Hi, I just published this package to jamjs. If you want to own the package in the jamjs registry, just let me know

thanks

Bug?: Multiple custom events

We have a function that binds to multiple custom events, like so:

bean.add(element, 'player.onEnded.videoPlayer player.onStop.videoPlayer', handler);

But it turns out when we try to fire the event, it will only fire the function on the last event name. So with the above example:

# this is working fine
bean.fire(element, 'player.onStop');

# this is not working!
bean.fire(element, 'player.onEnded');

I did a quick test with the code and events are properly added, types is actually an arry with the two events:

L482 bean.js

for (i = types.length; i--;) addListener(element, types[i], fn, originalFn, args)

but it just will only fire the function on the last set event in the string. It looks like something with the fire event function is causing this issue.

Does anybody has an idea what is going on? I tested this in Chrome 19

License

What's the Bean license?

I couldn't find the license anywhere. MIT would be cool!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.