MouseRelease not triggering: think I found a BUG

Think I've come across a bug where mouseReleased() does not get triggered. In the simplified example I've got up at the link below, you can see in the console that mouseReleased() does not trigger on actual mouseRelease. You have to click 2x for the release to trigger.

Only happens when attaching an HTML element to the mouseX and mouseY. Otherwise, works as expected.

Am I right? Is this a bug with mouseReleased? http://dfilm.com/lucs/releasetest/testdrag.html

Note: test it in FireFox and refresh once to get it to work (I haven't worked out image preloading yet, so the images need to cache before the example will work). Unrelated, but also seems that element.width doesn't work in Chrome. Instead I have to do: myelement.elt.naturalHeight.

Answers

  • I see the expected behaviour in Chrome:

    1. mousePressed
    2. mouseReleased
    3. mouseClicked (i.e. both a press and release have occurred; hence why triggered after released)

    I do see 'unusual' behaviour if I use a right-click; I assume because the context menu interrupts the event bubbling. Could be that in your actual code you do the equivalent by inserting an element under the mouse.

    So probably not a bug as such: either browser inconsistencies or you trying to perform an action that's not expected by the browser...

  • Hi. Thanks for taking a look. You see the expected behavior as long as you don't click and drag an item first. Try clicking and dragging one of the PNGs... when you do that, the mouseRelease event is not triggered. It's like attaching the PNG to MouseX,MouseY prevents the mouseRelease event.

    Btw, I don't think you can test in Chrome b/c none of the PNGs load in Chrome.

  • edited December 2015

    I don't think you can test in Chrome b/c none of the PNGs load in Chrome.

    @brig: They do; but width and height are set to 0 so with overflow: hidden that means they don't appear :/

    I had to do some digging but have managed to figure out your code: I'm not familiar with the DOM library as I'm comfortable using the vanillaJS library :D

    I think you're confusing DOM_element.mousePressed/Released() events with the global mousePressed() and mouseReleased() events. The mouseReleased event attached to your DOM elements is not the same as the global mouseReleased event.

    It is possible that there is a bug in the DOM library that prevents mouse events bubbling up to the global event (meaning console.log isn't firing when you expect); but that's not what is causing elements to get stuck on the mouse. From the DOM.mouseReleased() docs (my emphasis below):

    The .mouseReleased() function is called once after every time a mouse button is released over the element.

    The problem with elements getting hooked only appears to happen when you're dragging (and probably more often in one direction than the other); because at that point the mouse isn't necessarily over the element at the time of release; meaning the event won't fire until a subsequent press and release...

    Personally I wouldn't rely on attaching events to DOM objects like that; it's clunky, inefficient and clearly prone to error. Instead use the global events. On mousepress check which element is beneath the mouse and set it to be dragged. On mouserelease drop the currently dragged element. The global release is just checking that the mouse has been released and doesn't care which object it's over at the time... That will also avoid odd interactions when you drag an element over another with a higher z index.

  • edited December 2015

    Hi Blindfish. Agree that checking the element under the click is probably going to be the way to do it (although not as convenient).

    I don't think your hypothesis is correct though. I've written up a simpler example that shows the "bug" more clearly at: http://dfilm.com/lucs/releasetest/testdrag2.html (works this time in all browsers).

    You'll see in this example that no matter what you do, MouseRelease is not triggered either globally or from the element. It doesn't matter how fast or slow you drag the object or even if you release the object over the same spot where you started dragging it. MouseRelease simply doesn't trigger after you start drag! It does trigger if you click without dragging. But when you start the drag, it doesn't recognize the MouseRelease at all.

    Thanks GoToLoop for the tip to ondragend. Will play with that.

  • Your second example still doesn't work for me in Chrome which has made it hard to verify your claim... However, from a simple working example it looks like there is indeed a bug in the DOM library's mouse event handlers:

    function setup() {
    
        var dragger = createDiv('click me');
        dragger.style("display: block; width: 200px; height: 50px; color: #f90; background: #000; position: absolute;");
    
        dragger.mousePressed(function() { console.log('pressed')});
        dragger.mouseReleased(function() { console.log('released')});
    }
    
    function draw() {
    
    }
    
    function mousePressed() {
        console.info("global press");
    }
    
    function mouseReleased() {
        console.info("global release");
    }
    

    I don't have time to look at the source to identify the cause; but as you say when you drag, this appears to block event propagation to both the DOM and global release handlers. I suspect something like return false has been used in one of the handlers :/

  • @brig: as an aside my above example does confirm my previous assertion: Press mouse over DOM element (whilst not moving*), move off the DOM element, release and you'll see the DOM-element.mouserelease event doesn't fire. That makes sense as generally UIs wait till mouseUp before responding to a 'button press'.

    * From what I can see the blocked mouseRelease bug appears to happen only if you're 'dragging' at the time you mousepress... Odd.

  • dragger.elt.ondragend = function() { console.info('drag finished'); };

  • @blindfish: where is the right place to submit a bug? somewhere on the github repo?

    i do see in your example that element.mouserelease event doesn't fire. good simplified example. i should note that in my example: neither element nor global mousereleases fire.

    ps. strange that my example still doesn't work in chrome. tried it on a few computers and seems to work for me.

  • edited December 2015

    @brig: Looks like the issue on Chrome is resolved now that you preload your image. Think I might have been looking at a cached copy before :\">

    I also finally figured out the cause of the 'bug': if you highlight the text in my test, then click and drag, the browser 'drags' the highlighted text - as if you were going to drop it somewhere else. I noticed the same happening with your images. Presumably this is a built-in browser feature - I haven't implemented any drag functionality in my test - though I'm not sure what it's for. It's only when the selection is being dragged in this way that the mouse events are interrupted. Very odd...

    Happily there's a simple CSS solution. This resolves the issue for me with my text example... Edit: the CSS is non standard so not usable in production environments :(

    I'd still go ahead and raise an issue on Github, as it may be possible to catch and avoid this in the p5js mouse event handlers...

  • Ah, I was all excited for your solution, but see your edits above. Yea, I tried it on my image dragger and it didn't impact chrome or FF. Good idea though.

Sign In or Register to comment.