Multiple divs addClass and removeClass at the same time [duplicate] - javascript

This question already has answers here:
Swap css class
(4 answers)
Closed 10 months ago.
I want to make these two divs always have opposite skew angles.
But it doesn’t work and when I click on body, then they have the same skewY value.
Does anyone know how to correct this? Thank you!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="div1 content skew1">
</div>
<div class="div2 content skew2">
</div>
.div1 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.div2 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.skew1 {
transform: skewY(20deg);
transition: transform 1s;
}
.skew2 {
transform: skewY(-20deg);
transition: transform 1s;
}
$(function () {
$("body").on("click", function () {
if ($(".content").hasClass("skew1")) {
$(".content").removeClass("skew1").addClass("skew2");
} else {
$(".content").removeClass("skew2").addClass("skew1");
}
});
});

The problem is that .removeClass and .addClass both operate on ALL the elements in .content. Which means after one click they will have exactly the same classes. Use .toggleClass instead.
Exmaple:
When your App runs $('.content') will return [ <div1 class="skew1">, <div2 class="skew2"> ]
On the first click .removeClass('skew1') will return [ <div1>, <div2 class="skew2"> ]
Then, .addClass('skew2') will return [ <div1 class="skew2">, <div2 class="skew2"> ]
$(function () {
$("body").on("click", function () {
$(".content").toggleClass("skew1 skew2");
});
});
.div1 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.div2 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.skew1 {
transform: skewY(20deg);
transition: transform 1s;
}
.skew2 {
transform: skewY(-20deg);
transition: transform 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="div1 content skew1">
</div>
<div class="div2 content skew2">
</div>

This should help:
$(function() {
$("body").on("click", function() {
const div1 = $(".div1");
const div2 = $(".div2");
if (div1.hasClass("skew1")) {
div1.removeClass("skew1");
div1.addClass("skew2");
div2.removeClass("skew2");
div2.addClass("skew1");
} else {
div1.removeClass("skew2");
div1.addClass("skew1");
div2.removeClass("skew1");
div2.addClass("skew2");
}
});
});

you can do this using toggleClass
$(function () {
$("body").on("click", function () {
$('.content').toggleClass('skew1').toggleClass('skew2')
});
});
.div1 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.div2 {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
}
.skew1 {
transform: skewY(20deg);
transition: transform 1s;
}
.skew2 {
transform: skewY(-20deg);
transition: transform 1s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="div1 content skew1">
</div>
<div class="div2 content skew2">
</div>

Related

How can I repeatedly toggle a CSS animation class without a second click?

I want the colour and size of a div box to animate and return to its original values when a button is clicked. Here is my code example:
document.getElementById("andAction").addEventListener("click", function() {
document.getElementById("box").classList.toggle("animi");
})
.thing {
transform: translate(150px, 100px);
}
.box {
background-color: #999;
padding: 2px;
color: black;
width:20px;
margin: 0 auto;
text-align: center;
color: #fff;
}
#keyframes blob {
0% {
background-color: #999;
}
50% {
background-color: #F9086D;
transform: scale(2);
background-color: red;
border-radius: 20px;
}
100% {
background-color: #999;
}
}
.animi {
animation-name: blob;
animation-duration:3s;
animation-iteration-count:1;
}
<button id="andAction" class="button">button</button>
<div id="box" class="box">1</div>
Problem
My problem is that I am doing it with toggle. Which means I have to click twice on the second time. Another variety was classList.add and then remove again. This leads to no result because the animation is not started for the user. the only thing I could do would be to work with timeout.
Question
I have the feeling there is another way?
You can listen to the onanimationend event to remove the class when the animation ended without relying on timers that are harder to maintain:
const boxElement = document.getElementById("box")
boxElement.addEventListener('animationend', (e) => {
// if the target it the box (it's triggered by animations on children too)
// and the animation name is `blob` (it's triggered by any animation)
// remove the class
if (e.target === boxElement && e.animationName === "blob") {
boxElement.classList.remove('animi');
}
})
document.getElementById("andAction").addEventListener("click", function() {
boxElement.classList.add("animi");
})
Just add some js to remove the class automatically after the animation finished and change your initial behaviour to not toggle but just add the class. You can achieve that by using https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/animationend_event.
const box=document.getElementById("box");
document.getElementById("andAction").addEventListener("click", function() {
box.classList.add("animi");
});
box.addEventListener('animationend', () => {
box.classList.remove("animi");
});
.thing {
transform: translate(150px, 100px);
}
.box {
background-color: #999;
padding: 2px;
color: black;
width: 20px;
margin: 0 auto;
text-align: center;
color: #fff;
}
#keyframes blob {
0% {
background-color: #999;
}
50% {
background-color: #F9086D;
transform: scale(2);
background-color: red;
border-radius: 20px;
}
100% {
background-color: #999;
}
}
.animi {
animation-name: blob;
animation-duration: 3s;
animation-iteration-count: 1;
}
<button id="andAction" class="button">button</button>
<div id="box" class="box">1</div>

