andreruffert / rangeslider.js

🎚 HTML5 input range slider element jQuery polyfill
https://rangeslider.js.org
MIT License
2.16k stars 399 forks source link

The $.trigger events do not fire vanilla JS eventlisteners #241

Open kontur opened 8 years ago

kontur commented 8 years ago

The plugin triggers the input and change events via $.trigger, but those "events" are only received by jQuery's $.on listeners, not by vanilla event event listeners.

In the case where I have a range input transformed via rangeslider.js I can use $.on('input', handler) to react to changes, but using .addEventListener('input', handler) will not trigger on changes.

You can see this issue apparent in this fiddle - the button to generate the pure event as well as typing in the input will trigger both listeners, while triggering just the jquery event, as done by the plugin, will be received by the jquery listener.

The workaround I have used is to listen for the jquery event with the plugins callbacks, and then explicitly create a event object and trigger it on the input, but I imagine it would make sense to create and trigger the actual event in the plugin itself - as the Fiddle shows, the real event will also trigger the jquery .on() handler, when of same name as the event type of the vanilla event. I.e. my workaround looks like this:

onSlideEnd: function (position, element) {
                var evt = document.createEvent('HTMLEvents');
                evt.initEvent('input', true, true);
                this.$element[0].dispatchEvent(evt);
            }

It's up for decision how this should be handled, but for me this resulted in quite a lengthy search for a bug.

chris commented 6 years ago

Thanks for this, this solved it for me as well. That said, this (or maybe something else related?) doesn't seem to work on IE 11. As it turns out, (as you mention), I needed to add dispatching of the "change" event as well in order for it to trigger on IE. I dispatch both the input and change events, and this seems to still work fine in Chrome and others, and then in IE 11 as well. e.g.:

  function onSlideEnd(position, element) {
    var inputEvent = document.createEvent('HTMLEvents');
    inputEvent.initEvent('input', true, true);
    this.$element[0].dispatchEvent(inputEvent);

    var changeEvent = document.createEvent('HTMLEvents');
    changeEvent.initEvent('change', true, true);
    this.$element[0].dispatchEvent(changeEvent);
  }