1

I have a small issue trying to make a centered div draggable. The div is centered by using absolute position and negative margin (a workaround found maybe right here). The issue is that these top and left negative margins, change the limit of the draggable area. So if I set containment: "window", the result is that the div can go outside the window (to the left and to the top) till the end of these negative margin.

I tried to synthesized this issue with this code:

$(document).ready(function(){
 $("#box").draggable({containment: "window", scroll: false});
})
#box{
  position:absolute;
  top:50%;
  left:50%;
  margin-top:-50px;
  margin-left: -50px;
  width:100px;
  height:100px;
  background-color:green;
  text-align:center;
  line-height:8;
  font-size:12px;
  color:white; 
}
#box:hover{
  cursor:move;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8"> 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>  
</head>
<body>
<div id="box">
  <span>DRAG ME A LOT</span>
</div>      
</body>
</html>

Is there a way to prevent the box from going out to the left and to the top?

Many Thanks

Fabio
  • 229
  • 3
  • 5
  • Maybe contain on `body` and add a `50px` margin to top and left? – Owlvark Aug 18 '16 at 19:17
  • I tried to use an external container or tried with body but I had another bug: the draggable div disappeared.... I think the solution I found below is better – Fabio Aug 19 '16 at 06:34

4 Answers4

4

Try this. At the time of draggable creation I am setting margin to zero and setting the offset to current position

$(document).ready(function() {
  $("#box").draggable({
    containment: "window",
    scroll: false,
    create: function() {
      var position = $(this).offset();
      $(this).css('margin', '0').offset({
        top: position.top,
        left: position.left
      });
    }
  });
})
#box {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -50px;
  margin-left: -50px;
  width: 100px;
  height: 100px;
  background-color: green;
  text-align: center;
  line-height: 8;
  font-size: 12px;
  color: white;
}

#box:hover {
  cursor: move;
}
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</head>

<body>
  <div id="box">
    <span>DRAG ME A LOT</span>
  </div>
</body>

</html>
Gautham
  • 41
  • 4
0

I have found a solution. I don't know how much elegant it is but... it seems to work

$(document).ready(function(){
  var x1=50;//half box width
  var x2=$(window).width()-x1;
  var y1=50;//half box height
  var y2=$(window).height()-y1;

  $("#box").draggable({containment:[x1,y1,x2,y2], scroll: false});

  //DRAG AFTER RESIZE
  $(window).resize(function(){
    var new_x2=$(window).width()-x1;
    var new_y2=$(window).height()-y1;
    $("#box").draggable({containment:[x1,y1,new_x2,new_y2], scroll: false});
  });
})
#box{
  position:absolute;
  top:50%;
  left:50%;
  margin-top:-50px;
  margin-left: -50px;
  width:100px;
  height:100px;
  background-color:green;
  text-align:center;
  line-height:8;
  font-size:12px;
  color:white; 
}
#box:hover{
  cursor:move;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">  
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>  
</head>
<body>
 <div id="box">
  <span>DRAG ME A LOT</span>
    </div>      
</body>
</html>

Any improvement will be appreciated

Fabio
  • 229
  • 3
  • 5
0

Slight refactor for efficiency:

$(document).ready(function() {
    var $window = $(window);
    var $box = $("#box");
    var boxWidth = 100;
    var xOffs = boxWidth / 2.0; // half box width
    var yOffs = boxWidth / 2.0;

    var onResize = function() {
        var new_x2 = $window.width() - xOffs;
        var new_y2 = $window.height() - yOffs;
        $box.draggable({
            containment:[xOffs, yOffs, new_x2 ,new_y2],
            scroll: false
        });
    };

    $(window).resize(function(){
        onResize();
    });
    onResize();
});
Owlvark
  • 1,763
  • 17
  • 28
0

Yes something like I finally used :)

$(document).ready(function(){
  function init_drag(){
    var x1=50;//half box width
    var x2=$(window).width()-x1;
    var y1=50;//half box height
    var y2=$(window).height()-y1;
    $("#box").draggable({containment:[x1,y1,x2,y2], scroll: false});
  }

  init_drag();
  $(window).resize(function(){
    init_drag();
  });   
})
#box{
  position:absolute;
  top:50%;
  left:50%;
  margin-top:-50px;
  margin-left: -50px;
  width:100px;
  height:100px;
  background-color:green;
  text-align:center;
  line-height:8;
  font-size:12px;
  color:white; 
}
#box:hover{
  cursor:move;
}
<!doctype html>
<html>
<head>
 <meta charset="utf-8">  
 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>  
</head>
<body>
 <div id="box">
  <span>DRAG ME A LOT</span>
    </div>      
</body>
</html>
Fabio
  • 229
  • 3
  • 5