I am developing a website with Jquery-ui draggables. In the parent div block "container" there are many child draggables which allows user to freely move around the div block.
<div class="container">
<div class="draggable ui-widget-content" id="1">Table 1</div>
<div class="draggable ui-widget-content" id="1">Table 2</div>
...
</div>
I implemented a save function which saves the position of each div block as a json string. It stores the position of the draggables and their IDs. So it can be loaded with where they were at last time.
[{"id":"1","left":"256","top":"226"},{"id":"2","left":"256","top":"632"},{"id":"3","left":"1330","top":"226"},{"id":"4","left":"1330","top":"632"},{"id":"5","left":"818","top":"417"}]
Here's the problem:
I loaded the data from json. It turns out all the position is all wrong.
I recreated using JSFiddle to address the issue: https://jsfiddle.net/braveminds1823/wcmxL2bj/3/
Before saving
After saving, loading the position from json
Edit: I know setting the position to absolute works, but since my website is responsive. The draggables will break out from the container and cover up the web content
You can see from what you've provided in the question (not just the fiddle) that your stored values are not correct.
Looking at just "table" - when you load, it's 20x20, but when you move it further left and up, it's now 256x226 - so clearly not saving correctly.
Your issue is with your use of position
From MDN position:
relative
The element is positioned according to the normal flow of the document, and then offset relative to itself
so the inside squares do not want position:relative, they want position:absolute
absolute
The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to its closest positioned ancestor
So two small changes, in the css:
.draggable {
position:absolute;
}
#containment-wrapper {
position:relative;
}
so that the draggable items are positioned absolutely, relative to the parent wrapper.
Otherwise, your code works fine.
Updated fiddle: https://jsfiddle.net/hrfx9sky/1/
Related
I've built a jsfiddle. It is my first, so I am not certain that it is correct but all the code from my small example is there. Nothing cahnges when I run it. On my machine, the click handler is called but I see no change to the position of the viewport. That is the problem, I would like the image to move to the top of the viewport.
Hope this is a better question.
My original question is below:
I have a relatively positioned div that contains some absolute imgs. I want this arrangement to appear at the top of the viewport. I believe that if I can set the top of the div (position:relative) to the top to the viewport, the images it contains will come along.
Problem is, I can't figure out how to do this. The relative div is at the bottom of the page, and when I click on it, I want the document to reposition so it is displayed at the top with its content. I've tried scrollTop with large positive and negative numbers and I can't get the div to reposition.
I've been trying things like:
$(#view2").scrollTop(xxx);
With no luck.
My html looks like the following. Everything but #view2 is absolute, #view2 is relative. The content of #view1 is set dynamically.
<div id="view2">
<img>
<img>
<div id="view1" ></div>
<img>
<img>
</div>
Since you didn't provide some further it's pretty difficult to analyse your problem:
but scrollTop is used like this:
$('html, body').animate({
scrollTop: elementToScrollTo.offset().top
},200);
the parent element of your position absolute container must have position relative.
As i said, it's difficult to answer without proper code snippets of yours
If you just want your container element to sit at the top of your page then use:
#view2 {
position:fixed;
top:0;
left:0;
width:100%;
box-sizing:border-box;
padding:10px;
}
Just an example - obviously if you didn't need padding etc just remove them, the above is just a typical use for a fixed header.
I have checked other posts but none mentioned about a precise location to overlay.
Consider that I have an image, for eg. a traffic light. I need to overlay (not sure if this is the correct term or not) a div on top of the precise location of, the green lamp, for example. This is so that I can animate the div via jQuery to change the colour of the div in order to have an effect that the image is being animated.
The problem now is how to be precise in this, so that the location of the div completely matches that part of the image? Does it mean having to measure the pixels before setting the top and left of the divs? Or is there a smarter way?
I have considered other options such as using canvas (or svg, or silverlight) to redraw the whole thing instead of embedding the image (i.e. redraw a whole new traffic light picture). However, for this I believe it will be way more complicated than what I asked. Correct me if I am wrong here.
Please advise.
One way is to put the image inside a div which is either positioned relative if you want it to be inline with other elements or positioned absolute if you want to set its position on the page. Then position absolutely the overlapping div inside the same div as the image.
for example
Styles
#holder {
position:relative;
}
#over {
position:absolute;
width:40px;
height:40px;
left:20px;
top:30px;
}
Body
<div id='holder'>
<img src='IMAGE SOURCE'>
<div id='over'></div>
</div>
You will need to adjust the width, height, left and top of the div with id='over' as necessary.
You could replace the div with id='over' with an image use position absolute on this image and set left and top as needed.
As asked and explained in this question, the problem with the DIV's width set to 100% is that it'll get the window's width and not the enclosed BODY element.
The solution suggested is to place an auxiliary DIV between BODY and the actual DIV and make its width fix. But that just puts the issue to the next level, doesn't it?
Since I don't know the screen size of my users' viewers (let's call it platform independence - a term I've heard somewhere is good to keep in mind when developing for the web, hehe), I need the main-all-mighty-rooted-and-parentest DIV to be filling out all available space without sticking out.
Of course, setting fix width on BODY won't work. Should I go ugly and pull the width of the part of the window that isn't the window, double it (once for each side) and retract that to set the fix width of some root DIV element?!
And if so - how?! I'm unclear on how to obtain the magic width (which, however, might be googleable) but mostly I'm unsure how to enter that parameter into the static CSS file. Will I have to do that dynamically using jQuery and ready function?
Edit
I executed this line from the console.
$("body")[0].outerHTML
The result was as follows - still displaying the scroll bar.
<body style="width: 600px;">
<div id="mapDiv" style="width: 100%; height: 100%; position: absolute;">!</div>
</body>
Then I executed this line.
$("#mapDiv")[0].style.position = ""
Poof, the scroll bar is gone. I thought absolute was the default setting... Apparently it isn't. There's the problem.
Based on your edit if you have that code then you are stretching your body tag to 600px and the <div> inside with absolute position and width 100%.
First the default for position is static.
Since you are using absolute position this happen, is taken off the DOM and search for a new containing block:
The containing block for a positioned box is established by the nearest positioned ancestor
If you don't set the body with any position value then the div is off and takes values in relation to another parent in this case is the window or <html> tag.
Then if you inspect the element is with the dimensions of html tag but positioned where he was in this example http://jsfiddle.net/wZ57C/. Is causing scroll because has 100% dimensions but positioned where body begins wich is at margin 8px aprox. Here you solve the scroll just adding position top:0 left:0 check here http://jsfiddle.net/wZ57C/1/.
But if you want the div be 100% of the body and position:absolute then make the body the relative parent http://jsfiddle.net/wZ57C/2/.
This is hard to explain but I have draggable and droppable elements on my page. Some of the droppable elements have draggable elements inside them already but most don't.
When you hover over the droppables a back-ground image appears so you know your hovering over it. However, when you move a draggable into another droppable, now hovering over the newly moved draggable a background image appears in the OLD droppable which used to contain it.
if you look here you can see my problem: - try moving one of the yellow boxes around and then hover over it after you've moved it. The background image appears in the initial position.
http://liquidlizard.net/
Can anyone tell me how to sort this out? I'd appreciate it :)
EDIT here's some of the code I'm using
<div id="row-2col0" class="empty"><div class="position"><a href class="bookmark" target="_blank"></a></div></div>
<div id="row-2col1" class="empty"><div class="position"></div></div>
<div id="row-2col2" class="empty"><div class="position"></div></div>
JS:
$('.draggable').draggable({start: function() {var initialposition = ???}});
$('.droppable').droppable({drop: handleDropEvent, accept:'.bookmark'});
function handleDropEvent( event, ui ) {
}
CSS:
.empty:hover{background-image:url(../img/tilehover.png);}
Basically everything has a class 'empty' which shows the background image when the item is hovered over.
The problem is that your dragged element is a child of the div it came from, so when you assign the empty class to that element, because your dragged element is a child of that didv, your CSS rule, .empty:hover comes into play.
To avoid this problem, put a second div inside of each box, like this:
Add a new div inside of the div with the class empty.
So this line: (and all the ones like it)
<div id="row-2col3" class="empty"><div class="position"></div></div>
Changes to this: (I broke it down to make it easier to read.)
<div id="row-2col3" class="empty">
<div class = "elementContainer"> <!-- This is added..-->
<div class = "wordHolder"></div> <!-- ...............-->
</div> <!--................-->
<div class="position"></div>
</div>
Then add this to your CSS:
.elementContainer {
position:relative;
}
.wordHolder {
position:absolute;
width:65px;
height:65px;
}
And finally, replace your CSS rule .empty:hover with elementContainer:hover and it should work!
How and Why it works
To quote w3schools,
An absolute position element is positioned relative to the first parent element that has a position other than static. If no such element is found, the containing block is <html>:
So using .elementContainer with the relative attribute set serves as our container for our absolutely positioned elements with the class wordHolder. And they do not get in the way because they are removed from the regular flow and all the other elements act as if it did not exist.
You can read more about positioning elements here: http://www.w3schools.com/css/css_positioning.asp
Hope this helps!
I was trying to create an image map tool as part of my project
http://jsfiddle.net/MBThE/12/
Full screen result : http://jsfiddle.net/MBThE/12/embedded/result/
I tried to place the links as divs and positioning using css..
But the problem is that adding or deleting new hot spots reults in repositioning of other elements..I found the solution for this as
position:fixed for hot spot divs ..But this makes the hotspots remain there itself even if user scrolls down or up....So is there any way to find the number of pixels scrolled up or down using javascript and trigger an event when scrolling happens,so that i can increment or decrement the divs positions according to scrolling ?
I consider another alternative as HTML5 canvas....But that results in unwanted resizing of image...
So is there any way to make the divs does not affect each other but also place them inside the container div?
Note:- click 'add hot spot' button and click on the image to add hotspot..hover the hotspot to edit the hotspot
Yes, position:absolute will position absolutely based off of the closest parent that is either position:absolute or position:relative. So you could use the following to create a parent and then position within it.
<div style="position:relative" id="parentDiv">
<div style="position:absolute; top:15px; left:15px">I am 15 pixels from the top and left side of my parent div </div>
<div style="position:absolute; top:30px; left:30px">I am 30 pixels from the top and left side of my parent div </div>
</div>
hope that helps