OK I've had it with this script! jQuery Drag issue!

  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

I'm about ready to ditch this all together and find a different route. First off the site I'm applying this to was not built with the intentional use of jQuery but the feature that i need to add jQuery would be perfect for. In fact it is already setup and working however I'm having a hell of a time with dragging. The site is a intranet so Access Denied. The project is an image archive system it's base on a file tree and the feature they want to add it to drag the images into other folders. Everything is loaded via AJAX and when the folder containing the image is loaded I simply set a class of draggable on the container div. once I get back the AJAX request do this.
JAVASCRIPT Code: [ Select ]
$(function() {
    $('.draggable').draggable({
        opacity: 0.5,
        revert: true,
        cursorAt: {
            top: 8,
            left: -8
        },
        helper: function( event ) {
            return $('<img src="http://archive.mysite.com/aia/new_site/images/fam/photo_add.png">');
        }
    });
});
 
  1. $(function() {
  2.     $('.draggable').draggable({
  3.         opacity: 0.5,
  4.         revert: true,
  5.         cursorAt: {
  6.             top: 8,
  7.             left: -8
  8.         },
  9.         helper: function( event ) {
  10.             return $('<img src="http://archive.mysite.com/aia/new_site/images/fam/photo_add.png">');
  11.         }
  12.     });
  13. });
  14.  


OK so as you can see there is nothing wrong with this, right. Now to get to the issue I'm have comes down to timing. When you click and hold on the item to drag In firefox it takes average (tested 14 times) 107.1428571428571 milliseconds to call the start function and 985.8571428571429 milliseconds to call the drag function (to start dragging). So from click to drag in firefox it takes about a second.

Now for the nightmare the place I work for MUST have things working in IE the other people in the company are not even allowed / able to install any other browser.

Same test It takes IE an average (again 14 tests) 135 milliseconds to call start ... Not bad about the same as Firefox and ... 3404.428571428571 milliseconds to call drag ... Almost 3 and a half seconds. Really? Anyone have any ideas at all?

Most my issues I resolve myself and like always I will post any solutions I find.


I know most my post are complex IE issues which suck but help would be great I've been messing with this issue for a day and a half so far. I have yet to find anyone having an issue like this. I only thought is that there are too many html elements on the page and for some reason jquery wants to look at them. Its just a thought because just building a draggable object in IE works fine with no delay.
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

What a drag. I think I may have found a solution to my own personal issue on this dragging thing however it is not using the draggable function at all.

I really hate working on my old projects and my old code it really shows me how much I've improved I really feel like this is a hack to fix an issue and, well, it is. I'm out of time today and this weekend and I will not be online except maybe by phone until Tuesday. I'll be in Mammoth working ... on my carving lol. If anyone has any ideas please I'd love to hear them.

Yuck I just looked at the code again ... So Hacky
  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

hmmmm. I just came across this which I'll tryout later to see if this works better. since it is a lighter weight drag widget.

http://css-tricks.com/snippets/jquery/d ... jquery-ui/
  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

So I tried the light weight drag widget I found and it works but in my case it is very jumpy So i continued with my hack and came out with this which in my case works really well but most likely will not help others.

