Event reverse order - javascript

I wonder how do I change the order of events.
Because I have to check when I took a focusOut with a click, if the click was inside the parent div, I can not let it happen the focusOut.
The problem, which is called first event focusOut the click event.
Is it possible to reverse the order of events? (Click - focusOut)?
http://jsfiddle.net/eL19p27L/5/
$(document).ready(function(){
$(".clean").click(function(){
$(".alert").html("");
});
$(document).on({
click: function(e){
$(".alert").append("<p>click</p>");
},
focusin: function(e){
$(".alert").append("<p>focusin</p>");
},
focusout: function(e){
$(".alert").append("<p>focusout</p>");
}
})
});
It would be even better. If I could detect what the event might turn out to generate the fucusout. Hence check if it happened within the parent div, if not a focusIn, it leaves not give a focusOut.
ATT

No, the way you have your event handler set up on a common parent, you can't change the order of the events.
But, you can attach your event handlers to the specific objects you want to watch and then you can see events for that object only.
Or, you can look at the target of the event and see which object is which and you will see that the focusOut event is on a different object than the click event.
You can see the source of the event with e.target.
Example of looking at the object that is the source of the event: http://jsfiddle.net/jfriend00/u5tLhes7/

Related

Need to get info from any element, which was clicked, but not from parent elements

Need to get info from any element, which was clicked.
Example:
<div>text1<section>text2</section></div>
and JS
$(function(){
$('body *').click(function(){
alert($(this).get(0).tagName.toLowerCase());
});
});
If I click text2, parent element throw alert too. I need only first alert from section. How I can block next alerts from all parent elements of section.
Use event.stopPropagation() to prevent the event from firing on the containing elements.
$(function(){
$('body *').click(function(e){
e.stopPropagation();
alert($(this).get(0).tagName.toLowerCase());
});
});
Just wanted to expand on Kooilnc answer - Using on with event delegation is another option.
Event delegation would be nice if you have an event listener bound before or after on a node that needs to listen to a click handler that has bubbled up. If you stopPropagation, this obviously would be an issue.
Here's a fiddle with a demo:
http://jsfiddle.net/ahgtLjbn/
Let's say a buddy of yours has bound an event listener to a node higher up in the DOM tree. He expects any events that bubble up to it, to be handled by his script.
Using event delegation, the event still bubbles up (so your buddies code will still fire), but it will only alert once (since we called e.stopPropagation).
Calling on without event delegation, or binding the event directly using click (which, under the hood, is just calling on) will prevent the event from bubbling, so your buddies code will never run.

Access all event listeners in Javascript

I want to do something like this:
function('string', function2(){})
where I leave the to user to write what he wants in the string parameter and than execute function2.
The catch is here: string is an event listener. When the user writes click, I want to call onClick(), when the user writes mouse I want to call onMouseOver and so on.
I have in mind doing something with case, but how can I access all event listeners?
You should use addEventListener.
element.addEventListener("string", function() {}, false);
However, in the case of IE <= 8, you will need to use attachEvent as it does not follow the standard:
element.attachEvent("string", function() {});
Finally, as kybernetikos mentions in his comment, you can then use a simple dictionary to map mouse to mouseover.
If you wish to fire events, you should use dispatchEvent.
If you add the event listeners using the old model (i.e. elem.onclick = function(){ /* */ };), you can use
elem['on' + event]();
Keep in mind that this only fires the event listeners, but doesn't create an event (e.g. it won't bubble).
If you won't to create a event, which fires event listeners added using addEventlistener, and bubbles, and does all things a real event does, you must
Create your event using event constructors: Event or CustomEvent
Fire it with dispatchEvent
See MDN page for more information and examples.
you can use .trigger to do this. Check out this example in jsfiddle. type "dblclick" in the input box.
http://jsfiddle.net/jspatel/Suj4H/1/
<input id="writehere"> </input>
$('#writehere').dblclick(function() {
alert ('dblclick');
});
$('#writehere').bind('keypress', function(e) {
if(e.keyCode==13){
$(this).trigger( $(this).val() );
}
});

blur event: get the element clicked from inside the blur event

