CSS - Transition does not work properly in JavaScript for loop - javascript

I have used a JavaScript for loop to change the className property of a group of DIV's that have same class.
I'm trying to change of appearance of each div by the changing the className property so that the CSS transition activates and effects the each DIV.
The problem is that the transition ONLY affects the first DIV.
Here is my HTML code:
<body onload="init()">
<div id="menu">
<div class="accor hide" id="chosen">
od
</div>
<ul>
<li>To</li>
<li>Pr</li>
<li>La</li>
</ul>
<div class="accor hide">
En
</div>
<ul>
<li>fa</li>
<li>Co</li>
<li>Co</li>
</ul>
<div class="accor hide">
Sp
</div>
</div>
</body>
Here is my CSS:
.accor + ul {
max-height: 500px;
overflow: hidden;
transition: max-height 0.5s ease
}
.hide + ul {
max-height: 0px;
overflow: hidden;
transition: max-height 0.5s ease
}
Here is my JavaScript:
function init() {
var chosen = document.getElementById("chosen");
chosen.onclick = toggleDivs;
}
function toggleDivs() {
hideDivs = document.getElementsByClassName("accor hide");
for(var i = 0; i <= hideDivs.length; i++) {
hideDivs[i].className = 'accor';
}
}
When I click the DIV with the id of "chosen" I want to make all the DIV's with the class "accor" slide down like like jQuery's $.fn.slideDown(...);.
If I change the JavaScript a little bit the transition will effect the first two DIV's.
Here is my changed JavaScript:
hideDivs = document.getElementsByClassName('accor hide');
hideDivs[0].className = 'accor';
hideDivs = document.getElementsByClassName('accor hide');
hideDivs[0].className = 'accor';
I think this is because when I used the for loop (above) i was initially set to 0 and i did not increment so the transition only effected the first DIV.

pugazh have other fix so i want to post hear for diversity.
function toggleDivs() {
var menu = document.getElementsByClassName('accor')
for (var i = 0; i <= menu.length; i++)
menu[i].classList.toggle('hide');
};

I replaced hideDivs[i].className = 'accor'; with hideDivs[0].className = 'accor';
I did this because each time you execute toggleDivs(); the class hide is removed from the element, you want to toggle the DIV's not always hide them.
window.addEventListener("load", init, false);
function init() {
var chosen = document.getElementById("chosen");
chosen.onclick = toggleDivs;
}
function toggleDivs() {
hideDivs = document.getElementsByClassName("accor hide");
for(var i = 0; i <= hideDivs.length; i++) {
hideDivs[0].className = 'accor';
}
}
.accor + ul {
max-height: 500px;
overflow: hidden;
transition: max-height 0.5s ease
}
.hide + ul {
max-height: 0px;
overflow: hidden;
transition: max-height 0.5s ease
}
<body onload="init()">
<div id="menu">
<div class="accor hide" id="chosen">
od
</div>
<ul>
<li>To</li>
<li>Pr</li>
<li>La</li>
</ul>
<div class="accor hide">
En
</div>
<ul>
<li>fa</li>
<li>Co</li>
<li>Co</li>
</ul>
<div class="accor hide">
Sp
</div>
</div>
</body>

Related

jQuery - element crossing another element

