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

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.

Related

Handle blur event of parent element fired by focus on child element and by clicking outside of child

I have a "parent div" containing a child box input type=number. When user clicks outside of input box I use blur or focusout event of parent div to use input values at some other place.
I also need to use $('inputbox').trigger('focus') at some place, which fires "parent div"'s blur event unwantedly and runs code on that event.
Please give a solution to stop this parent blur event on child's focus OR give a way to find whether focus is made by trigger('focus') on child element or by user clicking outside of parent div.
I need to fire parent Blur only when user clicks outside of it & not when focus is triggered through code.
with jquery you can make custom events very easily , something like:
$('inputbox').trigger('special-focus');
then you can wait for this event just like any other event:
$('div').on('special-focus' , function(){ ... } );
this will prevent your events from interfering with the built in ones.
I guess if you don't want to use that suggestion then do this in your click handler or your focus handler of the child
.on('focus' , function(e){
e.stopPropagation();
e.preventDefault();
/// the rest of your code ...
});
this will stop the propagation of events to parent elements
This worked perfect for me:
if (e.relatedTarget === null) ...
What worked for me was checking the relatedTarget property of the eventObject object in the handler function.
$("#parentDiv").focusout(function (eventObject) {
if (eventObject.relatedTarget.id === "childInputId")
/// childInput is getting focus
else
/// childInput is not getting focus
});
.on('blur',...) of parent fires before .on('focus' ,...) of child.
Anyways for a parent div containing child input box
we can use $('input').trigger('special-focus');
and then
$("#form" ).on('special-focus', '.parentdiv' , function(event) {
$("#form" ).off('blur', '.parentdiv');
$(event.target).focus();
$("#form" ).on('blur', '.parentdiv' , showValuesOnBlur);
});
Now blur of parent will not fire on focus of child.This worked for me. i.e. off & on the blur event of parent inside special-focus.
Thanks Scott Selby :)

Event reverse order

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/

