This question already has answers here:
add and remove div after click [closed]
(5 answers)
Closed 8 years ago.
I would like 4 divs to appear. When I click any of the divs, I would like that div to move to the end.
So, for example, if the first div is clicked, it should become the last div.
The HTML:
</div>
</div>
</div>
</div>
The CSS:
#pop0 {
width: 100px;
height: 100px;
background: yellow;
position: relative;
}
#pop1 {
width: 100px;
height: 100px;
background: red;
position: relative;
}
#pop2 {
width: 100px;
height: 100px;
background: blue;
position: relative;
}
#pop3 {
width: 100px;
height: 100px;
background: green;
position: relative;
}
The jQuery:
var id = "pop0";
$(".pop").bind('click', function(){
var oldId = $(this).attr('id');
$(this).attr('id', id);
id = oldId;
})
Demo
Try this code
JS
$(".pop").on('click', function() {
// Get the closest anchor container
var $a =$(this).closest('a');
// Insert after the last anchor container
$a.insertAfter('a:last')
})
Also bind has been superseeded by on . Use that to bind event handlers.
Also your html can be cleaned up a bit, by not repeating the same styles. Move the common styles to the same class.
CSS
.pop{
width: 100px;
height: 100px;
position: relative;
}
#pop0 {
background: yellow;
}
#pop1 {
background: red;
}
#pop2 {
background: blue;
}
#pop3 {
background: green;
}
Check Fiddle
Perhaps just detach the item and append it to the end of the container?
$(document).on('click','.pop',null,function(){
var $pop = $(this);
var $parent = $pop.parent();
$pop.detach();
$parent.append($pop);
});
http://jsfiddle.net/rtpt5/3/
Using your code which is just bad as you don't have any DOM wrapper element... (except body)
$(".pop").bind('click', function(){
$('body').append($(this).parent());
})
DEMO
Related
I am using a Javascript function to try to add several div elements to an HTML page. The objects show up but they appear to be joined together. I can apply some css such as background-color and width and height, but I can't see how to change properties like top and left. I have tried putting them into a table generated with createElement, but they are still joined together. Is there a way to make the elements seperate after they are added this way? Thanks.
The css
.block {
display: inline-block;
width: 200px;
height: 200px;
top: 200px;
left: 200px;
border: solid 1px black;
background-color: aquamarine;
}
#container {
width: 100%;
height: 200px;
display: flex;
}
The javascript
function setup() {
word = "test";
container = document.getElementById("container");
for (let counter=0;counter<word.length;counter++) {
block = document.createElement("div");
block.innerHTML = word[counter];
block.className = "block";
container.append(block);
}
}
So I have a 360 Virtual tour using pannellum, I have this hotspot code desing in css
.custom-hotspot {
height: 30px;
width: 30px;
border-radius: 50%;
background: rgb(253, 253, 255);
}
I would like that when u click the hotspot popup an image but without using html tags only css and javascript, I try using this
.custom-hotspot:hover {
content: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg); /* no need for qoutes */
width: 100px;
height: 100px;
border-radius: 20%;
}
but this is not a popup image and its not the same.
Does anyone know a solution for this?
If by popup you mean separate browser window then no..
But if you want to display the image next to the cursor on element hover you can display it as the background in a pseudo element.
.custom-hotspot:hover::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 20%;
background-image: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg);
}
Make sure that the parent element has a defined position property like position: relative or absolute. Otherwise the image will be displayed at the top of the closest grandparent that has it defined.
edit..
.clicked::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 20%;
background-image: url(https://i.ibb.co/5c9zFfq/DCIM-100-MEDIA-DJI-0293-JPG.jpg);
}
Javascript:
// this gets HTML collection of all elements with the 'custom-hotspot' class
const elementCollection = document.getElementsByClassName('custom-hotspot');
// add a click listener to each element
elementCollection.forEach(e => {
e.addEventListener('click', handleClick, {passive: true});
});
/// here we toggle our 'clicked' class
function handleClick(event) {
// if '.target' does not work as expected try '.currentTarget'
event.target.classList.toggle('clicked');
}
I have the following DOM structure:
#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}
#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}
#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
}
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child"></div>
</div>
</div>
#content_text and #content_child would have various mouse events. I would like to detect mouse events on #container. But, if I simply attach events to #container, they will be activated by it's children, which is not desired. My requirements are the following (I'm using click events as an example):
when #container is clicked, I want its event to trigger
when a child graphically located within its div (like #content_text) is clicked, I want both the child's and #container's events to trigger
when a child graphically located outside its div (like #content_child) is clicked, I want only the child's event to trigger
I know beforehand which children will be outside and inside the div.
I can think of two approaches, both quite flawed:
Attach mouse events to #container, and for each child outside the div, add events same as those attached to #container, but make the handlers not do anything and make them non-propagating. This gets a bit unwieldy.
Add a "hit area"/"hitbox" div... somewhere. It would be a transparent div that's a child of #container (and the same size) and it would register clicks, which wouldn't propagate to the children of it's siblings, namely #content's children, because they are siblings. If I place it before #content, all of hitbox's events would be eaten by #content and they don't ever trigger. If I place it after, it's the same problem just the other way around. I can't have both listen for the same events at the same time in the same place, without passing them out to all their children.
Is there a way to achieve a hitbox sort of behavior without significant restructuring or fancy Javascript (I'm using Elm so both aren't an option)?
Attach the handler to #container. When you receive the event, if it passed through a child that is graphically outside the container, ignore it.
You can determine the path the click took to get to the container by examining target on the event object, and (if necessary) its parentNode, and so on, until you reach container.
Here's an example (in this, I hardcoded my check of whether the child is graphically inside the parent, since you said you already know that; no need to go into the work of figuring it out for a simple example):
function hook(selector, event, handler) {
var elements = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function(el) {
el.addEventListener(event, handler, false);
});
}
// container's click handler
hook("#container", "click", function(e) {
if (passedThroughChildOutsideBox(e, this)) {
// Ignore
} else {
console.log("container click");
}
});
// child handlers
hook("#content_text, #content_child", "click", function(e) {
console.log(this.id + " click");
});
// Fake detection
function passedThroughChildOutsideBox(e, container) {
var node = e.target;
while (node && node !== container) {
if (node.id === "content_child") { // Again, just hardcoded for demo
return true;
}
node = node.parentNode;
}
return false;
}
#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}
#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}
#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
}
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child"></div>
</div>
</div>
Use stop propagation https://developer.mozilla.org/en/docs/Web/API/Event/stopPropagation
will prevent further propagation..
var container = document.getElementById("container");
var container_text = document.getElementById("content_text");
var container_child = document.getElementById("content_child");
container.addEventListener("click", function () {
console.log('this is the container');
});
container_text.addEventListener("click", function () {
console.log('this is the container_text');
});
container_child.addEventListener("click", function (event) {
event.stopPropagation();
console.log('this is the container_child');
});
#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}
#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}
#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
}
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child"></div>
</div>
</div>
Try e.stopPropagation() which will block parents click while finds child event.
$(document).ready(function() {
$("#container").click(function(e) {
alert("#container clicked");
e.stopPropagation();
});
$("#content_text").click(function(e) {
e.stopPropagation();
alert("#content_text clicked");
});
$("#content").click(function(e) {
e.stopPropagation();
alert("#content clicked");
});
});
#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}
#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}
#content_text {
background: grey;
}
#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child">hi</div>
</div>
</div>
https://codepen.io/anon/pen/zZbYvp
//codepen.io/anon/pen/zZbYvp
I am trying to change the left-position of my absolute positioned div. The style is pre-declared in css using the following:
#menu {
position:absolute;
width:200px;
min-height:40%;
left:-200px;
}
Now, when I try to check what the value of left is using javascript, it shows to be "". The following JS is used to check the value:
var menuElement = document.getElementById('menu');
console.log(menuElement.style.left);
I have set up this codepen as a demonstration. Note that this happens for both negative as positive left-values.
Why is the value of left always ""?
For that matter, it appears that any style element is shown as "". Why is that happening?
You have to use getComputedStyle() to get the rules declared via stylesheet.
var menuElement = document.getElementById('menu');
var menuElement2 = document.getElementById('menu2');
console.log(getComputedStyle(menuElement).left);
console.log(getComputedStyle(menuElement2).left);
console.log(getComputedStyle(menuElement));
console.log(getComputedStyle(menuElement));
#menu {
position: absolute;
width: 200px;
min-height: 40%;
left: -200px;
background-color: black;
}
#menu2 {
position: absolute;
width: 200px;
min-height: 40%;
left: 200px;
background-color: black;
}
<div id="menu"></div>
<div id="menu2"></div>
According to this post i asked how to make a scroll method wich shows a element, scrolls to it and hide the element where i came from.
I improved that code, and it works.
But when I try to do this backwards, so from the second screen to the first screen again. Its not working. Its only scrolling to the top of the #content screen...
How does this come?
Here's a jsFiddle:
In order to achieve the desired effect you ll need to change up your markup/css and js logic a bit, as of now you are hiding the top element so once the scroll is done the bottom element's offset top = 0.
First change is to wrap your html in a <div> we ll give that div an id of #container.
Second of all we need to set the container's position to absolute so that we can slide it up and down on button click.
The css :
html,body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow:hidden;
}
#page1 {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
overflow-y:scroll;
}
#exploreBtn {
height: 50px;
width: 50px;
background-color: red;
}
#goBack {
position: fixed;
bottom: 5%;
right: 5%;
height: 50px;
width: 50px;
background-color: purple;
}
#container {
position:absolute;
width:100%;
height:100%;
}
And finally we need to change up the js:
$(document).ready(function () {
$('#exploreBtn').on('click', function () {
showScrollHide('#content', '#page1');
});
$('#goBack').on('click', function () {
showScrollHide('#page1', '#content');
});
});
function showScrollHide(element, hide) {
var _ele = $(element),
_container = $('#container'),
_ele_top = _ele.offset().top;
if(_ele_top < 0)
_ele_top = 0;
console.log(_ele_top);
_ele.fadeIn(500, function () {
_container.stop().animate({
top: - _ele_top
}, 1000);
});
}
We get the desired effect, needs a bit of tweaking but you get the general picture.
Hope i helped.
The fiddle
put this in clck handler of the back to top button:
$('html').scrollTop(0);