I have a fixed div on the page which contains a logo and as the user scrolls and this logo passes over other divs I wnat to the change the colour of the logo.
I have this working over a single div but need to it work across multiple so any help appreciated.
The WIP site can be seen here... dd.mintfresh.co.uk - if you scroll down you'll (hopefully) see the logo change from black to white as it crosses an illustrated egg. I need the same to happen when it crosses other divs further down the page.
The script so far...
jQuery(window).scroll(function(){
var fixed = jQuery("logo");
var fixed_position = jQuery("#logo").offset().top;
var fixed_height = jQuery("#logo").height();
var toCross_position = jQuery("#egg").offset().top;
var toCross_height = jQuery("#egg").height();
if (fixed_position + fixed_height < toCross_position) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else if (fixed_position > toCross_position + toCross_height) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else {
jQuery("#logo img").css({filter : "invert(0%)"});
}
}
);
Any help appreciated. Thanks!
you need to fire a div scroll event. you can assign
$("div1").scroll(function(){
//change the color of the div1
}
});
$("div2").scroll(function(){
//change the color of the div2
}
});
or you can assign a class to divs which you want to change the color
$(".div").scroll(function(){
//change the color of the div which you are scrolling now
}
});
You can use like this :-
$(window).scroll(function() {
var that = $(this);
$('.section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('active')) {
$('.logo').addClass('invert');
} else {
$('.logo').removeClass('invert');
}
}
});
});
body {
padding: 0;
margin: 0;
}
div {
background: #f00;
height: 400px;
}
.logo {
position: fixed;
top: 0;
left: 0;
width: 100px;
}
.logo.invert {
filter: invert(100%);
}
div:nth-child(even) {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://dd.mintfresh.co.uk/wp-content/uploads/2018/06/DD_logo.svg" class="logo" />
<div id="page1" class="section"></div>
<div id="page2" class="section active"></div>
<div id="page3" class="section"></div>
<div id="page4" class="section active"></div>
<div id="page5" class="section"></div>
As your site code you can do like this :
$(window).scroll(function() {
var that = $(this);
$('#content > section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('black')) {
$('#logo img').css({filter: 'invert(0%)'});
} else {
$('#logo img').css({filter: 'invert(100%)'});
}
}
});
});

Javascript transition on click after display block

