I have function to detect idle state of user. I want to update database if any of the event occurs.Now i have script like this
$("body").mousemove(function(event) {
myfuction();
});
I want to convert above script like this
$("body").anyOfTheEvent(function(event) {
myfuction();
});
How can i do this?
You can find the event name using the e.type property. Try looking this example
$('#element').bind('click dblclick mousedown mouseenter mouseleave',
function(e){
alert("EventName:"+e.type);
});
The jsfiddle for this is here http://jsfiddle.net/qp2PP/
You could have an array of the events you're interested in and subscribe to all of them
var events = ['click','mousemove','keydown'] // etc
$.each(events,function(i,e){
$('body')[e](myfuction);
});
Get a list of events here: http://api.jquery.com/category/events/
You can bind more than one event with bind()
$('#foo').bind('click mousemove', function(evt) {
console.log(evt.type);
});
just use on(), with a space-delimited list of events:
$('body').on('mousedown click', function(e) {
var eventType = e.type;
// do stuff
});
References:
on().
Instead of bind to specific element, you can bind directly to document.
$(document).bind('click mousemove', function(evt) {
document.getElementById("demo").innerHTML = Math.random();
});
Example in CODEPEN
Related
I am trying to let Jq listen to three buttons at the same onclick method
then trigger a function and call the clicked button by $(this);
here is a sample :
$("body").on('click', 'a.home:visible', 'a.mobile:visible', 'a.phone:visible', function () {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
You did it basically correct. Your approach is fine. But you have to combine it in one string, not as single parameters. And you don't need :visible, because you can't click on invisible elements. ;)
$("body").on('click', 'a.home, a.mobile, a.phone', function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
If the elements are static you should even use a normal event listener instead of a delegation.
$('a.home, a.mobile, a.phone').click(function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
Put them in one quotes
$("body").on('click', 'a.home:visible,a.mobile:visible,a.phone:visible', function() {
alert('Clicked')
});
JSFIDDLE
JSfiddle jsfiddle
I would like to use this concept of event delegation on each name spaced event. Appernetly it is more optimized than .big-ul li. I unfortunately cannot find the proper syntax to make it work while using namespaces or while trying to attach multiple event handlers simultaneously using a plain object?
$(".big-ul").on({
"click.namespace", "li": function(event){
$(this).toggleClass("active");
},
"mouseenter.namespace" , "li": function(event){
$(this).addClass("inside");
},
"mouseleave.namespace", "li": function(event){
$(this).removeClass("inside");
}
});
example of event delegation from jquery's site
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});
You can't attach multiple events to multiple functions like that. What you could do is using an each function on an object containing all the needed infos. You could even store your namespace-name (haha) in a separate variable:
Example on jsFiddle
var $root = $(".big-ul");
var namespace = 'namespace';
var events = [
{
event: "click"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).toggleClass("active");
}
},
{
event: "mouseenter"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).addClass("inside");
}
},
{
event: "mouseleave"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).removeClass("inside");
}
}
]
for(i=0;i<events.length;i++){
$root.on(events[i].event, events[i].delegate, events[i].fn);
}
The advantage compared with the accepted solution:
It's a far more flexible solution as you could send the events-Object across modules or dynamically bind events with one single function, when you always use the same event-Object structure.
You can delegate from one root object to different child nodes, not only one.
Example:
/* events array*/
var events = [
{
root: "root-query-string",
event: "eventname",
delegate: "delegate-query-string",
fn: function
}
]
/* dynamic batch bind function */
function batchBind(events) {
for(i=0; i<events.length; i++){
$(el.root).on(events[i].event, events[i].delegate, events[i].fn);
}
}
how about something like this?
$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){
var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;
if(eventMatch == "click.namespace"){
$(this).toggleClass("active");
}
if(eventMatch == "mouseenter.namespace"){
$(this).addClass("inside");
}
if(eventMatch == "mouseleave.namespace"){
$(this).removeClass("inside");
}
});
would that not work?
EDIT
you could also replace the mutiple if statements with a switch statement if you preferred... it would probably give better performance too (if you are worried about that).
$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){
var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;
switch(eventMatch){
case "click.namespace":
$(this).toggleClass("active");
break;
case "mouseenter.namespace":
$(this).addClass("inside");
break;
case "mouseleave.namespace":
$(this).removeClass("inside");
break;
}
});
EDIT2 updated so jsfiddle will work based on what #Nirazul said.
Example on jsFiddle
The each answer given will not be more efficient than using the .big-ul li selector. My theory being that a basic on() selector runs against the selector once and connects the event immediately whereas the deferred on() with selector runs the selectors each time the events occur (to find the matching elements).
You might as well do it this way and keep it simple:
$(".big-ul li").on({
"click.namespace": function (event) {
$(this).toggleClass("active");
},
"mouseenter.namespace": function (event) {
$(this).addClass("inside");
},
"mouseleave.namespace": function (event) {
$(this).removeClass("inside");
}
});
http://jsfiddle.net/AzQBR/1/
I am happy to be overruled about the speed of deferred on() compared to non-deferred on() calls if someone can run performance stats.
Having looked over all the answers again (including my original one), I would recommend simply connecting each event separately using the deferred on() syntax:
var $bigul = $(".big-ul");
$bigul.on("click.namespace", "li", function (event) {
$(this).toggleClass("active");
});
$bigul.on("mouseenter.namespace", "li", function (event) {
$(this).addClass("inside");
});
$bigul.on("mouseleave.namespace", "li", function (event) {
$(this).removeClass("inside");
});
All the other solutions over-complicate the code. This is about a straight forward as you can get.
JSFiddle http://jsfiddle.net/AzQBR/2/
It is possible guys! But you wrote it in wrong way! Try this :
$(document).ready(function(){
$(document).on({
mouseenter: function(){
$(this).css("background-color", "lightgray");
},
mouseleave: function(){
$(this).css("background-color", "lightblue");
},
click: function(){
$(this).css("background-color", "yellow");
}
},'p');
});
I have an event listener, and an element that triggers a custom event on click. They’re set up as follows:
$(document).on('customEventName', function(e) {
// do something
});
$(document).on('click', '[data-action]', function(e) {
e.preventDefault();
$(document).trigger( $(this).attr('action') );
});
Say I have an anchor tag (<a href="#" data-target="customEventName">) trigger the click event, how would I then get at that <a> tag and its properties in my listener? I’m wanting to get at the object to parse any additional data- attributes.
Solution 1: extraParameters
Use extraParamters parameter as second argument of trigger jQuery function.
$(document).on('customEventName', function(e, dataActionElement) {
// do something
});
$(document).on('click', '[data-action]', function(e) {
e.preventDefault();
$(document).trigger($(this).attr('action'), [$(this)]);
});
From documentation:
.trigger( event [, extraParameters ] )
event
Type: Event
A jQuery.Event object.
extraParameters
Type: Array or PlainObject
Additional parameters to pass along to the event handler.
JSFIDDLE
Solution 2: custom events
According to documentation, you also can create a custom Event where you can set the target:
Category: Event Object
jQuery’s event system normalizes the event object according to W3C standards. The event object is guaranteed to be passed to the event handler. Most properties from the original event are copied over and normalized to the new event object.
$(document).on('customEventName', function(e) {
// e.target is clicked element sent using customEvent
// do something
});
$(document).on('click', '[data-action]', function(e) {
var customEvent = $.Event($(this).attr('action'), {target: this })
$(document).trigger(customEvent);
});
JSFIDDLE
You could pass it as a parameter in trigger:
$(document).on('customEventName', function(e, target) {
// do something
});
$(document).on('click', '[data-action]', function(e) {
e.preventDefault();
$(document).trigger( $(this).attr('action'), [this] );
});
you could also try something like this:
$(document).on('customEventName', function(e) {
var target = e.target;
// do something
});
$(document).on('click', '[data-action]', function(e) {
e.preventDefault();
var customEvent = $.Event($(this).data('action'), { target: this });
$(document).trigger( customEvent );
});
I would like a cross modern browser way to take a mouse event from one html element and pass it on to another.
eg.
el1.addEventListener('mousemove', function(e) {
el2.trigger('mousemove', e);
});
el2.addEventListener('mousemove', function(e) {
//THIS SHOULD BE CALLED WHEN EITHER el1
});
a jquery solution is ok but I would prefer a non-jquery solution. Is this simple?
Here is the correct code
var el1 = document.getElementById('el1');
var el2 = document.getElementById('el2');
el1.onmousemove = function(e) {
alert('el1 event');
el2.onmousemove(e);
};
el2.onmousemove = function(e) {
alert('el2 event');
};
demo
This is good if you want the event argument e to pass over to el2's event. This updated demo shows mouse position being passed over.
native should work like that
var evt;
el1.onmousemove = function() {
evt = document.createEvent('MouseEvent');
evt.initEvent('mousemove', true, true);
el2.dispatchEvent(evt);
}
You can read up on element.dispatchEvent here:
https://developer.mozilla.org/en-US/docs/DOM/element.dispatchEvent
If you accept a jQuery answer then here's the code:
// el1 and el2 are the jQuery objects of the DOM elements
el1.mousemove(function (event) {
el2.mousemove(event);
});
In pure javascript:
el1.onmousemove = function(e) {
el2.onmousemove('mousemove', e);
};
el2.onmousemove = function(e) {
};
el1.addEventListener('mousemove', handler, false);
el2.addEventListener('mousemove', handler2, false);
function handler(e) {
// do some stuff
handler2.call(el2, e); // pass el2 as this reference, event as the argument.
};
not too sure if this is what you are looking for, just name the event handlers and trigger the one off the other.
if you do not need the this reference in the second handler, use handler2(e); instead.
further readings:
Function.prototype.call
Here is a half-baked demo passing the mouse event args. I'm unsure how well supported layerX/Y is, I just used it to show the demo.
I'm trying to create a custom function that unbinds and then binds an event. It looks like this:
App.bindEvent = function(selector, eventType, eventHandler) {
$(selector).unbind(eventType);
$(selector).bind(eventType, function(event) {
eventHandler(event);
});
};
However, the problem I am facing is that I cannot use the this keyword to reference the DOM element that was clicked. For example, I cannot do this:
App.bindEvent("#my-element", "click", function() {
var myId = $(this).attr("data-my-id");
});
How would I go about getting the this keyword to point to the clicked DOM element like it does in jQuery.bind()?
Thanks for any help.
Change:
eventHandler(event);
To:
eventHandler.call(this, event);
That'll change the "scope" of your function to be the same as the scope of the original "bind" call.
How about this instead:
App.bindEvent = function(selector, eventType, eventHandler) {
var element = this;
$(selector).unbind(eventType);
$(selector).bind(eventType, function(event) {
eventHandler.call(element, event);
});
};
You need to call the handler in the context of the object:
eventHandler.call(this, event);
I think you're trying to refer to
event.target
For example:
App.bindEvent("#my-element", "click", function(event) {
var myId = $(event.target).attr("data-my-id");
});
check out jquery's event documentation