If I click, I want to move the box [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 3 years ago.
It's a simple question. If I click the box ,
I want to move 200px to the left. but it's hard to me Please help me!
where's the problem?
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
}
.playing {
transform: translate(200px);
}
</style>
<title>Document</title>
</head>
<body>
<div class="box"></div>
<script>
const move = document.getElementsByClassName("box");
move.addEventListener("click", _move);
function _move(e) {
move.classList.add("playing");
}
document.getElementsByClassName() returns a HTMLCollection, not a single element, so you have to attach the event listener to every element in the collection.
const move = document.getElementsByClassName("box");
[...move].forEach(m => m.addEventListener("click", _move));
function _move() {
this.classList.add("playing");
}
.box {
width: 200px;
height: 200px;
background-color: red;
}
.playing {
transform: translate(200px);
}
<div class="box"></div>
getElementsByClassName returns array so you need to give index
var move = document.getElementsByClassName("box");
move[0].addEventListener("click", _move);
function _move(e) {
move[0].classList.add("playing");
}
.box {
width: 200px;
height: 200px;
background-color: red;
}
.playing {
transform: translate(200px);
}
<div class="box"></div>
Your css property for moving it to the left isn't right.
It should be
.playing {
transform: translateX(200px);
}
You can also use that. instead of using document.getElementsByClassName, use document.querySelector
const move = document.querySelector(".box");
move.addEventListener("click", _move);
function _move(e) {
move.classList.add("playing");
}
.box {
width: 200px;
height: 200px;
background-color: red;
}
.playing {
transform: translate(200px);
}
<div class="box"></div>
As this question is already solved but i was just experimenting if any one wants to move the box continuously by clicking on the box then this code will be helpful.
<head>
<style>
.box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
}
</style>
<title>Document</title>
</head>
<body>
<div class="box"></div>
<script>
let offset = 0;
const move = document.getElementsByClassName("box")[0];
move.addEventListener("click", _move);
function _move(e) {
offset += 200;
move.style.left = offset + 'px';
}
</script>
</body>
$(document).ready(function(){
$('#button-one').click(function(){
$('#box-one').css("transform","translate(200px,0)");
});
});
$(document).ready(function(){
$('#button-two').click(function(){
$('#box-two').css("transform","translate(250px,0)");
});
});
$(document).ready(function(){
$('#button-three').click(function(){
$('#box-one, #box-two').css("transform","translate(0px,0)");
});
});
#box-one,
#box-two
{
width: 100px;
height: 100px;
background-color: blue;
}
#box-two
{
transition: transform 0.6s ease;
}
#button-three
{
position: relative;
left: 100px;
}
body
{
background-color: #E1E7E8;
}
<h2>Translation on click by using jQuery</h2>
<div id="box-one"></div>
<button id="button-one">translate</button>
<hr/>
<h2>Smooth translation on click by using jQuery</h2>
<div id="box-two"></div>
<button id="button-two">translate</button>
<br/>
<button id="button-three">reset</button>

Firefox transition not yet rendered item [duplicate]