JAVASCRIPT Code: [ Select ]
$(function() {
   
    // Setup some herlper vars. Moving image will state if we are dragging verse just clicking an image
    // and dragger_id will hold onto the image id we are dragging
    var moving_image = false;  
    var dragger_id;
   
    // Bind the dragstart to not drag anything. I know this sounds strange but we don't want to actually drag anything
    // with the class name of draggable
    $('.draggable').bind('dragstart', function(event) {
       
        // Stop the default action
        event.preventDefault();
   
    });
   
    // Setup the mousedown function on the draggable class name
    $(".draggable").mousedown(function(event) {
                                       
        // Get and set the images id in the dragger id variable
        dragger_id = $(event.target).get(0).id;
       
        // Stop the default action of the mouse down this will prevent the script from firing the
        // default action of just clicking on the image.
        event.preventDefault();
       
        // Setup the mouse move function this will mimic the dragging action
        $(document).mousemove(function(event){
           
            // Check to see if we are moving the image yet. if not and you have been following along.
            // to get here the mouse must be down and you must have moved the mouse.
            if(!moving_image) {
               
                // Make the helper image this is going to be the visual dragging refrence.
                var img
                img = $('<img src="images/fam/photo_add.png">');
                img.attr('id', 'whatADrag');
                img.appendTo('body');
               
            }
           
            // Set the moving image flag to true
            moving_image = true;
           
            // Build the cssobject to position the dragg helper next to the cursor
            var cssObj = {
                'display' : 'inline',
                'position': 'absolute',
                'left' : (event.pageX + 8 ) + 'px',
                'top' : event.pageY +'px'
            };
           
            // Apply the css to the helper
            $("#whatADrag").css(cssObj);
         
        });
   
    });
         
    // Set mouse up event we wat this to be able to fire every where
    $(document).mouseup(function(event) {
                                 
        // Get rid of the help object                
        $("#whatADrag").remove();
       
        // This is created in the mouseover function it is a visual refrence for the folder to drop the file into.
        // we need to remove the te,pdrop image and the class that was applied
        $("#temp_drop").remove();
        $(event.target).removeClass('move-file');
       
        // Make sure we are moving the image before we do anything
        if(moving_image) {
           
            // Set the moving image flag to false so that we no longer do anything with moving the image after exiting this function
            moving_image = false;
           
            // Unbind the mousemove instance
            $(document).unbind('mousemove');
           
            // Check for our drop zones. there are two of them at the current time
            if($(event.target).hasClass('droppable') || $(event.target).hasClass('droppable2')) {
               
                // Get the taget id and remove the string info
                var target_id = $(event.target).get(0).id.replace('node_a_tag_', '');
               
                // Call the function to move the file
                move_file(parseInt(dragger_id), parseInt(target_id));
               
               
               
            }
           
        }
 
    });
           
    // Setup the mouse over and out functions
    $(".droppable, .droppable2").mouseover(function(event){
       
        // Make sure we are moving the image
        if(moving_image) {
           
            // Add the move-file class
            $(this).addClass('move-file');
           
            // Check for the folder and not the tree
            if($(this).hasClass('droppable2')) {
               
                // Make the image add bullet to add a visual refrence to the folder
                var img = $('<img id="temp_drop" src="images/fam/add.png">');
               
                // Check browser type
                if(document.all){
                   
                    // Fix offset position
                    indicator_offset_x = $(this).width() - 16;
                    indicator_offset_y = $(this).height() -16;
                   
                } else if(navigator.userAgent.indexOf('Opera')>=0){
                   
                    // Fix offset position
                    indicator_offset_x = $(this).width() - 16;
                    indicator_offset_y = $(this).height() - 16;                
                   
                } else {
                       
                    // Fix offset position
                    indicator_offset_x = $(this).width() - 16;
                    indicator_offset_y = $(this).height() - 16;
                   
                }
               
            } else {
               
                // Make the image add bullet to add a visual refrence to the folder
                var img = $('<img id="temp_drop" src="images/fam/bullet_add.png">');
               
                // Check browser type
                if(document.all){
                   
                    // Fix offset position
                    indicator_offset_x = -13;
                    indicator_offset_y = 0;
                   
                } else if(navigator.userAgent.indexOf('Opera')>=0){
                   
                    // Fix offset position
                    indicator_offset_x = -13;
                    indicator_offset_y = -5;                
                   
                } else {
                   
                    // Fix offset position
                    indicator_offset_x = -13;
                    indicator_offset_y = 0;            
               
                }
               
            }
               
            // Append to the body of the dom and the display none to stop scrollbar issues
            img.attr('style', 'display:none;');
            img.appendTo('body');
           
            // Make an css Object to postion the image correctly
            var cssObj = {
                'position' : 'absolute',
                'display' : 'inline',
                'left' : ($(this).position().left + indicator_offset_x) +'px',
                'top' : ($(this).position().top + indicator_offset_y) +'px'
            };
           
            // Apply the CSS
            $("#temp_drop").css(cssObj);
           
        }
       
    }).mouseout(function(event){
               
            // Remove the class move-file and the temp drop image
            $(this).removeClass('move-file');
            $("#temp_drop").remove();
               
    });
               
 
});
 
  1. $(function() {
  2.    
  3.     // Setup some herlper vars. Moving image will state if we are dragging verse just clicking an image
  4.     // and dragger_id will hold onto the image id we are dragging
  5.     var moving_image = false;  
  6.     var dragger_id;
  7.    
  8.     // Bind the dragstart to not drag anything. I know this sounds strange but we don't want to actually drag anything
  9.     // with the class name of draggable
  10.     $('.draggable').bind('dragstart', function(event) {
  11.        
  12.         // Stop the default action
  13.         event.preventDefault();
  14.    
  15.     });
  16.    
  17.     // Setup the mousedown function on the draggable class name
  18.     $(".draggable").mousedown(function(event) {
  19.                                        
  20.         // Get and set the images id in the dragger id variable
  21.         dragger_id = $(event.target).get(0).id;
  22.        
  23.         // Stop the default action of the mouse down this will prevent the script from firing the
  24.         // default action of just clicking on the image.
  25.         event.preventDefault();
  26.        
  27.         // Setup the mouse move function this will mimic the dragging action
  28.         $(document).mousemove(function(event){
  29.            
  30.             // Check to see if we are moving the image yet. if not and you have been following along.
  31.             // to get here the mouse must be down and you must have moved the mouse.
  32.             if(!moving_image) {
  33.                
  34.                 // Make the helper image this is going to be the visual dragging refrence.
  35.                 var img
  36.                 img = $('<img src="images/fam/photo_add.png">');
  37.                 img.attr('id', 'whatADrag');
  38.                 img.appendTo('body');
  39.                
  40.             }
  41.            
  42.             // Set the moving image flag to true
  43.             moving_image = true;
  44.            
  45.             // Build the cssobject to position the dragg helper next to the cursor
  46.             var cssObj = {
  47.                 'display' : 'inline',
  48.                 'position': 'absolute',
  49.                 'left' : (event.pageX + 8 ) + 'px',
  50.                 'top' : event.pageY +'px'
  51.             };
  52.            
  53.             // Apply the css to the helper
  54.             $("#whatADrag").css(cssObj);
  55.          
  56.         });
  57.    
  58.     });
  59.          
  60.     // Set mouse up event we wat this to be able to fire every where
  61.     $(document).mouseup(function(event) {
  62.                                  
  63.         // Get rid of the help object                
  64.         $("#whatADrag").remove();
  65.        
  66.         // This is created in the mouseover function it is a visual refrence for the folder to drop the file into.
  67.         // we need to remove the te,pdrop image and the class that was applied
  68.         $("#temp_drop").remove();
  69.         $(event.target).removeClass('move-file');
  70.        
  71.         // Make sure we are moving the image before we do anything
  72.         if(moving_image) {
  73.            
  74.             // Set the moving image flag to false so that we no longer do anything with moving the image after exiting this function
  75.             moving_image = false;
  76.            
  77.             // Unbind the mousemove instance
  78.             $(document).unbind('mousemove');
  79.            
  80.             // Check for our drop zones. there are two of them at the current time
  81.             if($(event.target).hasClass('droppable') || $(event.target).hasClass('droppable2')) {
  82.                
  83.                 // Get the taget id and remove the string info
  84.                 var target_id = $(event.target).get(0).id.replace('node_a_tag_', '');
  85.                
  86.                 // Call the function to move the file
  87.                 move_file(parseInt(dragger_id), parseInt(target_id));
  88.                
  89.                
  90.                
  91.             }
  92.            
  93.         }
  94.  
  95.     });
  96.            
  97.     // Setup the mouse over and out functions
  98.     $(".droppable, .droppable2").mouseover(function(event){
  99.        
  100.         // Make sure we are moving the image
  101.         if(moving_image) {
  102.            
  103.             // Add the move-file class
  104.             $(this).addClass('move-file');
  105.            
  106.             // Check for the folder and not the tree
  107.             if($(this).hasClass('droppable2')) {
  108.                
  109.                 // Make the image add bullet to add a visual refrence to the folder
  110.                 var img = $('<img id="temp_drop" src="images/fam/add.png">');
  111.                
  112.                 // Check browser type
  113.                 if(document.all){
  114.                    
  115.                     // Fix offset position
  116.                     indicator_offset_x = $(this).width() - 16;
  117.                     indicator_offset_y = $(this).height() -16;
  118.                    
  119.                 } else if(navigator.userAgent.indexOf('Opera')>=0){
  120.                    
  121.                     // Fix offset position
  122.                     indicator_offset_x = $(this).width() - 16;
  123.                     indicator_offset_y = $(this).height() - 16;                
  124.                    
  125.                 } else {
  126.                        
  127.                     // Fix offset position
  128.                     indicator_offset_x = $(this).width() - 16;
  129.                     indicator_offset_y = $(this).height() - 16;
  130.                    
  131.                 }
  132.                
  133.             } else {
  134.                
  135.                 // Make the image add bullet to add a visual refrence to the folder
  136.                 var img = $('<img id="temp_drop" src="images/fam/bullet_add.png">');
  137.                
  138.                 // Check browser type
  139.                 if(document.all){
  140.                    
  141.                     // Fix offset position
  142.                     indicator_offset_x = -13;
  143.                     indicator_offset_y = 0;
  144.                    
  145.                 } else if(navigator.userAgent.indexOf('Opera')>=0){
  146.                    
  147.                     // Fix offset position
  148.                     indicator_offset_x = -13;
  149.                     indicator_offset_y = -5;                
  150.                    
  151.                 } else {
  152.                    
  153.                     // Fix offset position
  154.                     indicator_offset_x = -13;
  155.                     indicator_offset_y = 0;            
  156.                
  157.                 }
  158.                
  159.             }
  160.                
  161.             // Append to the body of the dom and the display none to stop scrollbar issues
  162.             img.attr('style', 'display:none;');
  163.             img.appendTo('body');
  164.            
  165.             // Make an css Object to postion the image correctly
  166.             var cssObj = {
  167.                 'position' : 'absolute',
  168.                 'display' : 'inline',
  169.                 'left' : ($(this).position().left + indicator_offset_x) +'px',
  170.                 'top' : ($(this).position().top + indicator_offset_y) +'px'
  171.             };
  172.            
  173.             // Apply the CSS
  174.             $("#temp_drop").css(cssObj);
  175.            
  176.         }
  177.        
  178.     }).mouseout(function(event){
  179.                
  180.             // Remove the class move-file and the temp drop image
  181.             $(this).removeClass('move-file');
  182.             $("#temp_drop").remove();
  183.                
  184.     });
  185.                
  186.  
  187. });
  188.  


