Using "transform: translate" with JS only works once - javascript

I'm tyring to move a div every time I click a button. It should always move the same distance. I'm doing this with JavaScript, but I can't seem to get it working after the first click.
HTML
<div id="container">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
<button id="move">Click to move the square</button>
CSS
.slide {
display: inline-block;
width: 100px;
height: 100px;
background: lightblue;
margin-bottom: 10px;
margin-right: 10px;
}
JS
document.getElementById("move").addEventListener("click", function() {
document.getElementById("container").style.transform = "translateX(30px)"
})
I've tried calling the function from outside the event listener, like this:
document.getElementById("move").addEventListener("click", clickNext);
function clickNext() {
document.getElementById("container").style.transform = "translateX(30px)"
}
I've also tried to handle the click event through HTML with the "onclick" attribute:
HTML
<button id="move" onclick="clickNext()">Click to move the square</button>
JS
function clickNext() {
document.getElementById("container").style.transform = "translateX(-100px)"
}
In every one of these code bits the button works as intendedb but only once. After that, the button stops working.
Any help on why that's happening would be much appreciated.

As there is no change in the style property being assigned on the second occurrence of the click hence there is no animation
Try this:
var amount = 30;
var initial = 0;
document.getElementById("move").addEventListener("click", function() {
initial += amount;
document.getElementById("container").style.transform = "translateX(" + initial + "px)"
})
.slide {
display: inline-block;
width: 100px;
height: 100px;
background: lightblue;
margin-bottom: 10px;
margin-right: 10px;
}
<div id="container">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
<button id="move">Click to move the square</button>

Related

Hover on two elements using jQuery

I have two <div> elements attached to each other, I mean there is no space between them.
<div id="box1">1</div>
<div id="box2">2</div>
And I have this jQuery code:
$('#box1 , #box2').hover(function() {
console.log("Hovered")
}, function() {
console.log("Not")
});
My problem is when I move the mouse between box1 and box2, I still get on console log "Not".
I want those divs to be considered as one element so when I move the mouse between them I don't get on console log "Not".
Thanks in advance!
I want those divs to be considered as one element
Well, quite simply, they aren't. And they can't be. That's not how HTML and CSS works.
The hover event is triggered one for each individual element bound to the event handler. And every time you leave one of those elements it will print the "not" output as per your instructions.
There is no "fix" for this in the exact way you described, but there are alternative approaches. An obvious solution is to wrap them both in an outer div and bind the hover event to that instead. Then the whole area will be considered as one element (because it literally is). Demo:
$('#boxcontainer').hover(function() {
console.log("Hovered")
}, function() {
console.log("Not")
});
#boxcontainer {
border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boxcontainer">
<div id="box1">1</div>
<div id="box2">2</div>
</div>
friend check the code below. I think it will work for you. As you have dai you have an absolute position div you must need a parent div and the parent div position must be relative. For doing that you have to add just a simple CSS code position: relative;. You also need to do some changes to your jquery code. You can just hover on the parent div and it will do your work. Hope this code will help you.
//Box 1 Demo
$('#boxParrent1').hover(function() {
console.log("Hovered")
}, function() {
console.log("Not")
});
//Box 2 Demo
$('#boxParrent2').hover(function() {
console.log("Hovered")
}, function() {
console.log("Not")
});
/*Main Code that are needed*/
#boxParrent1, #boxParrent2 {
position: relative;
}
/*Codes Just used to give you a demo*/
#boxParrent1, #boxParrent2{
display: flex;
margin-bottom: 50px;
border: 1px solid #000;
}
#boxParrent1{
width: 200px;
}
#boxParrent2{
width: 210px;
}
#box1, #box2, #box3, #box4{
background: tomato;
width: 100px;
height: 100px;
display: grid;
justify-content: center;
align-items: center;
font-family: Arial;
font-size: 50px;
color: #fff;
cursor: pointer;
}
#box2, #box4{
position:absolute;
top: 0;
left:100px;
background: #02dce6;
}
#box4{
left:110px;
background: #02dce6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boxParrent1">
<div id="box1">1</div>
<div id="box2">2</div>
</div>
<div id="boxParrent2">
<div id="box3">3</div>
<div id="box4">4</div>
</div>
Try to place your 2 div's in one super div
<div id="super">
<div id="box1">1</div>
<div id="box2">2</div>
</div>
$('#super').hover(function() {
console.log("Hovered")
}, function() {
console.log("Not")
});