I want to smoothly display div from display:none to display:block. I know it can't be done to display:none, so I tried firstly to apply display:block and then perform transition, but this isn't working.
HTML
<input type="text" class="inp">
<div class="div"></div>
CSS
.div {
display: none;
visibility: hidden;
opacity: 0;
height: 100px;
width: 100px;
background: #000;
transition: 2s;
}
.block {
display:block;
}
.div-focused {
visibility: visible;
opacity: 1;
transition: 2s;
}
.one {
background: #ff0;
}
jQuery*
$(document).ready(function() {
$(".inp").on("keyup", function () {
if ( !$(this).val() ) {
$(".div").removeClass("one");
}
else {
$(".div").addClass("block");
$(".div").addClass("div-focused");
$(".div").addClass("one");
}
});
});
Here is the jsfiddle
$(document).ready(function() {
$(".inp").on("keyup", function () {
if ( !$(this).val() ) {
$(".div").removeClass("one");
}
else {
$(".div").addClass("block");
$(".div").addClass("one");
$(".div").animate({opacity: "1"},500);
}
});
});
jsfiddle
Try This
You asked for an hack ? Element.offsetTop is your friend.
When you request this property, the browser is forced to make a reflow of the page, so the class are added and the transitions can trigger, synchronously.
$(document).ready(function() {
$(".inp").on("keyup", function() {
var $div = $('.div');
if (!$(this).val()) {
$div.removeClass("one");
} else {
$div.addClass("block");
$div[0].offsetTop; // here is the magic
$div.addClass("div-focused one");
}
});
});
.div {
display: none;
visibility: hidden;
opacity: 0;
height: 100px;
width: 100px;
background: #000;
transition: 2s;
}
.block {
display: block;
}
.div-focused {
visibility: visible;
opacity: 1;
transition: 2s;
}
.one {
background: #ff0;
}
<input type="text" class="inp">
<div class="div"></div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
$(document).ready(function() {
$("div").hide();
$(".inp").on("keyup", function () {
if ( $(this).val()=="") {
$("div").fadeOut(3000);
} else {
$("div").fadeIn(4000);
}
});
});
.div {
height: 100px;
width: 100px;
background: red;
transition: 2s;
}
.block {
display:block;
}
.div-focused {
visibility: visible;
opacity: 1;
transition: 2s;
}
.one {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="inp">
<div class="div"></div>
Replace your css and script with the below code.
/* style */
.div {
display: none;
height: 100px;
width: 100px;
background: #000;
}
/* Script */
$(document).ready(function() {
$(".inp").on("keyup", function () {
if ( !$(this).val() ) {
$(".div").css("opacity",0);
}
else {
var item = $(this).val();
var length = item.length;
var opacity = length/10;
$(".div").css("display","block");
$(".div").css("opacity",opacity);
}
});
});
Try dis : https://jsfiddle.net/priyaraj/ggqztzvh/

CSS transition in combination with JS clickEvent

Encountering the following issue when trying to combine CSS transitions with JS event handlers. I know how to use CSS transition property for example:
div {
width: 50px;
height: 50px;
background: blue;
transition: width 2s;
}
div:hover {
width: 300px;
}
<div></div>
I also know how to put a click handler on an DOM element like this:
let eventDiv = document.querySelector('#clickMe');
let hiddenDiv = document.querySelector('#hiddenDiv');
eventDiv.onclick = () => {
if(hiddenDiv.style.display === 'block') {
hiddenDiv.style.display = 'none'
} else{
hiddenDiv.style.display = 'block';
}
}
#clickMe{
width: 100px;
height: 50px;
background-color: blue;
}
#hiddenDiv {
width: 100px;
height: 50px;
background-color: green;
display: none;
}
<div id="clickMe"></div>
<div id="hiddenDiv"></div>
Question
How do I combine the two and get a CSS transition (<div> should not appear immediately but should slide in) when I toggle the visibility of the <div> with a JS onclick event?
As per my comment, to combine the js and transition, you need to add and remove a class that changes the property that you want to transition.
In the below snippet, I add and remove a class of hide, which changes the height (that has a trnasition on it)
let eventDiv = document.getElementById('clickMe');
let hiddenDiv = document.getElementById('hiddenDiv');
eventDiv.onclick = () => {
if(hiddenDiv.classList.contains("hide")) {
hiddenDiv.classList.remove("hide");
} else{
hiddenDiv.classList.add("hide");
}
}
#clickMe{
width: 100px;
height: 50px;
background-color: blue;
}
#hiddenDiv {
width: 100px;
height: 50px;
background-color: green;
overflow:hidden;
transition: height 1s;
}
#hiddenDiv.hide {
height: 0;
}
<div id="clickMe"></div>
<div id="hiddenDiv" class="hide"></div>
The problem here is that you cannot give transition to display property:
div {
width: 50px;
height: 50px;
background: blue;
transition: 2s;
}
div:hover {
display:none;
}
<div></div>
What you can do is to use opacity instead.
let eventDiv = document.querySelector('#clickMe');
let hiddenDiv = document.querySelector('#hiddenDiv');
eventDiv.onclick = () => {
if(hiddenDiv.style.opacity === '1') {
hiddenDiv.style.opacity = '0'
} else{
hiddenDiv.style.opacity = '1';
}
}
#clickMe{
width: 100px;
height: 50px;
background-color: blue;
}
#hiddenDiv {
width: 100px;
height: 50px;
background-color: green;
opacity: 0;
transition: 2s;
}
<div id="clickMe"></div>
<div id="hiddenDiv"></div>
IMPORTANT
If you choose to use this property remember to change display to none after the transition is over if you don't want it to be block.