The concept being that you drag nothing but when you mouse down on the image container and then move your mouse it signifies that you want to drag so you get some info in my case the images id and create and add an image to the DOM that follows your mouse until you let go of the mouse button, This give the look like you're dragging something when your not. when you let go of the mouse you check your drop points and get more info in my case the folder id of the new folder to move the file to.
  • Bigwebmaster
  • Site Admin
  • Site Admin
  • User avatar
  • Posts: 9086
  • Loc: Seattle, WA & Phoenix, AZ

Post 3+ Months Ago

It is really hard to help you diagnose this without seeing it in action, but I will throw a few ideas out to you to see if that might get you anywhere.

My first thought is that your DOM is really big. Instead of using a broad class selector such as '.draggable', have you thought about narrowing it down to something like #element, or just something more specific.

My second thought is that is it possible you have a draggable class within draggable class? That might cause issues too.

I would be curious how often this function is being called when you try and drag the object. Maybe throw an alert in there to see if it is being called once, or thousands of times which would make it seem choppy, jumpy, or delayed.
  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

I realize that its hard to diagnose with out seeing it is action I try to provide as much info as I can. Most the things I make are on an intranet so unless on the LAN are not accessible.

Your first thought is correct the DOM is really big and I also had that thought and assigned each draggable element it's own custom id and still got the same issue. I also went a step farther and made a static div hard coded in the HTML and still had the delay the choppy script happens to be that light weight drag widget. I didn't test that out to see how often the function is being called in the light script but in the the jQuery ui draggable it gets called once every time the mouse moves it doesn't have an issue moving but the delay becomes longer the more element there are that are set to be draggable either by a broad class selector or by individual ids.

