Capture the 'MouseUp' event outside the browser window


I have following problem with MouseUp event specially under IE and FF (under Chrome there is no problem). This event is not captured outside the browser window in the case of single click, mouse down immediately after that, hold in this state, followed by quick
mouse move outside the browser window and mouse up there. When I make mouse down (hold in this state), mouse move (fast) and mouse up (last outside the browser window) there is no problem. The case is same, when I make double click followed by mouse down,
hold, followed by mouse move outside the window and releasing the button there (mouse up)  – there is no problem too. Can anyone help me to solve that issue? I use these events to drag elements, and they remain ‘hanging’ in the case of to say a ‘unfinished
double click’ in the window, but finished outside window.


I reviewed those examples already, but they are not related with my problem. I do not use the native drag and drop of HTML5, but I made a custom drag logic. On mousedown I ‘select’ one element and I raise a flag called ‘canMove’ for instance. When mouse
is moved at mousemove event, I dynamically change top and left of the ‘moved’ element. If I release the button in some point (mouse up), I clear that flag and the element remains in that position. But if I have clicked and then mouse down (to say that some
user have nervous fingers :-)), and move element accidentally out of window (i.e. the mouse pointer, because the moved element will remain inside the window next to the border) for example on the Windows’ task bar (the window remains in focus yet) and release
mouse button there (mouse up) and return in window, the ‘canMode’ flag will remain raised and the element will follow the mouse pointer until next mouse down, but in my case that will be problem. I suppose that after single click and mouse down, the browser
expects mouse up in order to trigger the double click event, but I do not care of that, because I want to be able to capture mouse up event and to clear the ‘canMove’ flag. I spent almost a week about this problem, and I did not find some solution until now,
unless if I trigger programmatically mouseup for instance on window.mouseout, but this is unprofessional behavior and will disappoint the users. Furthermore, It is not true that the ‘onmouseup’ can not be captured as is explained in the one of the those posts,
because it’s captured in the cases explained above, also it’s captured under Chrome, the problem exists only for IE and FF. I have tested under IE11 and FF 32.0.2. I also noticed that when it is captured outside, the eventPhase is 2.

Hi Zhoro76,

Thanks for your post here.

If you don’t mind ,please post code which can reproduce your problem for us.

Best Regards,

Kevin Shen.

        body {
             font-family: Arial;
             font-size: 13px;
             height: 100%;
             width: 100%;
             margin: 0;
             padding: 0;
        div.outer {
            margin: 0 auto;
            background: none;
            background-repeat: repeat;
            background-position: 0 0;
            background-attachment: scroll;
            background-color: transparent;
            position: relative;
            margin-top: 300px;
            min-height: 400px;
            width: 600px;
            border: solid 1px #000;

        ul.inner {
            float: left;
            padding: 0;
            overflow: visible;  

        ul.inner li {
            float: left;
            list-style: none outside none;
            margin: 0;
            padding: 0;
            border: solid 1px red;
            background-color: #d1cdcd;
            display: inline-block;
            cursor: move;
            position: relative;
            margin: 1px;
            clear: left;
            top: 0px;
            left: 0px;
            width: 200px;
            height: 80px;
            text-align: center;
    <script type="text/javascript" src=""></script>
    <script type="text/javascript">
        var lastPosX = 0;
        var lastPosY = 0;
        var canMove = false;
        var elemToMove = null;
        var d = new Date;

        $(document).ready(function () {

        function load() {
            document.onmousedown = function (e) { handleMouseDown(e); };
            document.onmouseup = function (e) { handleMouseUp(e); };
            document.onmousemove = function (e) { handleMouseMove(e); };
            document.onclick = function (e) { console.log(d.getTime() + ‘ mouse click’); };
            document.ondblclick = function (e) { console.log(d.getTime() + ‘ mouse double click’); };

        function handleMouseDown (e) {
            elemToMove = elemToMove || $([0];
            var whichButton = $(e.which)[0];
            if (whichButton == 1) {
                lastPosX = getMousePosX(e);
                lastPosY = getMousePosY(e);
                canMove = true;
            else {
                return false;
            console.log(d.getTime() + ‘ mouse down’);

        function handleMouseMove(e) {
            if (canMove) {
                var left = getMousePosX(e);
                var top = getMousePosY(e);
                var newLeft = ($(elemToMove).css(‘left’).toDecNum() + (left – lastPosX));
                var newTop = ($(elemToMove).css(‘top’).toDecNum() + (top – lastPosY));

                $(elemToMove).css(‘left’, newLeft);
                $(elemToMove).css(‘top’, newTop);
                lastPosX = left;
                lastPosY = top;

            return false;

        function returnInContainer() {
            $(elemToMove).animate({ left: "0px", top: "0px" });

        function handleMouseUp (e) {
            var whichButton = $(e.which)[0];
            if (whichButton == 1) {
                canMove = false;
            console.log(d.getTime() + ‘ mouse up’);

        function getMousePosX (e) {
            var posX = null;
            if (e.pageX) {
                posX = e.pageX;
            else if (e.clientX) {
                posX = e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
            return posX;

        function getMousePosY (e) {
            var posY = null;
            if (e.pageY) {
                posY = e.pageY;
            else if (e.clientY) {
                posY = e.clientY + document.documentElement.scrollTop + document.body.scrollTop;
            return posY;

        String.prototype.toDecNum = function () { return parseInt(this, 10) };
<body class="body">
    <div id="div1" class="outer">
        <ul id="ul1" class="inner">
            <li id="li1"></li>


Try this code with following scenario:

First try: Try mouse down on the gray div and move mouse on the Windows’ task bar and release the mouse button there.

Second try:  Make one click followed by immediate mouse down and repeat the process to the task bar.

Third try: Make double click followed by immediate mouse down by mouse down and repeat again the process to the task bar.

Problem appears in second try, when the flag ‘canMove’ remain ‘raised’ and the element follows the mouse until next mouse down. Is there any solution on this problem?



As far as I know,you can not capture  the event outside browser window.


Thanks for that reply, but I have already solved the problem.

Leave a Reply