Trigger event handler with custom event object - javascript

Is it possible to trigger an event on some object with a custom event object?
i.e.
$('#Element1').click(function(event){
console.log('Element1 clicked', event);
}
$('#Element2').click(function(event)
{ //handle click on one element
//optionally modify the event object
event.target=Something;
//Trigger the event handler(s) on some other element using modified event object
$('#Element1').click(event);
});
A bit of background:
In my instance Element2 is an almost identical clone of Element1 but with different position. When Element2 is clicked that click should be forwarded to Element1.
I already have code to identify the correct child of Element1 according to which child of Element2 was clicked but the click event handler on the child of element 1 requires the pageX and pageY properties to be set correctly and .click() omits these properties entirely.
It does not suffice in my example to do a deep clone and include the event handlers because the target property is incorrectly set.
One workaround in my instance would be for the cloned element to retain a reference to the original element (and for every child) and the handler to check for that reference, however, I would prefer a solution where the handler has no knowledge of the cloning process - not least because there are a LOT of handlers to modify!

I am not understand well your background logic, but you can try with trigger from jQuery. You can trigger event reusing the event object:
$('#Element1').click(function(event){
console.log('Element1 clicked with changed event: ' + event.something);
});
$('#Element2').click(function(event){
event.something = "Something";
$('#Element1').trigger(event);
});

You can try with .trigger() it accepts an event object as the argument
$('#Element1').trigger(event);
Demo: Fiddle

Related

using event.target vs selecting the element

Is there a difference between working a property of an element through the event.target vs working it directly?
I don't understand if there's any difference.
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(e) {
console.log(e.target.value);
//vs
console.log(btn.value);
}
Is there a better practice when doing this?
Yes, there is an important difference. The event.target property tells you what element was involved with the creation of the event. For a "click", it's the element that was under the cursor when the "click" happened.
Thus if your HTML looked like:
<button><span>Text</span><img src="something.jpg"></button>
a click on the button content would trigger the event from either the <span> or the <img>, and one of those elements would be the target.
There's another event property, event.currentTarget, that is always a reference to the element to which the event handler is attached. That's probably what you want. Alternatively, if you bind handlers with .addEventListener(), then the value of this when the handler is invoked will be a reference to the same thing as currentTarget.
In your case you're selecting an element by ID. Your reference is the same as the target so there is no difference. A lot of time we use delegation so you might not have reference to the clicked element. Hence we use target from the event object.
Worth also to check target vs currentTarget

Event stops working after dynamic ul li changes

The Code:
if($('.info-dropdown').length){
setTimeout(function(){
$('li').has('input[type="checkbox"]').on('click', function(){
$(this).find('.brand-checkbox').parent().toggleClass('active');
});
}, 10);
}
The Problem: This code detects event click on element checkbox. After dynamically changing this ul li the event stops working.
Note: These checkboxes are from bootstrap dropdown menu.
To bind event for dynamic HTML, You can follow below code :
$('containerSelector').on('eventName', 'mainElementSelector' function(e){
});
Realtime example
$("ul").on("click", "li:has(:checkbox)", function(){
});
Event handlers added directly to an object are added only to that specific DOM object. If you then add or replace more DOM objects, those DOM object won't have any of these event handlers on them. You will have to either manually add the event handlers after you create or replace the DOM objects or you will have to switch to using delegated event handling.
Delegated event handling attaches the event handler to a common parent object (that is not replaced) and uses the fact that many events bubble up the parent chain in order to process the event from the common parent. This allows you to freely create or replace child elements, but still have one event handler that works for all child objects.
You can read a lot more about how to do delegated event handling in these other answers:
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Does jQuery.on() work for elements that are added after the event handler is created?
JQuery Event Handlers - What's the "Best" method
As illustrated in those referenced answers, the general idea is like this:
$("#staticParentSelector").on("click", ".selectorForDynamicChildren", function(e) {
// event handler code here
});

Difference of $(document) and $('parentSelector') for adding events of dynamically add element?

I am confused with the $(document) in using this as my selector for a click event? Any difference or cos instead of using only the parent selector?
Both of them produces the same output but is there any factor like executing speed?
You can test this FIDDLE
var counter = 0;
Using parent selector
$(".parent").on("click", "button.btn", function(){
$(".parent").append("<button class = 'btn'> new button " + (++counter) + "</button><br />");
});
or $(document)
$(document).on("click","button.btn",function(){
$(".parent").append("<button class = 'btn'> new button " + (++counter) + "</button><br />");
});
You need to provide the closest parent selector which does not get dynamically generated and all the future element to whom event delegation is needed should be child elements of the static parent element.
when it comes to performance, delegating the event to closest static parent is more feasible compared to attaching to document or body of page.
You should generally bind to the most restrictive element that contains the dynamic elements that you want to delegate to. The way delegation works is that an internal jQuery handler is run every time the event occurs anywhere in the element that you bind to. This handler performs a check to see if the target matches the selector argument, and if so it calls your handler function.
So if you use $(document).on, it will have to do this check anytime you click anywhere on the page. But if you use $(".parent").on it only has to do the check when you click inside the parent element. This is less overhead on the browser.
Also, delegation depends on the event bubbling out to the element you bind to. If there's an element that contains button.btn and it has a click handler that calls event.stopPropagation(), this will cancel the bubbling, and the jQuery's internal handler will never be run. Binding to the parent should make this unlikely.

Jquery Dynamic Event firing from an element

I'm trying to get the event associated with an element and try to trigger the respective event. For example if I pass an id for a textbox and it has an event focus binded with it, then I want to trigger that focus event. I know we can get the event details by using
$.data('selector', 'events');
but how to use this object? This should be in jquery or javascript.
Thanks in advance
Not sure why on Earth would you need this. Try triggerHandler
var item = $("selector"),
trigger = function(name){
item.triggerHandler(name);
};
$.each($.data(item[0], "events"), trigger);
Warning This code won't work with delegated events and such. It only triggers handlers bound to matched element.

Override all JavaScript events bound to an element with a single new event

Assuming that there are a large number of elements throughout the site that have an unknown number and type of events bound to them.
If I need to override all of these events with one single bound event, and only that event will fire, what are some recommendations?
I would be binding the event to a click event handler, and I am using jQuery.
Thanks in advance.
You’re looking for jQuery#unbind.
To remove all event handlers on an element or a set of elements, just do:
$('.some-selector').unbind();
To unbind only click handlers, use unbind('click'):
$('.some-selector').unbind('click');
To unbind all click handlers and immediately bind your own handler after that, you can do something like this:
$('.some-selector').unbind('click').click(function(event) {
// Your code goes here
});
Note that this will only work for events bound using jQuery (using .bind or any jQuery method that uses .bind internally). If you want to remove all possible onclick events from a given set of elements, you could use:
$('.some-selector')
.unbind('click') // takes care of jQuery-bound click events
.attr('onclick', '') // clears `onclick` attributes in the HTML
.each(function() { // reset `onclick` event handlers
this.onclick = null;
});
I would like to provide a thought without removing all events all together (just override them).
If your new one single bound event (we call it "click" here) is specific to the element it binds to, then I believe you can ignore any other events simply by stopPropagation() function. Like this
$("specific-selector").on("click", ".specific-class", function (e) {
e.stopPropagation()
// e.stopImmediatePropagation()
/* your code continues ... */
});
It will stop events bubbles up, so your other events won't fire. use stopImmediatePropagation() to prevent other events attached onto the same elements as "click" does.
For example, if "mouseleave" event is also bind to $("specific-selector .specific-class") element, it won't fire, too.
At last, all other events won't fire on this element but your new "click" element.
The unsolved question is, what if other events also use stopPropagation()? ... Then I think the one with best specification wins, so try to avoid complex, too many events is final suggestion.
You can see "Direct and delegated events" on jQuery site for more information.
Looks like this is pretty simple actually:
$('#foo').unbind('click');
$('#foo').bind('click', myNewFunction);
Thanks for your responses though.
Try to use live instead of bind. Then you can easily remove live binding with die from selector which is fast operation and set another live equally fast.
$('selection here').live('..', .....); // multiple invocations
$('selection here').die();
$('selection here').live('click',.....);
DOM is not touched at all. Event condition is evaluated on event occurrence.
But generally if you just want to swap handler functions why not to do it this way:
var ahandler = function(evt) { /* first implementation */ }
$('.selector').bind('click', function(evt) { ahandler(evt); });
//and then if you want to change handlers
ahandler = function(evt) { /* new implementation */ };
This gives absolutely no cost of any changes, rebinding etc.

Categories

Resources