Graham
Graham

Reputation: 8151

How to check if the same event handler already exists in jQuery

If two different processes add a click handler to an element. Both these handlers are needed. What I want to do is check if one of the handlers already exists.

I can use:

$._data(ele, "events")

to get all the events on an element, but how do I know which click event handler is the one I want?

ele.click(handler1);
ele.click(handler2);

var handlers = $._data(ele,get(0), "events");

if (*some code that finds if handler1 is already there*)
  ...

Using jQuery 2.1.4 (can't change it).

Upvotes: 1

Views: 658

Answers (2)

fpierrat
fpierrat

Reputation: 804

I needed to test handler with namespaces, it finally looks like this:
(thanks to @mplungjan for the foundations):

function hasHandler($ele,namespacedHandler){
  [handler,namespace] = namespacedHandler.split('.');
  ev = $._data($ele.get(0), "events")[handler];//events for given handler ('click', 'message', etc...)
  if(namespace){ ev = ev.filter(e => e.namespace===namespace); }//eventually filtered on namespace if given
  return ev.length>0;
}

Usage:

if(hasHandler($("#foo"),'click.bar')){ ... }

Upvotes: 0

mplungjan
mplungjan

Reputation: 177786

Looking for specific handler

const handlerIs = ($ele, handler, func) => {
  const events = $._data($ele.get(0), "events");
  func = func.toString();
  return events && 
    events[handler]?.some(ev => ev.handler.toString() === func);
};

const $ele = $("button");

const clicked = () => alert("clicked");

$ele.on("click", clicked)
$ele.on("click", clicked)

if (handlerIs($ele, "click", clicked)) {
  console.log(`click clicked exists on ${$ele.get(0).tagName}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

<button type="button">Mouseover or click</button>

Just looking for click handlers

It could be implemented as a $fn to be called $ele.hasHandler...

const hasHandler = ($ele,handler) => Object.keys($._data($ele.get(0), "events"))
  .filter(key => key===handler).length>0;


const $ele = $("button");

$ele.on("click",function() { alert("clicked") }); // define click once

if (!hasHandler($ele,"click")) { // test before trying again
   $ele.on("click",function() { console.log("another click") }); 
}
else console.log(`click already found on ${$ele.get(0).tagName}`)

/* 
Object.entries($._data($ele.get(0), "events"))
  .forEach(ent => console.log(ent[0],ent[1][0].handler))
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

<button type="button">Mouseover or click</button>

Upvotes: 3

Related Questions