Search code examples
javascriptjqueryprototypejs

Is it possible to listen to a custom prototype event from jquery?


If I fire a custom event in prototype.js can I listen for that event in jquery?

I tried this but it doesn't work

$.noConflict();

$('target').observe('custom:event', function(){
  console.log("prototype method");
});

jQuery("#target").on("custom:event",function(){
  console.log("jquery method");
});

$('target').fire('custom:event');
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="target"></div>


Solution

  • You can, but you don't use the custom event's name. You would set an event listener for the event dataavailable, as that is what Prototype sets any custom events to go through.

    https://github.com/sstephenson/prototype/blob/560bb59414fc9343ce85429b91b1e1b82fdc6812/src/prototype/dom/event.js#L635

    if (isCustomEvent(eventName))
      observeCustomEvent(element, eventName, responder);
    else
      observeStandardEvent(element, eventName, responder);
    

    https://github.com/sstephenson/prototype/blob/560bb59414fc9343ce85429b91b1e1b82fdc6812/src/prototype/dom/event.js#L654

     function observeCustomEvent(element, eventName, responder) {
        if (element.addEventListener) {
          element.addEventListener('dataavailable', responder, false);
        } else {
          // We observe two IE-proprietarty events: one for custom events that
          // bubble and one for custom events that do not bubble.
          element.attachEvent('ondataavailable', responder);
          element.attachEvent('onlosecapture',   responder);
        }
      }
    

    So to listen for a Prototype event do something like:

    jQuery("#target").on("dataavailable",function(e){
      if(e.originalEvent.eventName == "custom:event"){
        doWhatever();
      }
      //Or even do a trigger through jQuery by passing the 
      //event target and event name
      //this will allow you to just set events like you were
      //with jQuery and not need a bunch of if statements
      jQuery(e.target).trigger(e.originalEvent.eventName);
    });
    

    Demo

    jQuery.noConflict();
    var protoTarget = $('target');
    var jQueryTarget = jQuery('#target');
    
    protoTarget.observe('custom:event', function(e){
      protoTarget.append('Prototype callback');
    });
    
    jQuery(document).on("dataavailable",function(e){
      jQuery(e.target).trigger(e.originalEvent.eventName);
    });
    
    jQueryTarget.on("custom:event",function(){
      jQueryTarget.append("<br>jQuery callback");
    });
    
    $('target').fire('custom:event');
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div id="target"></div>