dragend, dragenter, and dragleave firing off immediately when I drag

11,629

Solution 1

Had this problem just now - it is a Chrome bug, you must not manipulate the DOM in dragStart event, or else dragEnd fires immediately. The solution for me turned out to be - use setTimeout() and manipulate the DOM inside the function you timeout.

Solution 2

It seems to be a Chrome bug : https://groups.google.com/a/chromium.org/forum/?fromgroups=#!msg/chromium-bugs/YHs3orFC8Dc/ryT25b7J-NwJ

Solution 3

Not sure whether it is a bug or not, but I think the problem comes in when you change the DOM in the dragstart handler. The reason the first box works I presume has something to do with the fact that its position is before the other boxes in the DOM and when you change the DOM, the position (?) of the first one isn't affected and the dragdrop events fire reliably.

You will need to refactor your code somewhat, and add the dropSpaces in the dragenter event handler. You would need to change your addDropSpaces method to accommodate the fact that it will be called multiple times, though.

Share:
11,629

Related videos on Youtube

Bill
Author by

Bill

Updated on June 03, 2022

Comments

  • Bill
    Bill almost 2 years

    I'm trying to make a list of elements which can be repositioned by dragging and dropping. The first element, Box 1, works just fine 100% of the time. Sometimes the second box works, but none of the others work as expected. They seem to fire off all the drag events at once as soon as you start dragging them.

    I'm using the latest Chrome (v23) if that matters.

    var $questionItems = $('.question-item');
    
    $questionItems
      .on('dragstart', startDrag)
      .on('dragend', removeDropSpaces)
      .on('dragenter', toggleDropStyles)
      .on('dragleave', toggleDropStyles);
    
    
    function startDrag(){
      console.log('dragging...');
      addDropSpaces();
    }
    
    function toggleDropStyles(){
      $(this).toggleClass('drag-over');
      console.log(this);
    }
    
    
    function addDropSpaces(){
      $questionItems.after('<div class="empty-drop-target"></div>');
      console.log('drop spaces added');
    }
    
    function removeDropSpaces(){
      $('.empty-drop-target').remove();
      console.log('drop spaces removed');
    }
    

    Here's the HTML:

    <div class="question-item" draggable="true">Box 1: Milk was a bad choice.</div>
    <div class="question-item" draggable="true">Box 2: I'm Ron Burgundy?</div>
    <div class="question-item" draggable="true">Box 3: You ate the entire wheel of cheese?</div>
    <div class="question-item" draggable="true">Box 4: Scotch scotch scotch</div>
    

    Here is a jsFiddle of my code: http://jsfiddle.net/zGSpP/5/

    • jbabey
      jbabey over 11 years
      Are you using jquery draggables? where are you initializing the elements as draggable via element.draggable();?
    • sdespont
      sdespont over 11 years
      It is really wird. You should use JQueryUI widget events as workaround : jqueryui.com/draggable
    • Bill
      Bill over 11 years
      jbabey: The HTML5 attribute 'draggable=true'
  • sdespont
    sdespont over 11 years
    The target is to add spaces after each boxes
  • Bill
    Bill over 11 years
    It seems to prevent the rest of the function from executing? jsfiddle.net/zGSpP/11
  • Bill
    Bill over 11 years
    It seems related to the bug, but I do indeed want the div injected after every .question-item, not just the current one.
  • Bill
    Bill over 11 years
    I really need to be able to do more than sort the list, such as when an item is dragged on top of another item they become grouped.
  • SoluableNonagon
    SoluableNonagon over 11 years
    you still can, you just do it through jQuery for events. $( ".selector" ).on( "drag", function( event, ui ) {} ); and $( ".selector" ).on( "dragstart", function( event, ui ) {} ); And it has callbacks so you can still use the functions you already built.
  • SoluableNonagon
    SoluableNonagon over 11 years
    Also, have you tried to add each .on() to each single box item manually? Just to see the effect?
  • SoluableNonagon
    SoluableNonagon over 11 years
    Something like $questionItems[0].on('dragstart', startDrag); $questionItems[0].on('dragend', removeDropSpaces) $questionItems[0].on('dragenter', toggleDropStyles) $questionItems[0].on('dragleave', toggleDropStyles); $questionItems[1].on('dragstart', startDrag); $questionItems[1].on('dragend', removeDropSpaces) $questionItems[1].on('dragenter', toggleDropStyles) $questionItems[1].on('dragleave', toggleDropStyles); etc. just to see the effect?
  • Bill
    Bill over 11 years
    Yeah I'm going to give jQ UI's sortable a go. At this point I just want it to work. Good to know I can tap into the events too. Thanks.
  • Akkuma
    Akkuma over 10 years
    This bug still appears in Chrome 32.
  • Puppy
    Puppy over 8 years
    Still seem to be experiencing this problem in Chrome 47.
  • Able Johnson
    Able Johnson over 7 years
    Still there in Chrome 55.0.2883.87
  • Anton Bielousov
    Anton Bielousov about 7 years
    This worked for me. Also I had the same code working for me on one page variant but not the other and the only difference between them was that parent element for the manipulated element wasn't rendering (was hidden) in the case when it was failing.
  • cliff.meyers
    cliff.meyers over 6 years
    And still in Chrome 62 :/
  • Brian M. Hunt
    Brian M. Hunt about 6 years
    The linked bug is labelled WontFix for being unreproducible since 2015. Might be a good idea to submit a new bug with a reproduction in a CodePen or jsFiddle.
  • Andriy Petrusha
    Andriy Petrusha almost 4 years
    and still in Version 83.0.4103.116 (Official Build) (64-bit)
  • LuisAFK
    LuisAFK almost 2 years
    Still in Chrome version 101
  • JaeIL Ryu
    JaeIL Ryu almost 2 years
    generally just works well, but sometime must works like this answer..(this worked for me). i don't know what is wrong...