I've tried to show the element div then get the offset and hide it again, also tried to left -9999 in style but neither is working.
var spaceBelow = $(this)[0].getBoundingClientRect().bottom;
console.log("Before: " spaceBelow);
$(this).show();
var spaceBelow = $(this)[0].getBoundingClientRect().bottom;
$(this).hide();
console.log("After: " spaceBelow);
Your proposed solution works fine for me in Vanilla JS.
Code:
function run(){
var test = document.getElementById("test");
test.style.display = "block";
alert(test.getBoundingClientRect().bottom);
test.style.display = "none";
}
<div style="display:none;" id="test"></div>
<button onclick="run();">Run</button>
You can not retrieve the position of a hidden element with "display: none" but you can use the property "visibility: hidden".
Here is the demo of the issue :
console.log($('div > div:eq(0)')[0].getBoundingClientRect().bottom);
console.log($('div > div:eq(1)')[0].getBoundingClientRect().bottom);
console.log($('div > div:eq(2)')[0].getBoundingClientRect().bottom);
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="border: 1px solid black; padding: 50px">
<div style="border: 1px solid grey; height: 100px; width: 100%;"></div>
</div>
<div style="border: 1px solid black; padding: 50px">
<div style="border: 1px solid grey; height: 100px; width: 100%; display: none"></div>
</div>
<div style="border: 1px solid black; padding: 50px">
<div style="border: 1px solid grey; height: 100px; width: 100%; visibility: hidden"></div>
</div>
</html>
You should also use the methods provided by jQuery.
Finding the position of bottom of a div with jquery
Related
This is a super weird problem. Probably caused by something stupid in my HTML or CSS. I'm learning javascript currently, and I'm making a super simple webpage that demonstrates the dragging ability of javascript. I have two divs, one that floats left and one right, and a p element that should be below the divs. The problem is, I can't separate them. The border of the p element extends into the divs for some reason. I've tried messing with the height of the p element, but then the border isn't even around the text—it's in the divs. I've also tried separating them with margin-top on the p element and that brings the divs down with it. So the elements seem stuck together and I truly don't know why. Here is my code:
var dropzone = document.getElementById("dropzone");
var dropzone2 = document.getElementById("dropzone2");
var text = document.getElementById("text");
var dragging = null;
var wheredrop = null;
function dragover(e){
wheredrop = e.target;
}
function dragend(e){
wheredrop.appendChild(dragging);
wheredrop = null;
dragging = null;
}
function drag(e){
dragging = e.target;
}
text.ondragstart = drag;
text.ondragend = dragend;
dropzone.ondragenter = dragover;
dropzone2.ondragenter = dragover;
document.body.ondragenter = dragover;
<!DOCTYPE html>
<html>
<head>
<title>Test Drag</title>
</head>
<body>
<div id="dropzone" style="border: 1px solid black; width: 49.85%; height: 300px; float: left; margin-top: -50px;"></div>
<div id="dropzone2" style="border: 1px solid green; width: 49.85%; height: 300px; float: right; margin-top: -50px;"></div>
<p id="text" draggable="true" style="border: 1px solid pink; margin-top: 150px;">This is text to drag.</p>
</body>
</html>
You can add a property into your styles display:inline-block .I think it will solve both your issue it will be below div and the border of p would only take the size of the text
You can solve this by clearing the float. Add this <div style="clear: both;"></div> between second/last div and p element. This will clear the effect of float after the divs.
<div id="dropzone" style="border: 1px solid black; width: 49.85%; height: 300px; float: left; margin-top: -50px;"></div>
<div id="dropzone2" style="border: 1px solid green; width: 49.85%; height: 300px; float: right; margin-top: -50px;"></div>
<div style="clear: both;"></div>
<p id="text" draggable="true" style="border: 1px solid pink; margin-top: 150px;">This is text to drag.</p>
function select(){
document.getElementById('container').style.border="2px solid red";
}
function pick(){
document.getElementById('container').appendChild(document.getElementById('item'));
}
#container{
height: 100px;
width: 100px;
border: 1px solid black;
}
#item{
height: 50px;
width: 50px;
border: 1px solid black;
background: lightblue;
}
<html>
<body>
<p>Select the container and click the item to put it on the container</p>
<div onclick="select()" id="container">Container</div>
<br><br>
<div id="item" onclick="pick()">Pick me</div>
</body>
</html>
I want to be able to click the item and it goes to the container div and then I click the item again it goes back to its original place. Can I undo this process? Is there a better way to satisfy the same purpose?
You can do this:
function select(){
document.getElementById('container').style.border="2px solid red";
}
// boolean to keep track of the position
var inside = false;
function pick(){
if(!inside) {
document.getElementById('container').appendChild(document.getElementById('item'));
var getMeHere = document.getElementById('getMeBackHere');
}
else {
var pickMe = document.getElementById('container');
document.getElementById('getMeBackHere').appendChild(document.getElementById('item'));
}
inside = !inside;
}
#container{
height: 100px;
width: 100px;
border: 1px solid black;
}
#item{
height: 50px;
width: 50px;
border: 1px solid black;
background: lightblue;
}
<html>
<body>
<p>Select the container and click the item to put it on the container</p>
<div onclick="select()" id="container">Container</div>
<br><br>
<div id = "getMeBackHere"></div>
<div id="item" onclick="pick()">Pick me</div>
</body>
</html>
I would think you could use the parentNode property to check if the item div has the container div as it's parent node, and if it does, append it to the body (or wherever you need it to go). If the item nodes parent is not the container, then append it to the container.
https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode
function select(){
document.getElementById('container').style.border="2px solid red";
}
function pick(){
if(document.getElementById('container').contains(document.getElementById('item')))
{
var item = document.getElementById('item').cloneNode(true);
document.getElementById("container").removeChild(document.getElementById('item'));
document.getElementById('example').appendChild(item);
}
else
document.getElementById('container').appendChild(document.getElementById('item'));
}
#container{
height: 100px;
width: 100px;
border: 1px solid black;
}
#item{
height: 50px;
width: 50px;
border: 1px solid black;
background: lightblue;
}
<html>
<body id="example">
<p>Select the container and click the item to put it on the container</p>
<div onclick="select()" id="container">Container</div>
<br><br>
<div id="item" onclick="pick()">Pick me</div>
</body>
</html>
I think this is the only way to do that.
var savedElement;
function select(){
document.getElementById('container').style.border="2px solid red";
document.getElementById('container').removeChild(savedElement);
document.getElementById('container').after(savedElement);
}
function pick() {
savedElement = document.getElementById('item');
document.getElementById('container').appendChild(savedElement);
}
#container{
height: 100px;
width: 100px;
border: 1px solid black;
}
#item{
height: 50px;
width: 50px;
border: 1px solid black;
background: lightblue;
}
<html>
<body>
<p>Select the container and click the item to put it on the container</p>
<div onclick="select()" id="container">Container</div>
<br><br>
<div id="item" onclick="pick()">Pick me</div>
</body>
</html>
Another solution:
save a copy for document.getElementById('container').parentNode.innerHTML, even you can save it into one array, then it can support undo one by one step.
then when reset, assigns it back ( if save multiple copies into one array, assign with last copy then pop it).
Like below demo:
let cloned = []
cloned.push(document.getElementById('container').parentNode.innerHTML)
function select(){
cloned.push(document.getElementById('container').parentNode.innerHTML)
document.getElementById('container').style.border="2px solid red";
}
function pick(){
cloned.push(document.getElementById('container').parentNode.innerHTML)
document.getElementById('container').appendChild(document.getElementById('item'))
}
function reset(){
cloned && cloned.length > 0 && (document.getElementById('container').parentNode.innerHTML = cloned[0])
cloned = [cloned[0]]
}
function undo(){
cloned && cloned.length > 0 && (document.getElementById('container').parentNode.innerHTML = cloned[cloned.length-1])
cloned.pop()
}
#container{
height: 100px;
width: 100px;
border: 1px solid black;
}
#item{
height: 50px;
width: 50px;
border: 1px solid black;
background: lightblue;
}
<html>
<body>
<button onclick="reset()">Reset</button>
<button onclick="undo()">Undo</button>
<p>Select the container and click the item to put it on the container</p>
<div onclick="select()" id="container">Container</div>
<br><br>
<div id="item" onclick="pick()">Pick me</div>
</body>
</html>
You can change your 'pick' function to check whether the item is in the container and if it is, append it back to body, like this:
function pick(){
var item = doucumentgetElementById('item');
var container = document.getElementById('container');
if (item.parentElement == container)
{
document.body.appendChild(item);
}
else
{
container.appendChild(item);
}
}
On first click item is moved to the container, on second click it's moved back to the body.
In my navigation I have a div. Selecting this div allows another div to appear with options. I would like for the user to be able to select outside of the div and that would close the div, as well as selecting the div that opened it, and the user can obviously re-open this. Think of it as the Facebook navigation dropdown. Just trying to replicate that behavior.
HTML
<div class="headRight">
<ul>
<li><a id="settings"><div id="here">Account Settings</div></a></li>
</ul>
</div>
<div class="navi">
<ul>
<li><a><span>Signout</span></a>
</li>
</ul>
</div>
CSS
#here{
background-image: url(image.png);background-repeat: no-repeat;background-size: 10px;background-position: 4px 5px;opacity: 1;display: inline-block;height: 15px;overflow: hidden;text-indent: 534px;white-space: nowrap;width: 20px;top: 2px;left: 12px;margin-left: -9px;position: relative;
}
#here.active{
background-image: url(someimeage.png);background-repeat: no-repeat;background-size: 10px;background-position: 4px 5px;opacity: 1;display: inline-block;height: 15px;overflow: hidden;text-indent: 534px;white-space: nowrap;width: 20px;top: 2px;left: 12px;margin-left: -9px;position: relative;
}
.navi{
background: white;width: 200px;box-shadow:0px 1px 8px 0px rgba(0, 0, 0, .3);height: 122px;float: right;left: 759px;top: 45px;position: absolute; display:none;
}
JS
$j("#settings").click(function(e){
if($j("#here").hasClass("active")){
$j("#here").removeClass("active")
$j(".navi").hide();
}
else{
$j("#here").addClass("active")
$j(".navi").show();
}
});
$j(document).click(function(e) {
if (e.target.className !== "navi" && !$j(".navi").find(e.target).length && $j('.navi').css('display') == 'block') {
$j(".navi").hide();
}
})
A simple way is to add click listeners to the said div and the body
$("#first").click(function (e) {
e.stopPropagation();
$("#second").show();
});
$("body").click(function (e) {
$("#second").hide();
})
html, body {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first" style="width: 200px; height: 300px; border: 3px solid black">
</div>
<div id="second" style="width: 200px; height: 300px; border: 3px solid black; display: none">
</div>
However, this one uses event.stopPropagation. If for some reason you don't want to stop propagation because it's nested inside another element that you want to receive events then you can check where the event was called instead and check if it was body or something else.
$("#first").click(function (e) {
$("#second").show();
});
$("body").click(function (e) {
console.log(event.target.nodeName);
if (event.target.nodeName != "BODY")
return
$("#second").hide();
})
html, body {
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first" style="width: 200px; height: 300px; border: 3px solid black">
</div>
<div id="second" style="width: 200px; height: 300px; border: 3px solid black; display: none">
</div>
I have a flash object which is 300x600. I want to place it horizontally with another div. swfObject creates it with style="display: block !important;", so I think that's the problem.
I've tried to use swfobject.createCSS to disable this, but it didn't work-out.
I'd be glad for help.
Here's how you can do it ...
<!DOCTYPE html>
<html>
<head>
<style>
#wrapper {
width: 500px;
border: 1px solid black;
overflow: auto;
}
#first {
float: left;
width: 300px;
border: 1px solid red;
}
#second {
border: 1px solid green;
margin: 0 0 0 302px;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="first">
<object width="300" height="315"
data="http://www.youtube.com/v/XGSy3_Czz8k">
</object>
</div>
<div id="second">
<h1>This is some second div</h1>
</div>
</div>
</body>
</html>
Here is my contenteditable element:
#editor {
width: 200px;
height: 30px;
border: 1px solid red;
overflow: hidden;
}
<div id="editor" contenteditable="true"></div>
I want it can autosize according to the user's content. I try to listen to keyup event:
editor.addEventListener("keyup", function (){
newheight = editor.scrollHeight;
editor.style.height = newheight + "px";
})
this could work when the div grow higher, but when user delete all content, the div can't be shorter.
How can I let it be autosize?
DEMO here
Add "display: inline-block;" to your CSS and and "min-" to width and height.
Your DIV will automatically grow the innerHTML content.
<html>
<style type="text/css">
#Test
{
display: inline-block;
min-width: 30px;
min-height: 30px;
border: 1px solid red;
overflow: hidden;
}
</style>
<div id="Test" >
Nothing But Bigger
And <br />
Taller
</div>
</html>
Look at this fiddle:DEMO
This is working fine...
you just use the following HTML tag in your code
<div contenteditable="true" style= "border: 1px solid red; min-height:30px;width:200px"></div>