How to make an entire div clickable except a deep level child div?

I want to make an entire div clickable except a child div. This child div is not an immediate child of the div, rather it is in a few level deeper. I would like to dynamically exclude this child div by just passing div id or class name.
I tried to solve it with jQuery ".not()" and ".children()" methods, which works. But its static in a sense that I need to know in which level the div is and need to align the methods accordingly. However, I want something dynamic which will take only the div's class name or id, and find it from the DOM tree and exclude it from the new DOM object chain so that the jQuery ".click" and ".hover" function can be applied on the entire div except that particular div.
I have created a dummy example of my problem. In the example, I want to make the entire div (i.e., id = main1) hyperlinked except the "#d3" div.
Here is my JSFiddle: JSFiddle
Example Code:
HTML:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>
Untitled Document
</title>
</meta>
</head>
<body>
<div class="center border divmain1" id="main1">
<a href="https://www.google.ca" style="display: block">
link
</a>
<p>
Main
</p>
<div class="border-thin divd1" id="d1">
<p>
d1
</p>
</div>
<div class="border-thin divd2" id="d2">
<p>
d2
</p>
<div class="border-thin divd3" id="d3">
<p>
d3
</p>
<div class="border-thin divd4" id="d4">
d4
</div>
<div class="border-thin divd5" id="d5">
d5
</div>
</div>
</div>
</div>
</body>
</html>
CSS:
.border {
border: 5px solid RosyBrown;
}
.border-thin {
border: 2px solid RosyBrown;
}
.divmain1 {
width: 90%;
margin: 0 auto 0 auto;
overflow: hidden;
}
.divd1 {
width: 30%;
float: left;
}
.divd2 {
width: 60%;
float: right;
margin: 0 0 0 3.5%;
}
.divd3 {
margin: auto;
width: 90%;
}
.divd4 {
width: 30%;
}
.divd5 {
width: 30%;
}
jQuery:
// find elements
var main1 = $("#main1")
var d3 = $("#d3")
// handle click and hover pointer
main1.on("click", function(){
window.open('https://www.google.ca');
});
main1.hover(function(){
$(this).css("cursor", "pointer");
});
Could anyone please help me on how to make an entire div clickable and dynamically exclude a child div?
The key thing here is to pass the event object so you can check what is the element actually receiving the click.
Since #d3 contains both #d4 and #d5 I'm assuming you don't want those elements to fire either.
If that's the case, you can use Node.contains() to check if the element is a descendant of your target element.
The Node.contains() method returns a Boolean value indicating whether
a node is a descendant of a given node, i.e. the node itself, one of
its direct children, [...]
If you just want to prevent the action for the element #d3 itself, you don't need to d3.contains and just if (e.target != d3) should do.
// find elements
var main1 = $("#main1")
var d3 = $("#d3").get(0) // Get the HTMLElement
// handle click and hover pointer
main1.on("click", function(e) {
if (!d3.contains(e.target)) {
console.log("I'll open a window");
} else {
console.log("I'm " + e.target.id + " and won't open a window")
}
});
main1.hover(function() {
$(this).css("cursor", "pointer");
});
.border {
border: 5px solid RosyBrown;
}
.border-thin {
border: 2px solid RosyBrown;
}
.divmain1 {
width: 90%;
margin: 0 auto 0 auto;
overflow: hidden;
}
.divd1 {
width: 30%;
float: left;
}
.divd2 {
width: 60%;
float: right;
margin: 0 0 0 3.5%;
}
.divd3 {
margin: auto;
width: 90%;
}
.divd4 {
width: 30%;
}
.divd5 {
width: 30%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="center border divmain1" id="main1">
link
<p>
Main
</p>
<div class="border-thin divd1" id="d1">
<p>d1</p>
</div>
<div class="border-thin divd2" id="d2">
<p>d2</p>
<div class="border-thin divd3" id="d3">
<p>d3</p>
<div class="border-thin divd4" id="d4">d4</div>
<div class="border-thin divd5" id="d5">d5</div>
</div>
</div>
</div>
</body>
</html>
In your jQuery you can run
event.stopPropagation();
within a click event for the div child you don't want to trigger the initial function.
use cancelBubble
for example, to disable your root event on "#d5" div
$('#d5').on('click', function(e){
// stop the event from bubbling.
e.cancelBubble=true
});
I am not much of a fan of jQuery but I can tell you that this can be done with pure JavaScript. All you have to do is to implement an event listener to the top level div and see if the clicked element or it's parent has the targeted class.
Let's take this HTML markup for an example where we will trigger an alert "Target Locked" when someone clicked anything inside divd4 else "General Action"
function HasSelfClassOrParent(element, classname) {
if (element.classList && element.classList.contains(classname))
return true;
return element.parentNode && HasSelfClassOrParent(element.parentNode, classname);
}
let divd2 = document.querySelector(".divd2")
let target = 'divd4'
divd2.addEventListener("click", function(event) {
let isTargetOrChild = HasSelfClassOrParent(event.target, target)
if (isTargetOrChild) {
alert("Target Locked")
} else {
alert("General Action")
}
})
.border {
border: 5px solid RosyBrown;
}
.border-thin {
border: 2px solid RosyBrown;
padding: 20px;
margin-bottom: 10px
}
.divd4{
background: #64B448;
color: #fff;
cursor: pointer;
}
<p>Click on div four and see what happens</p>
<div class="border-thin divd2" id="d2">
<p>I am Div 2</p>
<div class="border-thin divd3" id="d3">
<p>I am Div 3</p>
<div class="border-thin divd4" id="d4">
<p>I am a simple paragraph inside div four</p>
<p>I am a another paragraph inside div four</p>
</div>
<div class="border-thin divd5" id="d5">
I am Div 5
</div>
</div>
</div>

Show last fadeIn div on first position

I have 10 divs which were displayed in a random time.
How can I set the last shown div on top (rank first position) each time and not in the html order of the divs?
Here is my code:
var myVar;
function showDiv(){
var random = Math.floor(Math.random() * $('.notification').length);
$('.notification').eq(random).fadeIn(200).delay(3000).fadeOut(200);
createRandomInterval();
}
function createRandomInterval(){
setTimeout(showDiv, 500+ Math.random() * 4000);
}
$(document).ready(function(){
createRandomInterval();
});
.notification {
width: 200px;
height: 50px;
background-color: yellow;
border: 1px solid rgba(0,0,0,0.2);
margin-bottom: 5px;
text-align: center;
padding-top: 20px;
display: none;/* hide initially so that fadIn() fadeOut() will work
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="notification">1</div>
<div class="notification">2</div>
<div class="notification">3</div>
<div class="notification">4</div>
<div class="notification">5</div>
<div class="notification">6</div>
<div class="notification">7</div>
<div class="notification">8</div>
<div class="notification">9</div>
<div class="notification">10</div>
Here is my fiddle: https://jsfiddle.net/gkq21ppt/3/
EDIT: Idea for a solution
A solution could be, to wrap the divs and set them column-reverse. And then add a JS-code which sets a sequential number as flex order number to every new faded in div.
But I have no idea how to do this, with my low JS skills.
So the loop could look like:
create number starting by 1 as variable
create class width name e.g. "order-[number]"
in ".order-[number]" class set css property "order" to [number]
add this class to the loop before it is faded in
remove this class after it is faded out
Or?
You can try using .prependTo()
What this will do (I think) is remove the active notification and add it back to the container, in the first position. Because of this behaviour, flexbox shouldn't be necessary.
Note this changes the HTML structure.
updated fiddle
var myVar;
function showDiv() {
var random = Math.floor(Math.random() * $('.notification').length);
$('.notification').eq(random).prependTo('.container').fadeIn(200).delay(3000).fadeOut(200);
createRandomInterval();
}
function createRandomInterval() {
setTimeout(showDiv, 500 + Math.random() * 4000);
}
$(document).ready(function() {
createRandomInterval();
});
.notification {
width: 200px;
height: 50px;
background-color: yellow;
border: 1px solid rgba(0, 0, 0, 0.2);
margin-bottom: 5px;
text-align: center;
padding-top: 20px;
display: none;
/* hide initially so that fadIn() fadeOut() will work */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="notification">1</div>
<div class="notification">2</div>
<div class="notification">3</div>
<div class="notification">4</div>
<div class="notification">5</div>
<div class="notification">6</div>
<div class="notification">7</div>
<div class="notification">8</div>
<div class="notification">9</div>
<div class="notification">10</div>
</div>

Trying to make container div change height on click

I am trying to make a container div change set height on click, but am having trouble getting it to work. I am not sure where I messed up and would love input as I am pretty new to Javascript.
$(function() {
$('#menu').click(function() {
$(".outer").css('height','600px ');
});
});
Here is a JS fiddle: https://jsfiddle.net/r92cc51d/2/
If you are just looking to increase the height on click then you don't need to do it in JS. You can do it in html also.
<div id="outer">
<div id="menu" onClick = "document.getElementById('outer').style.height = '600px';">
</div>
</div>
You're missing closing parenthesis for your click function:
$('#menu').on('click', function() {
$('.outer').css('height', '400px');
});
.outer {
width: 200px;
height: 200px;
background-color: #111111;
}
#menu {
height: 20px;
width: 20px;
background-color: #666666;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<div id="menu">
</div>
</div>

If hasClass help and subtracting from variables

I am trying to make it so when the '.main' is clicked, it will toggle its class to become a '.second', with this new class it will become red but the element will have already been classed as '.main' already, thus, I can still refer to it as '.main'. After that I want it to add to the 'count' variable and, if clicked again, revert back to the appearance of the '.main' class, then subtracting from the 'count' variable!
html
<div class="container">
<div id="box" class="main"></div>
<div id="box" class="main"></div>
<div id="box" class="main"></div>
<div id="box" class="main"></div>
</div>
relevent css
.main {
background: #888888;
}
.second {
background: red;
}
#box {
width: 10px;
height: 10px;
border-radius: 10px;
margin: 1% 1%;
line-height: 100px;
text-align: center;
}
And, jQuery
$(document).ready(function() {
var count = 0;
$('.main').click(function() {
$(this).toggleClass('second')
$(this).toggleClass('main')
if ($(this).hasClass('main')) {
count++;
} else if ($(this).hasClass('second')) {
count--;
}
if (count === 4) {
alert('Success')
}
});
});
So I need help because the jQuery will keep adding to the 'count' variable even if 'this' hasClass '.second'!
IF YOU THINK YOU HAVE AN ANSWER CHECK IT IN JSFIDDLE AND CLICK THE ONE BOX 4 TIMES, IF YOU GET A PROMPT THEN THE 'COUNT--;' ISN'T SUBTRACTING STILL
You may need to change these.
Remove the count variable and instead use jQuery's length.
Do not use the same value for ID.
$(document).ready(function() {
$('.main').click(function() {
$(this).toggleClass('second').toggleClass('main')
if ($('.main').length == 4)
alert('Success')
});
});
.main {
background: blue;
}
.second {
background: red;
}
#box1, #box2, #box3, #box4 {
width: 10px;
height: 10px;
border-radius: 10px;
margin: 1% 1%;
line-height: 100px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<div id="box1" class="main"></div>
<div id="box2" class="main"></div>
<div id="box3" class="main"></div>
<div id="box4" class="main"></div>
</div>
You need to remove $(this).toggleClass('main') from within $('.main').click(function() { updating the code to
$('.main').click(function() {
$(this).toggleClass('second')
if ($(this).hasClass('second')) {
count++;
} else if ($(this).hasClass('main')) {
count--;
}
if (count === 4) {
alert('Success')
}
});
when you toggle the .main class it is removed and it will not fall within the click call
And you can't have multiple items with the same ID within your HTML, you can assign class if it occurs more than once. See the fiddle linked below for an example of how you can have it
jsfiddle example: http://jsfiddle.net/ks14dnL1/4/

Categories

Resources