Skip to main content

Bug Tracker

Side navigation

#11047 closed bug (patchwelcome)

Opened December 17, 2011 12:14AM UTC

Closed December 17, 2011 12:48AM UTC

Last modified September 19, 2013 05:56PM UTC

If you trigger a custom event you can NOT catch it using the addEventListener function

Reported by: anonymous Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.7.1
Keywords: Cc:
Blocked by: Blocking:
Description

The trigger function should also dispatch custom events such that code using addEventListener can catch the custom event. However, that is not happening. In fact, that is the only of the 8 combinations listed below that does not work. We should fix this to allow better interoperability between jQuery event functions and W3C DOM event functions.

1. PASS: If you trigger a DOM event you can catch it using the bind function

2. PASS: If you trigger a DOM event you can catch it using the addEventListener function

3. PASS: If you trigger a custom event you can catch it using the bind function

4. FAIL: If you trigger a custom event you can NOT catch it using the addEventListener function

5. PASS: If you dispatch a DOM event you can catch it using the bind function

6. PASS: If you dispatch a DOM event you can catch it using the addEventListener function

7. PASS: If you dispatch a custom event you can catch it using the bind function

8. PASS: If you dispatch a custom event you can catch it using the addEventListener function

The code below shows all the combinations listed above, including the failing case. It reproes under all major browsers in Windows 7. There is also a jsFiddle at: http://jsfiddle.net/Jqeza/3/

<html>
<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <button id="idButtonTrigger" onmouseover="TriggerEvent()">Hover to Trigger Event</button>
  <button id="idButtonDispatch" onmouseover="DispatchEvent()">Hover to Dispatch Event</button>
  <p>ClickListener: <a id="idClickListener"></a></p>
  <p>ClickBind: <a id="idClickBind"></a></p>
  <p>CustomListener: <a id="idCustomListener"></a></p>
  <p>CustomBind: <a id="idCustomBind"></a></p>

  <script type="text/javascript">

    document.addEventListener('click', function(event) {
      document.getElementById('idClickListener').innerHTML = "Fired!";
      $('#idClickListener').fadeIn('slow').fadeOut('slow');
    });

    $(document).bind('click', function(event) {
      document.getElementById('idClickBind').innerHTML = "Fired!";
      $('#idClickBind').fadeIn('slow').fadeOut('slow');
    });

    document.addEventListener('custom', function(event) {
      document.getElementById('idCustomListener').innerHTML = "Fired!";
      $('#idCustomListener').fadeIn('slow').fadeOut('slow');
    });

    $(document).bind('custom', function(event) {
      document.getElementById('idCustomBind').innerHTML = "Fired!";
      $('#idCustomBind').fadeIn('slow').fadeOut('slow');
    });

    function TriggerEvent() {
      $('#idButtonTrigger').trigger('click');
      $('#idButtonTrigger').trigger('custom'); // CANNOT catch with addEventListener
    }

    function DispatchEvent() {
      var clickEvent = document.createEvent("MouseEvents");
      clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
      document.getElementById('idButtonDispatch').dispatchEvent(clickEvent);

      var customEvent = document.createEvent('Event');
      customEvent.initEvent('custom', true, true);
      document.getElementById('idButtonDispatch').dispatchEvent(customEvent);
    }

  </script>
</body>
</html>
Attachments (0)
Change History (5)

Changed December 17, 2011 12:48AM UTC by dmethvin comment:1

resolution: → patchwelcome
status: newclosed

jQuery's event system is a level *above* the native one, we're not trying to shim the browser functionality.

For example case 2, we actually "fail" that for custom event names. The only reason it works for most browser events is that calling the corresponding DOM method name fires the event.

Doing what you describe is pretty difficult, especially when you take IE<9 into account with .attachEvent/.fireEvent. Your examples aren't doing that so they aren't cross-browser compatible. And you have to still retain the current semantics (like optional trigger data) to avoid breaking all the thousands of sites and plugins out there.

Experiment with it in your own branch and see if you agree it's pretty tough.

Changed December 17, 2011 11:21AM UTC by anonymous comment:2

All that's being said here is that the trigger method should do a dispatchEvent (where supported) on custom events so that listeners using addEventListener can catch the custom event. For instance, something similar to the following piece of code at the end of the trigger method would be enough.

if (isCustomEvent(event) && elem.dispatchEvent) {
  var customEvent = document.createEvent('Event');  
  customEvent.initEvent(event.type, true, true);  
  if (data != null) {
    customEvent.data = data;
  }
  elem.dispatchEvent(customEvent);  
}

Where isCustomEvent(event) is a function that would return true if the event type is not one of the standard DOM events. This way, clients that are written purely using W3C's DOM Event model could still listen to custom events (in addition to standard DOM Events) fired by jQuery without having to modify any code (and without having to take a dependency on jQuery either).

Changed December 17, 2011 03:01PM UTC by dmethvin comment:3

do a dispatchEvent (where supported)

In general we haven't tried to implement functionality that only works on some browsers (and some events) but not all, since someone will immediately file a bug that it doesn't work right.

Where isCustomEvent(event) is a function that would return true if the event type is not one of the standard DOM events.

Can you post a cross-browser implementation of that?

Changed January 23, 2013 09:44AM UTC by nelson@fittopage.org comment:4

Changed September 19, 2013 05:56PM UTC by anonymous comment:5

You can use this plugin which has a method betterTrigger

https://github.com/sandeep45/betterTrigger