im trying to make a simple transition from right to left when i click on a button.
I've done this to illustrate what i mean : https://jsfiddle.net/Waarx/9kjhnwLp/22/
var button1 = document.querySelector('#div1');
button1.addEventListener('click', function(event) {
document.querySelector('#display2').style.display = "none";
document.querySelector('#display1').style.display = "block";
});
var button2 = document.querySelector('#div2');
button2.addEventListener('click', function(event) {
document.querySelector('#display2').style.display = "block";
document.querySelector('#display1').style.display = "none";
});
.parent {
width: 800px;
}
.col {
float: left;
width: 20%;
}
.col2 {
width: 70%;
}
.none {
display: none
}
<div class="parent">
<div class="col">
Div1
Div2
</div>
<div class="col2">
<div class="none" id="display1">
display 1
</div>
<div class="none" id="display2">
display 2
</div>
</div>
</div>
I hope that you could help me.
First off you can do the same thing with jQuery like this with less code:
$('#div1').click(function(event) {
$('#display2').hide();
$('#display1').show();
});
$('#div2').click(function(event) {
$('#display2').show();
$('#display1').hide();
});
Secondly: To animate an html element you have to set its opacity. display: none; will not animate at all. Also using only classes makes you lose less time on your CSS. So,
Test it here:
$( document ).ready(function() {
$('.div1').click(function(event) {
$('.display2').addClass('none');
$('.display1').removeClass('none');
});
$('.div2').click(function(event) {
$('.display2').removeClass('none');
$('.display1').addClass('none');
});
});
.display1, .display2 {
transform: translateX(0);
transition: all 1s ease-in-out;
}
.none {
transform: translateX(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="parent">
<div class="col">
Div1
Div2
</div>
<div class="col2">
<div class="display1 none">
display 1
</div>
<div class="display2 none">
display 2
</div>
</div>
</div>

How to shade an image and keep the value assigned in it in javascript?

I would like to know how I can click on an image like this
If I click on the BMW or Toyota logo then it shades the icon I have selected with CSS then keep that 'value' and save it in javascript variable so I can use later.
Let's say I have this
<ul class="car_types">
<li class="bmw"><img src="test/bmw.png"></li>
<li class="audi"><img src="test/audi.png"></li>
<li class="toyota"><img src="test/toyota.jpg"></li>
<li class="benz"><img src="test/benz.jpg">Discover</li>
</ul>
or i have
<table>
<tr>
<div class="car_types">
<img id="bmw" src="test/bmw.png">
<img id="audi" src="test/audi.png">
<img id="toyota" src="test/toyota.jpg">
<img id="benz" src="test/benz.jpg">
</div>
</tr>
</table>
or any other way of doing it.
Many thanks.
You need to add an event listener to each of your images, so that you can select which image should be highlighted.
Then, create a special css class which gives a special style to the selected image.
I've created a simple demo below:
Here, we have a listener that listens on the "click" event on the <li> elements inside of your .car_types list. When we do click on an image, we remove any elements that might have the shaded class (from a previous click), and then add the shaded class to the one we just clicked on.
The shaded class just gives a 50% brightness, instead of 100%.
$(".car_types li").on("click", function(){
$(".car_types li").each(function() {
$(this).removeClass("shaded");
});
$(this).addClass("shaded");
});
.car_types li {
display: inline-block;
}
.shaded {
filter: brightness(50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="car_types">
<li class="bmw"><img src="http://via.placeholder.com/135x135"></li>
<li class="audi shaded"><img src="http://via.placeholder.com/135x135"></li>
<li class="toyota"><img src="http://via.placeholder.com/135x135"></li>
<li class="benz"><img src="http://via.placeholder.com/135x135"></li>
</ul>
If you want to be able to shade several logos at once, try this instead:
$(".car_types li").on("click", function(){
if($(this).hasClass("shaded")) {
$(this).removeClass("shaded");
} else {
$(this).addClass("shaded");
}
});
.car_types li {
display: inline-block;
}
.shaded {
filter: brightness(50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="car_types">
<li class="bmw"><img src="http://via.placeholder.com/135x135"></li>
<li class="audi shaded"><img src="http://via.placeholder.com/135x135"></li>
<li class="toyota"><img src="http://via.placeholder.com/135x135"></li>
<li class="benz"><img src="http://via.placeholder.com/135x135"></li>
</ul>
Here it is with pure JS
HTMLCollection.prototype.each = function(cb) { for(var i = 0; i < this.length; i++) {
cb(this[i], i);
}
}
var imgs = document.getElementsByTagName('img');
imgs.each(function(img) {
img.addEventListener('click', function(ev) {
imgs.each(function(img) {
img.classList.remove('selected');
});
ev.target.classList.add('selected');
});
});
img {
opacity: .8;
}
.selected {
opacity: 1;
}
<ul class="car_types">
<li class="bmw"><img src="test/bmw.png"></li>
<li class="audi"><img src="test/audi.png"></li>
<li class="toyota"><img src="test/toyota.jpg"></li>
<li class="benz"><img src="test/benz.jpg">Discover</li>
</ul>
Considering you have added event listener like this,
Have a global variable in your js file and modify it on click event..
var selectedVal; //global variable for value
$(".car_types li").on("click", function(){
$(".car_types li").each(function() {
$(this).removeClass("shaded");
});
$(this).addClass("shaded");
selectedVal=$(this).data("val"); //modifying global variable
});
//access selectedVal anywhere
HTML:
<ul class="car_types">
<li class="bmw" data-val="bmw"><img src="test/bmw.png"></li>
<li class="audi" data-val="audi"><img src="test/audi.png"></li>
<li class="toyota" data-val="toyota"><img src="test/toyota.jpg"></li>
<li class="benz" data-val="benz"><img src="test/benz.jpg">Discover</li>
</ul>
CSS:
.shaded{
box-shadow:0px 0px 20px black;
}
Usually, you add a click listener to the image. This click listener then adds a selected class to the image. The image has styles which it applies when there is a .selected class on the image. These styles should then shade the image. The click listener also sets the JavaScript variable which you can then use.
Here is an example with plain JavaScript (no jQuery):
var selectedCar = 'no car selected';
var allCarTypes = document.querySelectorAll('.car_type');
allCarTypes.forEach(function (item) {
item.addEventListener('click', function (event) {
var selectedElement = event.target;
removeSelectedClassForAllElements();
selectedElement.classList.add('selected');
selectedCar = selectedElement.id;
});
});
function removeSelectedClassForAllElements () {
allCarTypes.forEach(function (item) {
item.classList.remove('selected');
});
}
.car_type {
width: 130px;
height: 130px;
position: relative;
cursor: pointer;
}
.car_type:after {
content: "";
position: absolute;
top: 0;
left: 0;
display: block;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.5);
transition: 0.3s ease all;
opacity: 0;
visibility: hidden;
}
.car_type.selected:after {
opacity: 1;
visibility: visible
}
<div class="car_types">
<img id="bmw" class="car_type" src="test/bmw.png">
<img id="audi" class="car_type" src="test/audi.png">
<img id="toyota" class="car_type" src="test/toyota.jpg">
<img id="benz" class="car_type" src="test/benz.jpg">
</div>
<!-- do not use 'onclick' -->
<button onclick="alert(selectedCar);">Which car is selected?</button>

disable and enable click events with a counter and transition effects

I have the following lines of code in my web page - demo/example.
HTML:
<button class="wrong-answer" onclick="showResult(this)">42</button>
<button class="right-answer" onclick="showResult(this)">43</button>
<p id="answer" class="answer-display-hidden">answer</p>
<div class="incorrect">
<span>Incorrect:</span>
<p>0</p>
</div>
<div class="correct">
<span>Correct:</span>
<p>0</p>
</div>
CSS:
.answer-display-visible {
visibility: visible;
opacity: 1;
transition: opacity 1s linear;
}
.answer-display-hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 1s, opacity 1s linear;
}
.incorrect, .correct {float: left; padding-right: 20px}
JS:
var incorrectCalls = 0;
var correctCalls = 0;
function showResult(b) {
var res = document.getElementById('answer');
if (b.classList.contains('right-answer')) {
res.innerHTML = '<span class="right">right</span>';
correctCalls++;
var cor = $('.correct > p:first');
cor[0].innerHTML = correctCalls;
}
else {
res.innerHTML = '<span class="wrong">wrong</span>';
incorrectCalls++;
var incor = $('.incorrect > p:first');
incor[0].innerHTML = incorrectCalls;
}
res.classList.remove("answer-display-hidden");
res.classList.add("answer-display-visible");
setTimeout(function() {
res.classList.add("answer-display-hidden");
}, 2000);
}
How can I de-activate the right-answer counter during the fade-in and wait effect on the text, and then re-activate afterwards? This is so that the user can't manipulate the counter (click on the button quickly before the text is displayed).
You can use setTimeout function when button clicked.
Live Demo
Code Block:
function showResult(b) {
.
.
.
$(".right-answer").prop("disabled", true);
$(".wrong-answer").prop("disabled", true);
setTimeout(function() {
$(".right-answer").prop("disabled", false);
$(".wrong-answer").prop("disabled", false);
}, 2600);
}
This is my solution
WORKING DEMO
Removed CSS code and following is the jQuery code.
$(document).ready(function(){
$(".wrong-answer").click(function(){
$(".right-answer").attr("disabled","disabled");
$("#answer").text("WRONG").fadeIn(5000,function(){
$(this).fadeOut(5000,function(){
$(".right-answer").removeAttr("disabled");
});
})
});
});

How can I change the x position of a div via javascript when I click on another div this way?

<body>
<div id = "SiteContainer">
<div id = "NavigationButtons"></div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition();">x</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition();">y</div>
<div id = "VideoWrapper">
<div id = "SlideShowItem">
<img src="Images/A.png" alt="A"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/B.png" alt="B"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/C.png" alt="C" ></img>
</div>
</div>
</div>
</div>
<script>
var wrapper = document.querySelector("#VideoWrapper");
function setPosition(e)
{
if(e.target.name = "forward")
{
if!(wrapper.style.left = "-200%")
{
wrapper.style.left = wrapper.style.left - 100%;
}
}
else
{
if(e.target.name = "back")
{
if!(wrapper.style.left = "0%")
{
wrapper.style.left = wrapper.style.left + 100%;
}
}
}
}
</script>
</body>
Hi, I am very new to javascript. What I am trying to do, is change the x-position of a div when another div (NavigationForward or NavigationBackward) is clicked. However it does not appear to do anything at all. Basically if the div with name forward is clicked, I want to translate the VideoWrapper -100% from it's current position and +100% when "back". The css div itself VideoWrapper has a width of 300%. Inside this div as you can see is a SlideShowItem which is what will change. Perhaps I am adding and subtracting 100% the wrong way?
EDIT:
Thanks everyone for helping me out with this...I had just one more query, I am trying to hide the arrows based on whether the wrapper is at the first slide or the last slide. If its on the first slide, then I'd hide the left arrow div and if it's on the last, I'd hide the right arrow, otherwise display both of em. Ive tried several ways to achieve this, but none of em work, so Ive resorted to using copies of variables from the function that works. Even then it does not work. It appears that my if and else if statements always evaluate to false, so perhaps I am not retrieving the position properly?
function HideArrows()
{
var wrapper2 = document.getElementById("VideoWrapper");
var offset_x2 = wrapper2.style.left;
if(parseInt(offset_x2,10) == max_x)
{
document.getElementById("NavigationForward").display = 'none';
}
else if(parseInt(offset_x2,10) == min_x)
{
document.getElementById("NavigationBackward").display = 'none';
}
else
{
document.getElementById("NavigationForward").display = 'inline-block';
document.getElementById("NavigationBackward").display = 'inline-block';
}
}
//html is the same except that I added a mouseover = "HideArrows();"
<div id = "ShowReelContainer" onmouseover="HideArrows();">
To achieve this type o slider functionality your div VideoWrapper must have overflow:hidden style, and your SlideShowItemdivs must have a position:relative style.
Then to move the slides forward or backward you can use the style left which allows you to move the divs SlideShowItem relative to it's parent VideoWrapper.
I've tested this here on JSFiddle.
It seems to work as you described in your question, although you may need to do some adjustments, like defining the width of your slides, how many they are and so on.
For the sake of simplicity, I defined them as "constants" on the top of the code, but I think you can work from that point on.
CSS
#VideoWrapper{
position:relative; height:100px; white-space:nowrap;width:500px;
margin-left:0px; border:1px solid #000; overflow:hidden; }
.SlideShowItem{
width:500px; height:100px;display:inline-block;position:relative; }
#NavigationForward, #NavigationBackward{
cursor:pointer;float:left; background-color:silver;margin-right:5px;
margin-bottom:10px; text-align:center; padding:10px; }
HTML
<div id = "SiteContainer">
<div id = "NavigationButtons">
</div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition('back');">prev</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition('forward');">next</div>
<div style="clear:both;"></div>
<div id = "VideoWrapper">
<div class= "SlideShowItem" style="background-color:blue;">
Slide 1
</div>
<div class = "SlideShowItem" style="background-color:yellow;">
Slide 2
</div>
<div class = "SlideShowItem" style="background-color:pink;">
Slide 3
</div>
</div>
</div>
</div>
JavaScript
var unit = 'px'; var margin = 4; var itemSize = 500 + margin; var itemCount = 3; var min_x = 0; var max_x = -(itemCount-1) * itemSize;
function setPosition(e) {
var wrapper = document.getElementById("VideoWrapper");
var slides = wrapper.getElementsByTagName('div');
var offset_x = slides[0].style.left.replace(unit, '');
var curr_x = parseInt(offset_x.length == 0 ? 0 : offset_x);
if(e == "forward")
{
if(curr_x <= max_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + -itemSize) + unit;
}
else if(e == "back")
{
if(curr_x >= min_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + itemSize) + unit;
} }
After you analyze and test the code, I don't really know what's your purpose with this, I mean, you maybe just playing around or trying to develop something for a personal project, but if you are looking for something more professional avoid to create things like sliders on your own, as there are tons of plugins like this available and well tested out there on the web.
Consider using jQuery with NivoSlider, it works like a charm and is cross browser.
I would recommend using jQuery, this will reduce your coding by quite a bit. Can read more here: http://api.jquery.com/animate/
I've created a simple fiddle for you to take a look at. This example uses the .animate() method to reposition two div elements based on the CSS 'left' property.
CSS:
#container {
position: absolute;
left: 1em;
top: 1em;
right: 1em;
bottom: 1em;
overflow: hidden;
}
#one, #two {
position: absolute;
color: white;
}
#one {
background: pink;
width: 100%;
top:0;
bottom:0;
}
#two {
background: blue;
width: 100%;
left: 100%;
top:0;
bottom:0;
}
HTML:
<div id="container">
<div id="one">Div One</div>
<div id="two">Div Two</div>
</div>
JavaScript/jQuery:
var one, two, container;
function animateSlides(){
one.animate({
left : '-100%'
}, 1000, function(){
one.animate({
left : 0
}, 1000);
});
two.animate({
left : 0
}, 1000, function(){
two.animate({
left:'100%'
}, 1000);
});
};
$(function(){
one = $('#one');
two = $('#two');
container = $('#container');
setInterval(animateSlides, 2000);
});
JSFiddle Example: http://jsfiddle.net/adamfullen/vSSK8/3/

Categories

Resources