HTML Code: [ Select ]
<!-- Page html javascript and css above -->
<style type="text/css">
.dragging-box-with-no-possibility-of-duplicating-style {
    width: 100px;
    height: 100px;
    border: 1px solid #000000;
    background-color:#CCCCCC;
    position:absolute;
}
</style>
 
<div id="div_with_an_id_with_no_possibility_of_duplicating" class="dragging-box-with-no-possibility-of-duplicating-style">
Drag Me
</div>
 
<script type="text/javascript">
 
$(function() {
   
   $("#div_with_an_id_with_no_possibility_of_duplicating").draggable();
 
});
 
</script>
 
 
  1. <!-- Page html javascript and css above -->
  2. <style type="text/css">
  3. .dragging-box-with-no-possibility-of-duplicating-style {
  4.     width: 100px;
  5.     height: 100px;
  6.     border: 1px solid #000000;
  7.     background-color:#CCCCCC;
  8.     position:absolute;
  9. }
  10. </style>
  11.  
  12. <div id="div_with_an_id_with_no_possibility_of_duplicating" class="dragging-box-with-no-possibility-of-duplicating-style">
  13. Drag Me
  14. </div>
  15.  
  16. <script type="text/javascript">
  17.  
  18. $(function() {
  19.    
  20.    $("#div_with_an_id_with_no_possibility_of_duplicating").draggable();
  21.  
  22. });
  23.  
  24. </script>
  25.  
  26.  
  • Bigwebmaster
  • Site Admin
  • Site Admin
  • User avatar
  • Posts: 9086
  • Loc: Seattle, WA & Phoenix, AZ

