Prevent firing focus event when clicking on div
Asked Answered
T

5

80

This question is similar to my previous question, Click action on Focused DIV, but this time the main topic is, How to prevent focus event from triggering when I click one of the divs. Last time I had one div with tabindex='-1' to make it focusable on click, now I have a list of divs with tabindex>0 so they can gain focus when tabbing as well.

<div tabindex='1'>Div one</div>
<div tabindex='1'>Div two</div>
<div tabindex='1'>Div tree</div>
<div tabindex='1'>Div four</div>

some styling:

div {
    height: 20px;
    width: 60%;
    border: solid 1px blue;
    text-align: center;
}
div:focus {
    border: solid 2px red;
    outline: none;
}

Now I'm using a flag(action) to fire an action(alert) when clicking the div for 2nd time, and with just one click if it's already focused,with TAB for example.

var action = false;
$('div')
    .click(function(e){
        e.stopImmediatePropagation();
        if(action){alert('action');}
        action = true;})
    .focus(function(){action = true;})
    .blur(function(){action = false;});

The problem with the code above is focus event is being fired, which means stopImmediatePropagation doesn't work the way I expected.. The two click action works commenting the focus event line, but you still need to double click when div gains focus on TAB. Here is the example: http://jsfiddle.net/3MTQK/1/

Tympan answered 4/1, 2012 at 23:45 Comment(0)
E
131

DEMO here

I think you are missing some parts here,

  1. event.stopPropagation() is used to stop the event from bubbling. You can read about it here.

  2. event.stopImmediatePropagation() In addition to keeping any additional handlers on an element from being executed, this method also stops the bubbling by implicitly calling event.stopPropagation(). You can read about it here

  3. If you want to stop browser events, then you should use event.preventDefault(). You can read about it here

  4. click = mousedown + mouseup -> The focus will be set on a HTML element when the mouse down is successful. So instead of binding click event, you should use 'mousedown'. See my demo.

  5. You cannot use 1 action boolean value to determine which div is clicked and how many times it has been clicked. Check my Demo to see how you can handle that.

Endemic answered 5/1, 2012 at 0:47 Comment(2)
If I bind two events to one element, how does that work? For instance, if I write: $(document).on("touchstart click", ".myelement", function (e) {e.stopImmediatePropagation(); //run function here}) ....If I am on a tablet device, will the touchstart fire first and all other events stopped? Because right now if I click an element and keep my finger held down, both the touchstart and the click fire and my function is run twice. Will stopImmediatePropagation fix that?Schappe
What does it mean that the 'mousedown' be successful?Biphenyl
P
53

To simply prevent firing focus when clicking on div just use mousedown + event.preventDefault(). Use mousedown rather than click because, as @Selvakumar Arumugam explained, focus fires when mousedown is succesfull and event.preventDefault() will stop browser events (including our focus).

Here's a code example:

$('#div').on('mousedown', function(event) {
// do your magic
event.preventDefault();
});
Pierette answered 16/7, 2017 at 17:28 Comment(3)
There are so many drawbacks to mousedown. Its not a simple switch. Please be careful before just putting this everywhere you put click.Predicate
@JamieMarshall drawbacks such as...?Kaliope
@Kaliope - mousedown doesn't trigger touch events as you probably expect. Many native components such as dropdown boxes have default behaviors based on mousedown and mouseup. There are many, many, scenerios where mousedown is not synonymous with click. They used to be more so in the past, but in todays world it is not a simple switch.Predicate
F
18

Simply,

// ❌ Don't (focus already set on mouse down)
onClick={e => e.preventDefault()}
// ✔️ Do (prevent focus)
onMouseDown={e => e.preventDefault()} 
Felske answered 23/2, 2022 at 22:12 Comment(1)
Unfortunately this also disables other default behavior like selecting text :(Palawan
C
1

For the moment the apparent answer would be to restrict your selector from simply 'div' to a system of toggled class names, thereby you could control on what element your focus event would fire. It is more tedious and requires a bit more exception coding, but would do the job.

Coralloid answered 5/1, 2012 at 0:32 Comment(1)
I guess this would work but the accepted answer is sooo much better (event.preventDefault() in mousedown handler).Merriemerrielle
A
-2
var action = false;
$('div')
    .click(function(e){
        e.stopImmediatePropagation();
        if(action){alert('action');}
        action = true;})
    .focus(function(){action = true;})
    .blur(function(){action = false;});
Anatollo answered 5/11, 2022 at 7:27 Comment(1)
Your answer could be improved by adding more information on what the code does and how it helps the OP.Soteriology

© 2022 - 2024 — McMap. All rights reserved.