views:

86

answers:

1

I'm using this tiny drag plugin to drag div.slider horizontally across it's div.container. I do not want div.slider to be able to go past the bounds(don't want it to exit) div.container. so when div.slider reaches the very right side of it's container div.container, i want it to not allow the user to drag it any further right, so that it stays inside of it's container.

here's my jquery:

 $(".slider").mouseup(function() {
  var leftStyleValue = $('div.slider').css('left');
  $('.display_value').html(leftStyleValue);

     if (parseInt($('.slider').css('left')) > 100) {
   $('#completion').text("YOU DID IT!");
  }
  else {
   $(".slider").animate({left: 0
   }, 500);
  }

 });

If i change "mouseup" to mousemove, then it wont allow you to even drag it since it's checking on every pixel move. right now, i can drag div.slider outside of div.container and when i let go of the mousebutton, since i'm not doing a mouseup on div.container, it does nothing.

If you want to see the plugin code, go to the site above, copy the compressed plugin code, then go to http://jsbeautifier.org/ and see the uncompressed version.

Thank you SO much!!! This is the LAST piece to my puzzle!

+2  A: 

jQuery UI's draggable supports this via containment property, you might want to check that out to save you from modifying the plugins's source code.

Note that you can do a custom download package of jQuery UI if you don't need anything else than the draggable.

EDIT

After some thinking, I guess you can make it with your method with some modifications. You have to:

  1. Bind a function to the .slider element's mousedown event to capture the start of dragging
  2. Calculate maximum left position (and others if necessary)
  3. Bind to mousemove event, detect the position where the element is now, check if it's over the limit, if it is, adjust it's css to maximum left position

The problem lies within step 3. As the plugin has bound to the mousemove event also and changes the element's css constantly, you might run into some flickering or weird behaviour as the two mousemove functions are trying to edit the CSS with different values. This is the reason why I suggested you to edit the plugin itself.

Anyways, here's a modified version of your code that should work somewhat acceptably:

$(".slider").mousedown(function() {    
    var $slider = $(this);

    // Get maximum x-position. 
    // The max_x position is equal to the sliders width from the container's right side.
    var max_x = $slider.parent().offset().left + $slider.parent().width() - $slider.width();

    // Track mouse position
    $().mousemove(function(e) {
        if(e.pageX > max_x) {
            $slider.css({
                left: max_x
            });
        }
    });

    // Unbind events to $() to prevent multiple bindings
    $().one('mouseup', function() {
        $().unbind();
    });
});

Note that without examining the plugin's source code, I cannot guarantee that this works. That's why it would be wise to implement this behaviour inside the plugin.

Usually it would be wise to return false; after mousemove and mousedown events to prevent browser behaviour, but I'm not sure whether it'll confilct with the plugin itself.

And this function only takes account the right boundary, it will allow the element to pass through from other sides of the container. But I guess you'll be able to implement those if needed.

Tatu Ulmanen
Jquery UI is Hugely bloated and WAY too big for what I want, once I figure this last piece out, the weight will be less than 1.5k, whereas Jquery UI will be around 20-30k.
ExodusNicholas
And i don't think i'll need to edit the plugin source code, i'm pretty sure it's possible to do by adding to my own jquery code above, i'm just not sure exactly how or the best way to go about it.
ExodusNicholas
On the subject of your solution being 1.5k to jQuery UI's 20-30k, the significant metric is the difference between the gzipped sizes not the difference between the raw source sizes. Consider also the probability of a bug in your code vs that of jQuery UI, and the probability of jQuery UI already being in the client browser's cache. jQuery UI may be the more wise choice.
Jon Cram
Ah so close! Sorry i'm still new to Jquery but from what I understand, in your code you have it track the mouse position from the very left of the page. When i position .container 200px from the left of the page, and then i click on the .slider, it automatically jumps all the way to the right side, if i position .container 20px from the left of the page, then i can drag .slider to the right until i'm 20px from the right side of .container, and then it jumps the rest of the way. How can i fix this? hope that made sense.
ExodusNicholas
If the container is positioned relatively (or absolutely) and the slider absolutely, you just have to take the `$slider.parent().offset().left` part out, then the `max_x` is relative to the container.
Tatu Ulmanen