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.
Related
I am working on a chat application and I have two major issues in chatbox design.
I want some part of the screen scrollable just like other chatting applications when we have more messages we scroll up to see previous messages and other things are fixed on the screen like: sendbar,top-menu-bar, etc. but I unable to do so, I tried overflow-y = scroll but it didn't work.
As I mentioned in the first point some things have to be fixed on the screen but after setting position = fixed it also doesn't work.
I tried everything please help.
function fxn(){
var text = document.getElementById("inp").value
var ele = document.getElementById("parent")
var foo = document.createElement("div")
foo.innerHTML = "<div class = box1>" + text + "</div><br><br><br>";
ele.appendChild(foo)
}
#box {
margin-bottom: 10px;
background-color: aqua;
width: 300px;
border: solid 2px black;
}
.box1 {
display: inline;
padding: 10px;
border-radius: 15px;
width: 300px;
border: solid 2px black;
}
.out{
position: fixed;
width: 100%;
background-color: aquamarine;
}
<body id="bd">
<div id ="box">
Testing chat box
</div>
<div id="parent"></div>
<div class="out">
<input type="text" id="inp">
<button onclick="fxn()">Send</button>
</div>
</body>
Output
I see that the post has been accepted and it works nicely for the OP. But I would still like to present one more option. I just made CSS changes to make the footer fixed and header sticky so as to mimic your requirement.
function fxn(){
var text = document.getElementById("inp").value
var ele = document.getElementById("parent")
var foo = document.createElement("div")
foo.innerHTML = "<div class = box1>" + text + "</div><br><br><br>";
ele.appendChild(foo)
}
#box {
margin-bottom: 10px;
background-color: aqua;
width: 300px;
border: solid 2px black;
position: sticky;
top:0;
}
.box1 {
display: inline;
padding: 10px;
border-radius: 15px;
width: 300px;
border: solid 2px black;
}
.out{
position: fixed;
width: 100%;
background-color: aquamarine;
left: 0;
bottom: 0;
}
<body id="bd">
<div id ="box">
Testing chat box
</div>
<div id="parent"></div>
<div class="out">
<input type="text" id="inp">
<button onclick="fxn()">Send</button>
</div>
</body>
function fxn(){
var text = document.getElementById("inp").value
var ele = document.getElementById("parent")
var foo = document.createElement("div")
foo.innerHTML = "<div class = box1>" + text + "</div><br><br><br>";
ele.appendChild(foo)
ele.scrollTop = ele.scrollHeight;
}
#parent{
height:100px;
overflow-y:scroll;
}
#box {
margin-bottom: 10px;
background-color: aqua;
width: 300px;
border: solid 2px black;
}
.box1 {
display: inline;
padding: 10px;
border-radius: 15px;
width: 300px;
border: solid 2px black;
}
.out{
position: fixed;
width: 100%;
background-color: aquamarine;
}
<body id="bd">
<div id ="box">
Testing chat box
</div>
<div id="parent"></div>
<div class="out">
<input type="text" id="inp">
<button onclick="fxn()">Send</button>
</div>
</body>
please note here i had added height to the parent div and overflow-y to be scroll, and also added ele.scrollTop = ele.scrollHeight; in the js part.
here you can read more about ScrollTop
Try this
function fxn(){
var text = document.getElementById("inp").value
var ele = document.getElementById("parent")
var foo = document.createElement("div")
foo.innerHTML = "<div class = box1>" + text + "</div><br><br><br>";
ele.appendChild(foo)
window.scrollTo(0,document.body.scrollHeight);
}
.out{
width: 100%;
background-color: aquamarine;
}
I have to create boxes inside of a div(The div here is box) whenever the user clicks the button. I have done the following so far, but no boxes are created.
Code:
<!DOCTYPE html>
<html>
<head>
<style>
.myDiv {
height: 50px;
width: 50px;
border-color: blue;
}
#box {
width: 700px;
height: 700px;
border: solid black;
}
</style>
</head>
<body>
<h1>The onclick Event</h1>
<button id ="theBoxes" >Creating boxes</button>
<div id = "box"></div>
<script>
var x = document.getElementById("theBoxes");
x.addEventListener("click", myFunction)
function myFunction() {
var box = document.createElement('div');
box.classList.add('myDiv');
document.body.appendChild(box);
}
</script>
</body>
</html>
var x = document.getElementById("theBoxes");
x.addEventListener("click", myFunction)
function myFunction() {
var box = document.createElement('div');
box.classList.add('myDiv');
document.body.appendChild(box);
}
.myDiv {
height: 50px;
width: 50px;
border: 1px solid blue;
}
#box {
width: 700px;
height: 700px;
border: solid black;
position: absolute;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>The onclick Event</h1>
<button id ="theBoxes" >Creating boxes</button>
<div id = "box"></div>
</body>
</html>
Your code is working, unfortunately border-color: blue in myDiv doesn't work and the box also added outside your div #box.
So I modify a bit your code by adding position: absolute in #box and border: 1px solid blue in .myDiv.
I want to make it so when you click on an image a border shows then when you click on it for the second time it goes away. I've tried many different ways, but first I can't figure out how to get the images to show initially without the borders (only when you click on them the border goes away). From there is when i want to border/disappear when clicked on.
Also, I know you can do in-line css styling in JS, but I don't want to do that. If it's needed though then let me know. I am still learning!
http://jsbin.com/joxuyez/1/edit?html,css,js,output
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Practice Refactoring to jQuery">
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>Practice Refactoring to jQuery</title>
</head>
<body>
<div id="refrigerator">
<div class="oranges">
<img src="https://whydyoueatthat.files.wordpress.com/2011/12/oranges-vitamin-c-lg.jpg">
</div>
<div class="apples">
<img src="http://lymanorchards.com/files/7013/6725/1487/apples.jpg">
</div>
<div class="grapes">
<img src="https://images.homedepot-static.com/productImages/23e05da4-8bdf-4408-8ca0-e9c8c9a780df/svn/van-zyverden-fruit-trees-plants-11425-64_1000.jpg">
</div>
</div>
</body>
</html>
CSS
#refrigerator {
background-color: #FFFFFF;
width: 200px;
border: 5px solid #333333;
}
#refrigerator img {
width: 100px;
display: block;
margin: 30px auto;
}
.oranges {
border: 5px solid orange;
}
.apples {
border: 5px solid red;
}
.grapes {
border: 5px solid purple;
}
JS
$(document).ready(function() {
alert("Pick a healthy snack from the refrigerator!");
});
$('.oranges').click (function(event) {
$('.oranges').css("border","none");
alert("You chose an orange!");
});
$('.apples').click (function(event) {
alert("You chose an apple!");
});
$('.grapes').click (function(event) {
alert("You chose grapes!");
});
Simply toggle a class with each click using toggleClass().
Here I updated your CSS a little, and shorten the script, to show how-to.
Why having a border already set, and just change color, you avoid the element from moving, which it otherwise does by default when changing its size.
Stack snippet
$(document).ready(function() {
//alert("Pick a healthy snack from the refrigerator!");
});
$('.oranges, .apples, .grapes').click( function(event) {
$(this).toggleClass("showborder");
if (this.className.includes('showborder')) {
alert("You selected " + this.className.replace(" showborder","") )
}
});
#refrigerator {
background-color: #FFFFFF;
width: 200px;
border: 5px solid #333333;
}
#refrigerator img {
width: 100px;
display: block;
margin: 30px auto;
}
.oranges, .apples, .grapes {
border: 5px solid transparent;
}
.oranges.showborder {
border-color: orange;
}
.apples.showborder {
border-color: red;
}
.grapes.showborder {
border-color: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="refrigerator">
<div class="oranges">
<img src="https://whydyoueatthat.files.wordpress.com/2011/12/oranges-vitamin-c-lg.jpg">
</div>
<div class="apples">
<img src="http://lymanorchards.com/files/7013/6725/1487/apples.jpg">
</div>
<div class="grapes">
<img src="https://images.homedepot-static.com/productImages/23e05da4-8bdf-4408-8ca0-e9c8c9a780df/svn/van-zyverden-fruit-trees-plants-11425-64_1000.jpg">
</div>
</div>
Updated based on a comment.
If you would want to allow only one at the time, you could do something like this
Stack snippet
$(document).ready(function() {
//alert("Pick a healthy snack from the refrigerator!");
});
$('.oranges, .apples, .grapes').click(function(event) {
if ($(this).hasClass("showborder")) {
$(this).removeClass("showborder");
} else {
$(this).parent().find(".showborder").removeClass("showborder");
$(this).addClass("showborder");
if (this.className.includes('showborder'))
alert("You selected " + this.className.replace(" showborder","") )
}
});
#refrigerator {
background-color: #FFFFFF;
width: 200px;
border: 5px solid #333333;
}
#refrigerator img {
width: 100px;
display: block;
margin: 30px auto;
}
.oranges,
.apples,
.grapes {
border: 5px solid transparent;
}
.oranges.showborder {
border-color: orange;
}
.apples.showborder {
border-color: red;
}
.grapes.showborder {
border-color: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="refrigerator">
<div class="oranges">
<img src="https://whydyoueatthat.files.wordpress.com/2011/12/oranges-vitamin-c-lg.jpg">
</div>
<div class="apples">
<img src="http://lymanorchards.com/files/7013/6725/1487/apples.jpg">
</div>
<div class="grapes">
<img src="https://images.homedepot-static.com/productImages/23e05da4-8bdf-4408-8ca0-e9c8c9a780df/svn/van-zyverden-fruit-trees-plants-11425-64_1000.jpg">
</div>
</div>
you can use .toggleClass with JQuery to handle removing and adding classes. Refer to this JSFiddle I put together. https://jsfiddle.net/xpvt214o/334757/
In JQuery you can make a click handler to target the exact box you're clicking with $(this)
Example:
var box = $(".box")
box.on("click", function(){
$(this).toggleClass('border')
})
If you need each box to be a different color you can do something like this:
.box.border{
border-width: 3px;
border-style: solid;
}
.box1{
border-color: orange;
}
.box2{
border-color: red;
}
.box3{
border-color: blue;
}
With this method, you can have a .border class whichcontrols the style and width of the border. The different classes such as .box1 can alter the border color.
<div>
<div class="box box1">box 1</div>
<div class="box box2">box 2</div>
<div class="box box3">box 31</div>
</div>
Assigned like that. Hope this helps.
As you are still learning, i have a solution for you in a simple way, though better methods are available but definitely this method will help you to understand whats happening. I have made couple of changes in your CSS and JS file.
It also available at https://jsfiddle.net/9s37v6tu/11/
$(document).ready(function() {
alert("Pick a healthy snack from the refrigerator!");
});
$('.oranges').click (function(event) {
if($('.oranges').hasClass('orange-border'))
{
$('.oranges').removeClass('orange-border');
}
else
{
$('.oranges').addClass('orange-border');
}
alert("You chose an orange!");
});
$('.apples').click (function(event) {
if($('.apples').hasClass('apple-border'))
{
$('.apples').removeClass('apple-border');
}
else
{
$('.apples').addClass('apple-border');
}
alert("You chose an apple!");
});
$('.grapes').click (function(event) {
if($('.grapes').hasClass('grape-border'))
{
$('.grapes').removeClass('grape-border');
}
else
{
$('.grapes').addClass('grape-border');
}
alert("You chose grapes!");
});
#refrigerator {
background-color: #FFFFFF;
width: 200px;
border: 5px solid #333333;
}
#refrigerator img {
width: 100px;
display: block;
margin: 30px auto;
}
.orange-border {
border: 5px solid orange;
}
.apple-border {
border: 5px solid red;
}
.grape-border {
border: 5px solid purple;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Practice Refactoring to jQuery">
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>Practice Refactoring to jQuery</title>
</head>
<body>
<div id="refrigerator">
<div class="oranges">
<img src="https://whydyoueatthat.files.wordpress.com/2011/12/oranges-vitamin-c-lg.jpg">
</div>
<div class="apples">
<img src="http://lymanorchards.com/files/7013/6725/1487/apples.jpg">
</div>
<div class="grapes">
<img src="https://images.homedepot-static.com/productImages/23e05da4-8bdf-4408-8ca0-e9c8c9a780df/svn/van-zyverden-fruit-trees-plants-11425-64_1000.jpg">
</div>
</div>
</body>
</html>
$(function(){
$('.box').click(function(){
$('.main div').removeClass('border');
$(this).addClass('border');
var index = $(this).index();
if(index == 0){alert('YOU CLICKED RED BOX!!!');};
if(index == 1){alert('YOU CLICKED GREEN BOX!!!');};
if(index == 2){alert('YOU CLICKED BLUE BOX!!!');};
});
});
.box{
display:inline-block;
width:100px;
height:100px;
margin:10px;
}
.red{
background:red;
}
.green{
background:green;
}
.blue{
background:blue;
}
.border{
border:5px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div class="main">
<div class="box red"></div>
<div class="box green"></div>
<div class="box blue"></div>
</div>
</body>
</html>
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
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>