Is it possible to get the dom element that was clicked from the blur event.
myTxtBox.blur(function (e) {
var myTxtBoxClass = e.target.className
var getClassOfElementclicked == //get the class of clicked element
});
I think you should use .click(function(){}); to get clicked object. Then you can set it to blur. Right now it is unclear what initiates the blur event in the first place.
If you want to see which object that is currently "blurring" is clicked, you could assign a class to the objects when they blur and assign click event to this class.
blur can be called for more than just clicking away from a control--the user could have tabbed away. If all you're interested in is the target of a click event, then you can register a handler for clicks.
However, if you're more interested in the elements that gain & lose focus in close proximity to one another (they are two separate events, so you can't really consider a blur to have a "newly-focused target" attribute, you can use something like this:
$('input').blur(function (e) {
console.log('lost focus: ', e.target);
});
$('input').focus(function (e) {
console.log('gained focus: ', e.target);
});
http://jsfiddle.net/Palpatim/QUDED/
Also, be sure to see the discussion of blur() in the jQuery documentation: the event doesn't bubble in IE, so depending on your use case, you may wish to use the focusout event instead.

Capture only hashchange events not resulting from anchor clicks

I am trying to use Javascript to emulate the CSS :target pseudo-class so as to capture all events that result in an element on page being targeted. I've identified 3 trigger events:
window.location.hash already targets an element of the same ID on initialisation
An anchor targeting the element is clicked
The hashchange event is fired independently of the above (for example via the window.history API)
Scenario 2 is important as a distinct case since I would want to invoke the click event's preventDefault. The simplified code for this scenario follows:
$('body').on('click', 'a[href*=#]', function filterTarget(clickEvent){
$(this.hash).trigger('target', [clickEvent]);
});
The problem comes when trying to implement scenario 3:
$(window).on('hashchange', function filterTarget(hashChangeEvent){
$(this.hash).trigger('target', [hashChangeEvent]);
});
If a target handler doesn't cancel the native behaviour for scenario 2, it will be triggered again when the native behaviour causes the resulting hashchange event. How can I filter out these edge cases?
POST-SOLUTION EDIT:
roasted's answer held the key — handle a namespaced hashchange event, then unbind and rebind the handler based on logic handled inside the click handler and its preventDefault. I wrote up the full plugin here.
If i understand it, you don't want the hashchange event to be fired if an anchor tag is clicked. You could then set your logic using namespaced events:
DEMO
$('body').on('click', 'a[href*=#]', function (clickEvent) {
filterTarget(clickEvent,this);
$(window).off('hashchange.filter').on('hashchange.tmp', function () {
$(this).off('hashchange.tmp').on('hashchange.filter', filterTarget);
});
});
$(window).on('hashchange.filter', filterTarget);
function filterTarget(event,elem) {
$(elem?elem.hash:window.location.hash).trigger('target', [event]);
//you could filter depending event.type
alert(event.type + '::'+ (elem?elem.hash:window.location.hash));
}
if the click is setting the hash with the fragment anyway, just throw away duplicates in the hash change event:
onhashchange=function(e){
if(e.newURL == e.oldURL ){return; }
//do your normal hashchange event stuff below:
};
ref: https://developer.mozilla.org/en-US/docs/Web/API/window.onhashchange
this fixes cascade issues no matter what invoked the change.
Seems like you could use mousedown instead of click, if you're going to be calling preventDefault on it. Then presumably the hashchange would not be triggered.

jquery - perform effect on any event

i have 5 elements in a page.
i have selected them using class names $('.class')
i am trying to perform a function for those selected elements irrespective of event (click or hover or watever).
eg:
$('.class').hover(function(){definition1});
$('.class').click(function(){definition1});
i dont want to have 2 seperate event as above 2, instead i want the function to be executed irrespective of whether its hover or click event.
$('.class').bind('click mouseenter', function() {
// Go nuts.
});
(if using jQuery >= 1.7, swap bind() with on().)
Keep in mind that hover()'s second argument is for mouseleave event, which you haven't written anything for here.
If you want to cover most events, pass in 'blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error' as the first argument.
You could also try to detect them with code by iterating over properties that start with on, but it sounds too flaky to me.
To bind multiple events to one element in jQuery 1.7 and later you can do the following by separating event names by spaces:
jQuery('.class').on('click hover mousenter mouseleave', function(event){
// do what you need to do
});
which you can see in jsfiddle.
But: be careful, because you can easily fire the event too much times (more than necessary and more than enough). By binding so many events some may be called unnecessarily (as in the example above the code will be fired twice when the mouse cursor will leave the element it hovered over).
If you do not want to exec a function without any event put it in
$(function(){
function test(){definition1}
});
then in html
<body onload="test();">

Categories