Is it possible to assign prevent default for all the events of an element at once? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jQuery - How can I bind all events on a DOM element?
Imagine, if we want to make some element completely initeractable.
We could, of course bind a prevent default for a click event as follows:
$('form *').bind('click', function(event) {
event.preventDefault();
});
But that's just one event, and there are many more, like hover, focus, selectstart, and many more.
We could specify them all in one line like 'click focus hover dblclick blur selectstart' but that doesn't make much sense and is not easy to maintain.
So, is it possible to bind an event listener without discriminating for the type of the event? Maybe some native JavaScript listeners allow it?
No such possibility because not all elements support same events and not all events behave in the same way. You always have to explicitly provide a list of events whether defined statically or dynamically by a script that spits out event names.
Even though I linked to a script that creates an array of event names, these are made on one element only. You should of course be generating this with a more complex and slower script that enumerates over all elements in question and adds missing events. Using Javascript objects as associative array for faster searching whether a particular event has been added or not.
A better suggestion
What you're trying to do is likely a highly over-engineered solution. When I'm creating a demo clickable interface that should disable some elements (be it links, buttons or anything else) I rather do it by defining a CSS class that disables an element in question and have a simple script that does disabling afterwards.
You could leverage this even further by also providing which events you'd like to disable on particular element (with default being a click event).
<!-- no events; use defaults -->
No-follow link
<button class="disable">Nothing happens</button>
<!-- provide events -->
No-follow link
<form class="disable" data-events="submit">...</form>
Script
$(function() {
var disable = function(evt) {
evt.preventDefault();
console.log("Prevented on " + evt.target.tagName);
};
$(".disable").each(function() {
var ctx = $(this);
ctx.bind(ctx.data("events") || "click", disable);
});
});
Using smart defaults
Upper example defines one single event default. click event. This is fine and works in majority of cases, but not in all. form elements for instance would always have to define submit event that should be disabled. So. Smart defaults then. We should also consider the fact that list events that need supression is usually short. And if we cover majority of cases using defaults we only have a small overhead on those elements that actually do deviate from defaults.
$(function() {
// click is still default event
// this object defines per element events that aren't just click
var extraDefaults = {
form: "submit"
};
var disable = function(evt) {
evt.preventDefault();
console.log("Prevented on " + evt.target.tagName);
};
$(".disable").each(function() {
var ctx = $(this);
ctx.bind(
// use inline-defined events
ctx.data("events") ||
// use extra defaults if present
extraDefaults[this.tagName.toLower()] ||
// just use default click event
"click",
disable);
});
});
You can bind most jQuery events like this :
$("#elementID").on(Object.keys(jQuery.event.fixHooks).join(" "), function(e) {
e.preventDefault();
});
This will preventDefault on the following events :
click dblclick mousedown mouseup mousemove mouseover mouseout
mouseenter mouseleave keydown keypress keyup contextmenu
FIDDLE
Well after considering all the options, it still does not look convenient for all this event hustling. As it also has to bind the handlers for each event individually the script will hit the performance as well.
I am going to stick with a much simpler solution, just putting a div with transparent bg on top to cover our element.
$('form').css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url(1px_transparent.png);"></div>'));
Which is going to automatically fill the whole area of the element, alternatively, we can use a half-transparent picture so it will be also understood by a user that this is locked element, and would not cause confusion.
And to unlock we simply remove the .mask div from our element.
EDIT
New Fiddle: http://jsfiddle.net/YAdXk/8/
Actually we can disable tabbing by setting tabindex attribute to -1
.find('input,textarea,select').attr('tabindex','-1');
The updated fiddle prevents from tabbing as well.
EDIT2
OR, we can extend jQuery to use our custom lock() and unlock() functions on any element.
See the last fiddle: http://jsfiddle.net/YAdXk/13/
(function($) {
$.fn.lock= function() {
return this.each(function() {
$(this).css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url('+transparent_picture+');"></div>')).find('input,textarea,select').attr('tabindex','-1');
});
};
$.fn.unlock= function() {
return this.each(function() {
$(this).find('*').removeAttr('tabindex').filter('.mask').remove();
});
};
})( jQuery )
var all_events = "click blur focus mouse"; //etc...
$('form *').bind(all_events, function(event) {
event.preventDefault();
});
Now is easier to maintain ;)
jQuery defines all shortcut event types here, so you can use that string to store all events for re-use:
var events = "blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu";
$('button').bind(events, function() {
// hey
});
Yes, it is possible, to catch all events of one type at once! But you'll need to specify all the event types explicitly.
Your code example of "form *" is inefficient, and would not catch events on elements that are added after your code executes.
Because of the bubbling effect of javascript events, you can assign a catch all event handler on the most parent element, eigther $("form") or $("body"), and add preventDefault() to that.
Example code:
$("a").on("click", function() {
$("body").append("<p>Clicked...</p>");
});
$("body").on("click", function(e) {
e.preventDefault();
});
with:
<div>
<p>Click on me</p>
</div>​
On JSfiddle: http://jsfiddle.net/erlang/EHeBK/
The concept of catching all events on a parent element, is often referred to as event delegation.

get element, caused change event in javascript

i want to get know within onchange event handler, which control caused change (or blur) event.
i tried to use jQuery $(":focus") for that aim, but
$('.some_class').change(function (e) {
console.log(e.target);
console.log($(':focus').get(0)); // always `undefined`.
/* ......... other code......... */
});
$('.some_class').change(function (e) {
console.log(e.target);
console.log($(':focus').); // just remove the .get(0)
});
remove the .get(0),you can get the element which is on focus
In jQuery, this refers to the element with the event handler and event.target, if event is the parameter to your event handler callback will be the source of the event, if, for example, you clicked on a child element and the click bubbled up.
The focus event gets fired after the blur event, so there will be a short period of time during which no element has focus. If you really need this, you could set a short timeout to see if another input has focus a couple milliseconds after the original one gets blurred.

jquery offclick?

I have a 'li' that pops down when I click on a 'link' via jquery's 'click'.
Does anyone know of a clean way to do something along the lines of 'offclick'? As in, when I click off of the element, it would hide the pop down?
Thanks!
Matt
You would want to assign a click listener to the window and also assign the click listener to your link. Inside the link click listener, you'll want to stop the event propagation so it doesn't travel up the DOM tree and fire your window's click listener.
Something like this should do the trick:
$(window).click(function(){
$('li#my_li').slideUp();
});
$('a#my_link').click(function(event){
try
{
event.stopPropagation();
}
catch(err)
{
// IE does it this way
window.event.cancelBubble=true;
}
$('li#my_li').slideDown();
});
I guess you could look at blur, which is called when the element looses focus:
ref: http://api.jquery.com/blur/
You can use blur or focusout depending on your needs

Categories