Using .css("background-color") for comparison jQuery/Js

I am working on a project to make angled divs where the break between each basic panel on a page is an angle if the div has a background-image on the previous div, and a background-color of green on the next div.
I know I can't select pseudo classes directly so I decided to use the .addClass() to show and hide the angle.
The problem is my comparisons either turn all divs green, or adds angles to all the divs. I think most of my problem is in my approach, but I'm not sure where I am going wrong.
Here is the JS and the jQuery so far, I'm just trying to make the comparison work so it is still rough:
$(function() {
green = $('div').css("background-color", "rgb(0,255,0)");
if ($('.box').prev() === green)
{
$(this).addClass('withTop withoutTop');
//if ($(this).css("background-color") == green)
}
});
I have used regex to strip all but digits from the rgb but it seems to have the same effect. Thanks in advance and here is the link to the codepen.
http://codepen.io/AnomalousDevs/pen/GJmrrw
CSS and markup
$(function() {
green = $('div').css("background-color", "rgb(0,255,0)");
if ($('.box').prev() === green) {
$(this).addClass('withTop withoutTop');
//if ($(this).css("background-color") == green)
}
});
.box {
height: 100px;
width: 100%;
/*background-color: rgb(0,255,0);*/
position: relative;
}
.box:nth-of-type(5) {
background-color: green;
/* background-image:url("http://www.google.com/imgres?imgurl=http://dreamatico.com/data_images/guitar/guitar-6.jpg&imgrefurl=http://dreamatico.com/guitar.html&h=851&w=1280&tbnid=DVUGPDoyiOu4sM:&zoom=1&docid=OlLKDKDUUigDoM&hl=en&ei=iqJzVcaEOcvAtQXW-oO4Cw&tbm=isch&ved=0CDwQMygKMAo");*/
}
.box:nth-of-type(4) {
background: red;
position: relative;
}
.box:nth-of-type(3) {
background: blue;
}
.box:nth-of-type(2) {
background: rgb(0, 255, 0);
}
.box:nth-of-type(1) {
background: lightblue;
}
.withTop::before {
content: '';
position: absolute;
background: black;
width: 100%;
/*top:-16px;*/
height: 30px;
left: 0;
transform: skewY(-1.3Deg);
z-index: 1;
}
.withoutTop::after {
content: '';
position: absolute;
background: black;
width: 100%;
height: 30px;
left: 0;
transform: skewY(2Deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="parent">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box withTop"></div>
</section>
Your question is not clear but I think that what you are trying to achieve is adding a class to the .box after the green one.
Suggestion of base logic you should do:
$(function() {
var boxes = $('.box'),
greenBox = '';
//for each box
boxes.each(function(index) {
//if this box is the green one
if ($(this).css("background-color") === "rgb(0, 255, 0)") {
greenBox = $(this);
//addClass to the next one
$(this).next().addClass('withTop');
}
});
});
.box {
height: 100px;
width: 100%;
/*background-color: rgb(0,255,0);*/
position: relative;
}
.box:nth-of-type(5) {
background-color: green;
/* background-image:url("http://www.google.com/imgres?imgurl=http://dreamatico.com/data_images/guitar/guitar-6.jpg&imgrefurl=http://dreamatico.com/guitar.html&h=851&w=1280&tbnid=DVUGPDoyiOu4sM:&zoom=1&docid=OlLKDKDUUigDoM&hl=en&ei=iqJzVcaEOcvAtQXW-oO4Cw&tbm=isch&ved=0CDwQMygKMAo");*/
}
.box:nth-of-type(4) {
background: red;
position: relative;
}
.box:nth-of-type(3) {
background: blue;
}
.box:nth-of-type(2) {
background: rgb(0, 255, 0);
}
.box:nth-of-type(1) {
background: lightblue;
}
.withTop::before {
content: '';
position: absolute;
background: black;
width: 100%;
/*top:-16px;*/
height: 30px;
left: 0;
transform: skewY(-1.3Deg);
z-index: 1;
}
.withoutTop::after {
content: '';
position: absolute;
background: black;
width: 100%;
height: 30px;
left: 0;
transform: skewY(2Deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="parent">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box withTop"></div>
</section>

Categories