Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript mousup event triggers very late

I have a jquery sorting plugin which works pretty fine, but if I make few dragging operations the mouseup event starts to be very slow. It takes about 1 second while it triggers the event. If I dump end of mousemove event it stops immediately but mouseup event starts after the second. I added the console.log() for every method in the code but there is no call between drag stop and mouseup. What could be the problem? How can I debug possible parallel processes in the browser? The code looks like:

    ....
        state.doc
            .on( 'mousemove', dragging )
            .on( 'mouseup', endDrag );

    }

    /**
     * @desc Start dragging
     * @param e event obj.
     */
    function dragging( e )
    {
        ...

        console.log('dragging end');
    }


    function endDrag( e )
    {
        var cEl = state.cEl,
            hintNode = $( '#sortableListsHint', state.rootEl.el ),
            hintStyle = hint[0].style,
            targetEl = null, // hintNode/placeholderNode
            isHintTarget = false, // if cEl will be placed to the hintNode
            hintWrapperNode = $( '#sortableListsHintWrapper' );

        if ( hintStyle.display == 'block' && hintNode.length && state.isAllowed )
        {
            targetEl = hintNode;
            isHintTarget = true;
        }
        else
        {
            targetEl = state.placeholderNode;
            isHintTarget = false;
        }

        offset = targetEl.offset();

        cEl.el.animate( { left: offset.left - state.cEl.mL, top: offset.top - state.cEl.mT }, 250,
            function()  // complete callback
            {
                tidyCurrEl( cEl );

                targetEl.after( cEl.el[0] );
                targetEl[0].style.display = 'none';
                hintStyle.display = 'none';
                // This has to be document node, not hint as a part of documentFragment.
                hintNode.remove();

                hintWrapperNode
                    .removeAttr( 'id' )
                    .removeClass( setting.hintWrapperClass );

                if ( hintWrapperNode.length )
                {
                    hintWrapperNode.prev( 'div' ).append( opener.clone( true ) );
                }

                var placeholderNode = state.placeholderNode;
                // Directly removed placeholder looks bad. It jumps up if the hint is below.
                if ( isHintTarget )
                {
                    placeholderNode.slideUp( 150, function()
                    {
                        var placeholderParent = placeholderNode.parent();
                        var placeholderParentLi = ( ! placeholderParent.is( state.rootEl.el ) ) ? placeholderParent.closest( 'li' ) : null;

                        placeholderNode.remove();
                        tidyEmptyLists();

                        setting.onChange( cEl.el );
                        setting.complete( cEl.el ); // Have to be here cause is necessary to remove placeholder before complete call.
                        state.isDragged = false;

                        if( setting.maxLevels !== false )  // Has to be after placeholder remove.
                        {
                            recountLevels( cEl.el );
                            if( placeholderParentLi ) recountLevels( placeholderParentLi );
                        }
                    });
                }
                else
                {
                    state.placeholderNode.remove();
                    tidyEmptyLists();
                    setting.complete( cEl.el );
                    state.isDragged = false;
                }

            } );

        scrollStop( state );

        state.doc
            .unbind( "mousemove", dragging )
            .unbind( "mouseup", endDrag );

    }

    ....

Here https://camo.publicvm.com/ I made an example with dumps for all methods in the code. Look at the latency of endDragggggggggggggggggggggggggggggg log. Also I checked this issue in Opera browser and it has no problem with it.

EDIT: I think the problem was in local variables in the closure in animate call. var placeholderNode, var placeholderParent and var placeholderParentL. As I rewrite it to global state object problem is gone.

like image 640
Čamo Avatar asked Oct 16 '22 03:10

Čamo


1 Answers

A classic user click triggers mousedown and mouseup. The time between the two is usually somewhere ~50ms. In that short period of time, the browser might be busy due to processes fired by mousedown and event bubbling and propagation, specially if you bound too much handlers far up in the DOM tree like to document or "html, body". Avoid that.

Also, mouseup might end up being never registered. If some processes are taking too much time or you're simply too fast with your mouse, the mouseup might not be over the target element at the time it's triggered, therefore never firing that event.

like image 110
Raghul SK Avatar answered Oct 18 '22 14:10

Raghul SK