开发者

How do I detect a blur that is triggered on mouse up?

I am listening for a blur event on a form input. Right now, the event immediately gets triggered when the mouse is pressed down outside of the control. I need to be able开发者_高级运维 to detect when the mouse is completely clicked outside of the input (mouse down and then mouse up).

Is there already an event type that I can listen to that will handle this? If not, what is the best way to handle this type of event?


I'd say no, there aren't any event of that type. And I don't think there is a perfect way to handle that

I'll try to handle it this way

  • adding a global var, defaulting it to -1 and setting it to 1 when the form get the focus.
  • adding a mousedown handler to the document when the form get the focus. It will set a global variable to 1.

    • When triggered, it'll test if it's still in the form (using event.target). If it's the case, let 1, else set it to 0.
  • The mousedown handler will have event.preventDefault; and return false;. This may cause some trouble to your others eventHandlers. To avoid such trouble, I'll try to capture the events that could be damaged on the capturing phase, not the bubbling one.

  • adding a mouseup handler to the document when the form get the focus. In it, test if the variable has a value of 0. if yes, then do the blur job and remove the two special handlers.

But this might have some weakness (especially if the user leaves the window while the mouse is pressed).

I hope this is clear, I'll try to post a fiddle asap.

EDIT: Here is the fiddle. However note that I force the focus on the form and it works only one.I did so because it looks like the form never get focused otherwise (probably linked to the way jsfiddle handle events). But in theory that should work without the $("form").focus(); line.

As a side note, i used jQuery for some shortands I'll try to remove the calls if needed.


hmmm i think i got something after thinking about this for a few. I'm still a little shakey with my syntax, but I think this may do what your looking for. The idea is that you capture the control id in the .blur, and then in your mouseup you check that controls id against your .blur control id and if they are not equal you have lost focus and can do what you want in the mouseup, also dont forget to clear out your blur control id after you fire your mouseup event or it will fire for multiple mouse ups.

var blurControlID;

$("selector").blur(function () {
    blurControlID = this.id;
});

$("selector").onMouseUp(function() { 
    if (blurControlID != "")
    {    
        if (this.id != blurControlID)
        {//do what you want
            blurControlID = "";
        }
    }
});


You can call a function in the onmouseup attribute of the body tag.

<body onmouseup="doWhatINeed();">

In that function you will have to reference the object in question of course, but without example of your code I cannot offer further help.

Edit: Without knowing the purpose I can give a rough example of a particular type of purpose...

Javascript:

var hasBeenDone = false;

function doWhatINeed() {
  if(!hasBeenDone) {
    //do what is required
    hasBeenDone = true;
}

function anotherFunction() {
  //some other stuff which requires the mouseup event to fire again for the element in question...
  hasBeenDone = false;
}

This is the approach I have used countless times for similar circumstances and has never been problematic in any way.


I ran into a similar problem, and handled it this way (I used jQuery for events, but you can of course use addEventListener instead):

// Catch the blur event.
$('#myinput').blur(function () {
    // Record the input the blur event happened on.
    var input = this;
    // Catch the mouseup event once, on either the window or the input.
    $(window).add(input).one('mouseup', function (e) {
        // If the mouseup event happened on the input, prevent
        // propagation up to the window, and don't do anything else.
        if (input === this) {
            e.stopPropagation();
            return;
        }
        // Otherwise, wait for any other click handlers to run.
        // In my code, this is used to detect if a user clicked
        // a "cancel" button, rather than just leaving the input.
        setTimeout(function () {
            // Do what you need to do.
            // In my code, this calls a REST API to save the input,
            // or has no effect if the user previously clicked cancel.
        }, 0);
    });
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