3

Edit

The thing that was bothering me, was that if you drag the div all the way to the bottom right, then you make the browsers size larger, the div isn't within its parents view, until you actually drag it. Once you drag it, it snaps back within its parents view.

How can I make the div stay in its parent view even after you resize the browser?

JSFiddle

See code snippet bellow.



Older

I have a div which I made draggable through JQuery UI. I want it to be positioned with a percentage value. This way, when you resize the browser, the div will be relatively, or proportionally at the same position.

I checked out this answer, and followed what it said. When I output the left and top position, the numbers were not accurate. When I drag the div all the way to the bottom right, it gives me the following output:

66.55518394648828%
92.71255060728744%

Actually, it does depend on the window size, but the point is, the numbers aren't 100% for left and right.

How can I keep the div at the same position proportionally, when the browser resizes?

Relevant Code:

stop: function () {
    console.log(parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
    console.log(parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");
}

JSFiddle

Code Snippet

var wrapper = $('#fixed');
var dragDiv = $('#draggable');

dragDiv.css({
  'top': ($(window).height() / 2) - (dragDiv.outerHeight() / 2),
  'left': ($(window).width() / 2) - (dragDiv.outerWidth() / 2)
});

dragDiv.draggable({
  containment: "parent", // <- keep draggable within fixed overlay
  stop: function() {
    $(this).css("left", parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
    $(this).css("top", parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");

    console.log(parseInt($(this).css("left")) / (wrapper.width() / 100) + "%");
    console.log(parseInt($(this).css("top")) / (wrapper.height() / 100) + "%");
  }
});
body {
  /*width: 2000px;
  height: 2000px;*/
  background-image: url("http://www.freevector.com/site_media/preview_images/FreeVector-Square-Patterns-Set.jpg");
}
#fixed {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.25)
}
#draggable {
  color: lightblue;
  background-color: red;
  width: 200px;
  position: absolute;
}
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>


<div id="fixed">
  <div id="draggable">Drag Me!</div>
</div>
Community
  • 1
  • 1
Jessica
  • 9,379
  • 14
  • 65
  • 136
  • 1
    I don't understand why it need to be 100%. Please note that when your div is at the right-most side of the screen, the sum of its left position AND its width added together will be the viewport's width. If the div's left is 100% its content will spill outside its container. I think you need to clarify what is your desired result here. – AVAVT Dec 04 '15 at 05:19
  • How do you know it is not accurate? – Abhitalks Dec 04 '15 at 05:27
  • Oh, I get what you're saying! You're right! So I guess the thing that was bothering me, was that if you drag the `div` all the way to the bottom right, then you make the browsers size larger, the `div` isn't within its parents view, until you actually drag it. Once you drag it, it snaps back within its parents view – Jessica Dec 04 '15 at 05:28

1 Answers1

0

The problem is the the parent container to the dragable element has the fixed position. You can't position items relative to a fixed element.

 $(this).css("left") // this refers to $('#draggable')

This is not giving you a left position relative to the fixed container, but rather the body element which has padding on it. So either set the html, body, and #fixed container to have a height and width of 100% and make them position relative.

OR

Remove the padding and margin from your body and html element

body, html{ margin: 0px; padding: 0px;}

Fiddle with body, html, and #fixed at 100%

Fiddle with 0 padding and margin

EDIT

I created a new event to fire every time the window is resized. The event checks to see if the dragable div is outside the bounds of the window. Adjusting as necessary to keep the element in view. I used the code WITHOUT the fixed element because it is not necessary. Let me know if you have any questions.

JS

$(window).resize(function () {
  if ($(window).innerWidth() > $(dragDiv).width()) {
    var oLeft = parseInt($(window).innerWidth() - $(dragDiv).width());
    var posLeft = parseInt($(dragDiv).css("left"));
    if (posLeft > oLeft) {
      $(dragDiv).css("left", oLeft);
      toPercent();
    }
  }

  if ($(window).innerHeight() > $(dragDiv).height()) {
    var oTop = parseInt($(window).innerHeight() - $(dragDiv).height());
    var posTop = parseInt($(dragDiv).css("top"));
    if (posTop > oTop) {
      $(dragDiv).css("top", oTop);
      toPercent();
    }
  }

});

function toPercent() {
  $(dragDiv).css("left", parseInt($(dragDiv).css("left")) / (wrapper.innerWidth() / 100) + "%");
  $(dragDiv).css("top", parseInt($(dragDiv).css("top")) / (wrapper.innerHeight() / 100) + "%");
}

Updated Fiddle for question part 2

mattdevio
  • 2,319
  • 1
  • 14
  • 28
  • Updated my answer, hope that is what you are looking for. – mattdevio Dec 04 '15 at 07:10
  • Thank you! Really nice and good improvement! There's just one issue. Put the `div` all the way to the right. Then resize the window horizontally so that the window hugs the div on both sides. Then when you make the window larger again, the div goes to the left side. – Jessica Dec 04 '15 at 07:18
  • Also, the fixed div is necessary because, I want the div to stay stationary when you scroll. – Jessica Dec 04 '15 at 07:20
  • @Jessica The reason it goes left is because the point of reference where "top" and "left" is being measured from is the top left corned of the div and not the center of it as you would think. You could remedy this by using negative margins, but you would have to edit the JavaScript code to compensate. Like i said, you can't position an element relative to a fixed container. You would need another div inside of the Fixed element that has a width and height of 100% with it's position set to relative. – mattdevio Dec 04 '15 at 07:29
  • Can you please show an example where the div is measured at the center? – Jessica Dec 04 '15 at 07:39
  • @Jessica I refactored the code because my previous example was getting messy. See if you can understand this code, If you have questions let me know. [jsfiddle take 3](http://jsfiddle.net/tp2pr7wu/14/) – mattdevio Dec 04 '15 at 10:03
  • Thank you very much! Finally! A working solution! Now my only questions will be trying to understand the code. :) 1 - Why do we need to set the margin of the 3 elements? 2 - Why do we need a `span` and a `p` element? We'll start with those questions. – Jessica Dec 04 '15 at 17:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97003/discussion-between-magreenberg-and-jessica). – mattdevio Dec 04 '15 at 17:22
  • I found one more problem. On startup, before you start dragging, if you resize the browser, the draggable `div` doesn't stay centered. – Jessica Dec 04 '15 at 19:31
  • 1
    Hey, just move the conPercent() initial function call to after you set the css to center the dragable div. [fiddle](http://jsfiddle.net/tp2pr7wu/15) – mattdevio Dec 04 '15 at 19:40