Post 3+ Months Ago

I have a few more ideas for you.

Try removing position:relative from the parent containers or the drag me div if it exists. See if changing the position values effect performance.

Also I am curious if you are using any universal selectors for padding or margins such as:

CSS Code: [ Select ]
* { padding:0 }


Back to how many times the function is being called, it sounds correct that it would fire each time the mouse is moved. I would like to rule out that it is being called multiple times each time the mouse is moved.

Have you tried this entire scenario on a basic page with basic CSS (not your entire site's CSS and JS). I would also like to confirm that you can at least get it working correctly with that.
  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 449

Post 3+ Months Ago

I have done a basic page and it works fine with no delay or at least not one that is noticeable. I didn't notice any performance issue by removing the position:relative and also I don't use universal selectors. I do see performance differences the more I put into the functions.

Example
JAVASCRIPT Code: [ Select ]
// This preform the best with very little delay
$(function() {
    $(".draggable").draggable();
});
 
// This adds more delay
$(function() {
           
    // Setup the mousedown function on the draggable class name
    $(".draggable").draggable({
        revert:true,
        helper: function( event ) {
            return $('<img src="images/fam/photo_add.png">');
        }
    });
           
    $(".droppable").droppable({
        greedy: true,
        drop: function( event, ui ) {
            alert('dropped');
        }
    });      
 
    $(".droppable2").droppable({
        greedy: true,
        drop: function( event, ui ) {
            alert('dropped2');
        }
    });
           
});
 
  1. // This preform the best with very little delay
  2. $(function() {
  3.     $(".draggable").draggable();
  4. });
  5.  
  6. // This adds more delay
  7. $(function() {
  8.            
  9.     // Setup the mousedown function on the draggable class name
  10.     $(".draggable").draggable({
  11.         revert:true,
  12.         helper: function( event ) {
  13.             return $('<img src="images/fam/photo_add.png">');
  14.         }
  15.     });
  16.            
  17.     $(".droppable").droppable({
  18.         greedy: true,
  19.         drop: function( event, ui ) {
  20.             alert('dropped');
  21.         }
  22.     });      
  23.  
  24.     $(".droppable2").droppable({
  25.         greedy: true,
  26.         drop: function( event, ui ) {
  27.             alert('dropped2');
  28.         }
  29.     });
  30.            
  31. });
  32.  


The more I put into the draggable or droppable functions cause more delay I consoled out the jQuery UI functions for this and watched every call that happened and there are several functions that extend each other that get called for example the function drag() gets called about 8 times and if you add the drag in the the call it gets called again. That's one reason I looked for a light weight drag function.

JAVASCRIPT Code: [ Select ]
$(function() {
    $(".draggable").draggable({
        drag: function() { alert('dragging'); }
    });
});
 
  1. $(function() {
  2.     $(".draggable").draggable({
  3.         drag: function() { alert('dragging'); }
  4.     });
  5. });
  6.  

Post Information

  • Total Posts in this topic: 8 posts
  • Users browsing this forum: No registered users and 118 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
cron
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.