I want to pass eventObject with trigger function, means when i manually trigger any event say:
$(".test").bind({ click : Testing });
$('.test').trigger("click");
function Testing(e)
{
}
When the function testing is called by mouseclick , the parameter e contains the eventobject, so i want this same thing when we trigger it manually.Can we pass eventobject when we trigger any event manually, Is this possible?
As gdoron points out (+1), jQuery will supply the event object for you. But you can create it explicitly if you like, to fill it in with information that jQuery can't fill in for you. You can create an Event object and pass it into trigger.
Here's an example of both using the default event object and creating your own: Live copy | source
jQuery(function($) {
$(".test").click(function(e) {
display("Received click on target");
display("typeof e = " + typeof e);
if (e) {
display("e.type = " + e.type);
if (e.type === "click") {
display("Coords: (" + e.pageX + "," + e.pageY + ")");
}
}
});
//Create a new jQuery.Event object without the "new" operator.
var e = $.Event("click");
// Fill in more info
e.pageX = 42;
e.pageY = 27;
// Trigger an artificial click event
display("Issuing a click via <code>$('.test').trigger('click')</code>");
$('.test').trigger("click");
// Trigger an artificial click event
display("Issuing a click creating our own event object with more info on it.");
$('.test').trigger(e);
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
You don't need to do anything, the Event object is there already when you trigger an event as well....
The event object is always passed as the first parameter to an event handler
...
...
trigger docs
Live DEMO
Related
There is the following JS:
for (var catId in this.data.categories) {
(function (catId) {
$("li#tsCat-" + catId).click(function (event) {
$(this).addClass("tax-active");
event.stopPropagation();
})
}(catId))
for (var floor in this.data.floors) {
(function (floor, catId) {
var selector = "#tsCatFloor_" + catId + "_" + floor;
$(selector).on("click", function (event) {
$(this).addClass("active-filt");
event.stopPropagation();
});
}(floor, catId));
}
}
This code forms two level list.
On clicking links on 1st level, it executes correct click handler $("li#tsCat-" + catId).
But on clicking 2nd level it again executes 1st handler $("li#tsCat-" + catId).
It needs to execute 2nd handler $(selector).
Where is the problem?
Sorry, I didn't provided the full view, but what is good I found a solution what could be useful for everyone:
If You're adding .click() event be sure, that You put the data (against which .click is called) already to DOM. Otherwise .click will never be called.
I have added a function to jQuery prototype as below. What I want to do is when this method is invoked, generate an html form based on the arguments passed to the method and show it in a colorbox.
(function($) {
$.fn.myFunction = function(data){
var form = $('<form name="people"></form>');
var index;
for (index = 0; index < data.length; index++) {
var match = data[index];
$('<input type="radio" name="person">' + match['name'] + ' [' + match['uri'] + ']<br> ')
.attr("value", match['uri'])
.appendTo(form);
}
$('<input type="button" id="a_button" value="Add"/><br>')
.appendTo(form);
var list = $('<div>').append(form).html();
$('#a_button').click(
function(){
console.log('message from event handler');
}
);
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
};
})(jQuery);
As you can see, form has a button called Add using which I hope to make an ajax request. But unfortunately click event handler attached to this button doesn't seem to be invoked.
Does anyone have any idea about what's wrong here? myFunction is actually invoked by a drupal ajax command in case if that's helpful.
You are appending the form to the DOM after attaching the event handler.
$('#a_button') searches the DOM at that specific point in time, but the form is not added to the DOM until after your call to colorbox with list as a parameter.
Try a permanent delegated event handler instead (or simply add the click handler after the colorbox line).
e.g.
$(document).on("click", "#a_button", function(){
console.log('message from event handler');
});
or
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
$('#a_button').click(
function(){
console.log('message from event handler');
}
);
I have a click event
$('#ship_Move').click(function (event) {
event.stopPropagation();
$('.shipActionsList').remove();
moveShip(shpID);
});
that calls a function moveShip
function moveShip(shp_id) {
$('.fieldDivs').click(function () {
$("#hello").append("Move "+ shp_id + "to " + $(this).attr('id')+"<br/>");
});
}
And the debugging is giving the right results - but with one problem. If I first click the #ship_Move element 4 times, and then select a destination (.fieldDivs) I get this:
Move 162 to FD455
Move 162 to FD455
Move 162 to FD455
Move 162 to FD455
Because the moveShip function has been called 4 times, and each of them are waiting for a .fieldDivs element to be clicked, and when it is clicked, all 4 of them append their results (162 is the ship ID I want to move, FD455 is its destination).
What I need is something among these lines:
function moveShip(shp_id) {
$('.fieldDivs').click(function () {
$("#hello").append("Move "+ shp_id + "to " + $(this).attr('id')+"<br/>");
// IF A NEW #SHIP_MOVE IS CLICKED, END THIS FUNCTION AS IT WILL BE CALLED AGAIN
});
}
I know I can return false to break functions, but for a click event I need a new function, so return false would just end the click event inside that event. What I mean is - if you exchange the above commented line //IF A NEW SHIP with the following code:
$('.ship_Move').click(function () {
// return false would break this function
});
This code will only end this click event, but not the moveShip function.
I hope I made myself clear enough...
Thanks!
You could unbind existing click event handler beforehand:
$('.fieldDivs').off('click').click(function() {
// ...
});
If there are other click event handlers that should be kept, I suggest to use namespaced events:
$('.fieldDivs').off('click.move').on('click.move', funciton() {
// ...
});
Though, after thinking about it, instead of binding event handlers over and over again, you could just bind them once and share necessary data via variables:
$(function() {
var shpID = ...; // however this is set
$('#ship_Move').click(function (event) {
event.stopPropagation();
$('.shipActionsList').remove();
// set shpID here somehow?
});
$('.fieldDivs').click(function () {
$("#hello").append("Move "+ shpID + "to " + $(this).attr('id')+"<br/>");
});
});
It doesn't look like you have to bind a new event handler only because shpID changes. Of course this is a simplified example since I don't know your code, but maybe it helps.
I am trying to create leverage jQuery's .on() (ex-live()) to bind multiple events. It is working for elements which exist on document.ready, but if I dynamically add a second link after page load, my event handler isn't triggered.
This makes sense since the outer-most method iterates over the elements, and doesn't listen for newly added DOM nodes, etc. The .on(..) is what listens for new DOM nodes, but requires an event name params, which I don't have until I have the DOM node.
Seems like a chick and the egg sort of situation.
Thoughts?
Test 1
Test 2
$(function() {
$('.js-test').each(function() {
var $this = $(this);
var e, events = $this.data('test-events');
for(e in events) {
$this.on(events[e], function() {
console.log("hello world!")
});
}
});
});
Update, The following does seem work either; $(this) doesn't appear to be in the right scope.
Test 1
Test 2
$(function() {
$('.js-test').on($(this).data('test-events'), function() {
// call third party analytics with data pulled of 'this'
});
});
Update 1:
I think my best bet will be to create special .on methods for all the methods I want to support like so:
$(document).on('click', '.js-test[data-test-events~="click"]' function(event) {
record(this, event);
});
$(document).on('mouseover', '.js-test[data-test-events~="mouseover"]', function(event) {
record(this, event);
});
... etc ...
$('a.js-test').on('click mouseover', function(event) {
// you can get event name like following
var eventName = event.type; // return mouseover/ click
console.log(eventName);
// you code
console.log('Hello, World!');
});
Sample example
If you want something like live event then:
$('body').on('click mouseover', 'a.js-test', function(event) {
// you can get event name like following
var eventName = event.type; // return mouseover/ click
console.log(eventName);
// you code
console.log('Hello, World!');
});
According to your last edit try this:
$('.js-test').on($('.js-test').data('test-events'), function() {
console.log("hello world!")
});
Sample example for edit
and for live event delegation
$('body').on($('.js-test').data('test-events'), '.js-test', function() {
console.log("hello world!")
});
Afraid you can't do this because you need to provide jQuery with either DOM elements or event names.
You can bind events to new DOM elements manually or bind all possible events that can be in data-test-events (if you have 3-5 of them, with all DOM events it will become a silly and slow solution) and check if your element has one of them:
$('body').on("mouseover click mouseout mouseenter mouseleave", '.js-test', function(e) {
if (!$.inArray(e.type, $(this).data('test-events').split(' '))) {
return;
}
console.log("hello world!");
});
If you want to trigger an event whenever a matching element is added to the DOM, you might want to have a look at livequery - http://docs.jquery.com/Plugins/livequery.
This code will allow you to register multiple event handlers as a function array. It's tested and working. See this jsfiddle demo and test cases.
JavaScript:
$(document).ready(function() {
eventFnArray = [];
eventFnArray["click"] = function(e) {
if(e.type != "click") return ;
alert("click event fired - do xyz here");
// do xyz
};
eventFnArray["mouseover"] = function(e) {
if(e.type != "mouseover") return ;
alert("mouseover fired - do abc here");
// do abc
};
eventFnArray["mouseout"] = function(e) {
if(e.type != "mouseout") return ;
alert("mouseout fired - do JKL here");
// do JKL
};
$('.js-test').each( (function(fn) {
return function(i) {
if(i != 0) return;
var _that = this;
var events = [];
events = $(_that).attr("data-events").split(" ");
// alert($(_that).attr("data-events") + " : " + events.join(" "));
$(this).parent().on(
events.join(" "),
'.js-test',
function() {
console.info("hello - this is the " + event.type + " event");
// alert("data-events = " + $(this).attr("data-events") + " : event.type = " + event.type);
// delegate to the correct event handler based on the event type
if($(this).attr("data-events").indexOf(event.type) != -1)
fn[ event.type ](event);
}
);
}
})(eventFnArray)); // pass function array into closure
});
HTML:
<div id="container">
Test 1
Test 2
</div>
Testing adding more elements:
Here are 3 test cases:
// adds a link with the click event attached.
$('#container').append("<a href='#' class='js-test' data-events='click'>TEst333</a>");
// adds a link with the mouseover event
$('#container').append("<a href='#' class='js-test' data-events='mouseover'>TEst444</a>");
// adds a link with mouseout
$('#container').append("<a href='#' class='js-test' data-events='mouseout'>TEs555</a>");
// adds a link with both mouseover and mouseout attached
$('#container').append("<a href='#' class='js-test' data-events='mouseout mouseover'>TEstLast</a>");
// mouseout and click
$('#container').append("<a href='#' class='js-test' data-events='mouseout click'>TEstLastForREAL</a>");
Word of caution:
I noticed that one of your links has both the click and mouseover attached. While this code will handle multiple events per link, as demonstrated by the last test case, the click event will not fire if a mouseover event is present.
This is not a fault in the above code but in the way events are processed, as demonstrated here:
// mouseover and mouseout fire, but not the click event
$('#container').on('mouseover mouseout click', '.js-test',function() { alert("afdas " + event.type); });
I have two div :
<div id="div1"></div>
<div id="div2"></div>
and i have the following jquery for div1:
$('#div1').click(function(e)
{
alert(e.pageX + ' ' + e.pageY);
});
.
Now, i want to trigger click eventhandler of div1 to execute on clcicking of div2.
For this i wrote:
$('div2').click(function(e)
{
$('#div1').trigger('click');
});
It's working fine but the problem is i am not able to get e.pageX and e.pageY in the event handler of div1.
How to pass eventdata of div2 click event handler i.e e to div1 click event handler.
Please help.
Since the event you want to trigger is of the same type, you can pass the old event object right along:
$('#div2').click(function (e) {
$('#div1').trigger(e);
});
For events of a different type, you may create a custom event object:
$('#div2').mouseenter(function (e) {
var newE = jQuery.Event('click');
newE.pageX = e.pageX;
newE.pageY = e.pageY;
$('#div1').trigger(newE);
});
jQuerys .trigger()help should be the answer here. You can pass in event-strings (along with parameters) aswell as event objects.
$('#div2').click(function(e) {
$('#div1').trigger(e);
});