slide hide & show text - javascript

I want to create an animation where every X seconds the active
class is changing to the next span inside the profession-wrapper span,
in a way that the developer span will slide on top of the active span in a way
that will show the letters of the new active span, slide on top of it while hiding each letter
and when it covers the entire word the active class will go to the next span.
I got the developer span to slide, and the active class to work as they should,
however the developer span does not cover the active span that it slides on,
and since the length of the text is different for each span the sliding doesn't finish on the end of the word but in a fix place that leaves a lot of empty space between the | and the active span.
How can I achieve the slide to cover the text it slides on, and make sure that the slide will finish on the end of the new active word?
const firstProfession = document.querySelector('.profession-wrapper').firstElementChild;
let professionActive = document.querySelector('.active');
setInterval(() => {
professionActive.classList.remove('active');
professionActive.classList.add('inactive');
if (professionActive.nextElementSibling) {
professionActive = professionActive.nextElementSibling;
} else {
professionActive = firstProfession;
}
professionActive.classList.remove('inactive');
professionActive.classList.add('active');
}, 6000);
.profession-header {
display: flex;
width: 100%;
position: relative;
}
.profession-wrapper {
position: relative;
display: flex;
padding-right: 7px;
}
.inactive {
opacity: 0;
position: absolute;
overflow: hidden;
display: inline-block;
}
.active {
opacity: 1;
display: inline-block;
position: relative;
overflow: hidden;
width: max-content;
padding-right: 5px;
}
.developer::before {
content: '';
border-left: 2px solid white;
display: block;
margin-right: 5px;
height: 1.5rem;
position: absolute;
left: -7px;
}
.developer {
position: absolute;
animation: slide-text-in-out 6s ease-in-out infinite;
}
#keyframes slide-text-in-out {
0% {
left: 8px;
}
45%, 55% {
left: 50%;
}
100% {
left: 8px;
}
}
<h5 class="profession-header">
<span class="profession-wrapper">
<span class="profession active">Web</span>
<span class="profession inactive">Full Stack</span>
<span class="profession inactive">Front End</span>
<span class="profession inactive">Back End</span>
</span>
<span class="developer">Developer</span>
</h5>

UPDATED VERSION
In response to the OP's comment below, here is an updated version of the animation script/css, that respects the width of the profession when animating the .developer element.
It works basically the same, but uses CSS transition and transform instead of animation and left to move the .developer div.
setupProfessionAnim(document.querySelector('.profession-header'));
function setupProfessionAnim(containerEl) {
let professions = Array.from(containerEl.querySelectorAll('.profession')),
sliding = containerEl.querySelector('.developer'),
covered = true; // <-- state tracking variable
sliding.addEventListener('transitionend', runNextAnimation); // <-- changed event
runNextAnimation(); // <-- starts the first transition
function runNextAnimation() {
let active, next;
covered = !covered; // <-- inverse the state
if (covered) { // <-- are we in covering mode?
sliding.style.transform = 'translateX(0)'; // <-- then cover
return; // <-- and stop further processing
}
// otherwise
active = getWithClass(professions, 'active');
next = active.nextElementSibling ? active.nextElementSibling : professions[0];
next.classList.add('active'); // <-- switch the .active class
active.classList.remove('active'); // <-- here, too
sliding.style.transform = 'translateX(' + getWidth(next) + 'px)'; // <-- and let the .developer div uncover
}
}
function getWithClass(elList, className) {
return elList.find
? elList.find(el => el.classList.contains(className))
: elList.filter(el => el.classList.contains(className))[0];
}
function getWidth(el) {
return el.getBoundingClientRect().width;
}
.profession-header {
display: flex;
width: 100%;
position: relative;
}
.profession-wrapper {
position: relative;
display: flex;
padding-right: 7px;
}
.profession {
display: none;
width: max-content;
padding-right: 1ex;
}
.profession.active {
display: block;
}
.developer {
position: absolute;
width: 160px; /* adjust if necessary */
background-color: #fff; /* remove if you like, just for demonstation purposes */
transform: translateX(0);
transition: transform 2s ease-in-out 0s;
}
<h5 class="profession-header">
<span class="profession-wrapper">
<span class="profession active">Web</span>
<span class="profession inactive">Full Stack</span>
<span class="profession inactive">Front End</span>
<span class="profession inactive">Back End</span>
</span>
<span class="developer">Developer</span>
</h5>
PREVIOUS VERSION
You should avoid having an implicit requirement between setInterval and CSS animation timings. Instead, use the events a CSS animation fires to switch classes. This makes sure your animation "timelines" cannot get out of sync (another way to view it is that it ensures there's just a single timeline instead of multiple).
Below is a working example that addresses your problems. Please note the comments I left!
setupProfessionAnim(document.querySelector('.profession-header'));
function setupProfessionAnim(containerEl) {
let professions = Array.from(containerEl.querySelectorAll('.profession')), // get an array of all professions
sliding = containerEl.querySelector('.developer'); // get the 'developer' element
sliding.addEventListener('animationiteration', runNextAnimation); // re-execute runNextAnimation whenever an animation iteration finishes
function runNextAnimation() {
// this actually switches the classes from 'active' to 'inactive' and vice-versa
let active = getWithClass(professions, 'active'), // get the current 'active' profession
next = active.nextElementSibling ? active.nextElementSibling : professions[0]; // find next profession
active.classList.replace('active', 'inactive'); // switch!
next.classList.replace('inactive', 'active'); // here, too!
}
}
function getWithClass(elList, className) {
// convenience helper, uses Array.prototype.find if available and falls back to Array.prototype.filter
return elList.find
? elList.find(el => el.classList.contains(className))
: elList.filter(el => el.classList.contains(className))[0];
}
.profession-header {
display: flex;
width: 100%;
position: relative;
}
.profession-wrapper {
position: relative;
display: flex;
padding-right: 7px;
}
.inactive {
opacity: 0;
position: absolute;
overflow: hidden;
display: inline-block;
animation: slide-text-out 2s ease-in-out;
}
.active {
opacity: 1;
display: inline-block;
position: relative;
overflow: hidden;
width: max-content;
padding-right: 5px;
animation: slide-text-in 2s ease-in-out;
}
/* --- removed ---
.developer::before {
content: '';
border-left: 2px solid white;
display: block;
margin-right: 5px;
height: 1.5rem;
position: absolute;
left: -7px;
}
--- removed --- */
.developer {
position: absolute;
/* --- new additions --- */
width: 160px; /* adjust if necessary */
border-left: 2px solid white;
padding-left: 5px;
background-color: #fff; /* remove if you like, just for demonstation purposes */
/* --- end new additions --- */
animation: slide-text-in-out 6s ease-in-out infinite;
}
#keyframes slide-text-in-out {
0% {
left: 0;
}
45%, 55% {
left: 50%;
}
100% {
left: 0;
}
}
<h5 class="profession-header">
<span class="profession-wrapper">
<span class="profession active">Web</span>
<span class="profession inactive">Full Stack</span>
<span class="profession inactive">Front End</span>
<span class="profession inactive">Back End</span>
</span>
<span class="developer">Developer</span>
</h5>

Related

Line across any device and in the centre, using canvas or html,css

I'm making an app using JavaScript and JQuery, which will tell the user if there device is straight or not, basically like a spirit level. I want to draw a line a straight line across the middle of the screen and i want this to be responsive no matter the size of the device. This will be used on mobiles and tablets. I used a canvas to the draw a line and so far i'm not sure if this is the right way to approach this?
if anyone could give me any advice i would really appreciate it. Below is my canvas line so far. And I've included some rough drawing of what i mean.
const c = document.getElementById("LineCanvas");
const drw = c.getContext("2d");
drw.beginPath();
drw.moveTo(10,45);
drw.lineTo(180,47);
drw.lineWidth = 5;
drw.strokeStyle = '#006400';
drw.stroke();
If the phone is aligned straight the line will be green else red
to draw the line you can use a pseudo element from HTML or body or any specific tag that you want to use in a specific page or click , then update rotation via transform:rotate() ; or rotate3D()
example ( without javascript, rotate values will have to be taken from your device via your app ):
let level = document.querySelector("#level");
document.querySelector("#spirit").onclick = function() {
level.classList.toggle('show');
}
#level {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
display: none;
pointer-events: none;
}
#level.show {
display: block;
}
#level::before {
content: '';
position: absolute;
width: 200vmax;
margin: 0 -50vmax;
border-top: 1px solid;
box-shadow: 0 0 1px 5px #bee;
top: 50%;
transform: rotate(0deg);
}
#level.show~#spirit::before {
content: 'Hide';
}
#level:not(.show)~#spirit::before {
content: 'Show';
}
/* animation to fake phone device moving */
#level::before {
animation: rt 10s infinite;
}
#keyframes rt {
20% {
transform: rotate3d(1, -1, 1, -0.25turn);
}
40% {
transform: rotate3d(1, 1, 1, 0.5turn);
}
60% {
transform: rotate3d(1, -1, 1, -0.75turn);
}
80% {
transform: rotate3d(1, 1, -1, -0.5turn);
}
}
<div id="level">
<!-- to show on a single page or via js on user request -->
</div>
<button id="spirit" type=button> that spirit level</button>
While drawing a line with canvas can work you might find it more straightforward to draw it with a simple div element. When you sense a slope you can change its color to red and back to green if it's level.
Of course you will have to do some calculations to decide what angle you want the line to be - but I guess that is the whole point of your webapp to show people how far off they are.
When you know the angle you want the line to be call slope(n) where n is the number of degrees. I've also put in a simple button so the user can choose whether to show the line or not but I expect you'll have your own code for that.
On any page where you want the user to be able to show the line put this in the head:
<style>
* {
margin: 0;
padding: 0;
}
.linecontainer {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
z-index: 99999;
}
#line {
width: 200vmax;
height: 5px;
position: relative;
top: 50%;
left: calc(50vw - 100vmax);
transform: rotate(45deg);
background-color:red;
}
.hideline {
display: none;
}
#showbtn {
font-size: 20px;
background-color: blue;
color: white;
height: 2em;
width: auto;
padding: 2px;
}
</style>
and put this in the main body of the page:
<div class="linecontainer">
<div id="showbtn" onclick="document.getElementById('line').classList.toggle('hideline');">
Click me to show/hide the line
</div>
<div id="line"></div>
</div>
<script>
function slope(deg) {
let line = document.getElementById('line');
line.style.backgroundColor = ( deg%180 == 0 ) ? 'green' : 'red';
line.style.transform = 'rotate(' + deg + 'deg)';
}
</script>
Here's a snippet where you can show the line at different angles.
function slope(deg) {
let line = document.getElementById('line');
line.style.backgroundColor = ( deg%180 == 0 ) ? 'green' : 'red';
line.style.transform = 'rotate(' + deg + 'deg)';
}
* {
margin: 0;
padding: 0;
}
.linecontainer {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
z-index: 99999;
}
#line {
width: 200vmax;
height: 5px;
position: relative;
top: 50%;
left: calc(50vw - 100vmax);
transform: rotate(45deg);
background-color:red;
}
.hideline {
display: none;
}
#showbtn {
font-size: 20px;
background-color: blue;
color: white;
height: 2em;
width: auto;
padding: 2px;
}
<div class="linecontainer">
<div id="showbtn" onclick="document.getElementById('line').classList.toggle('hideline');">
Click me to show/hide the line
</div>
<div id="line"></div>
</div>
<!-- this is just for the demo -->
<div style="background-#eeeeee;font-size: 20px;position:fixed;z-index:100000;bottom:0;left:0;">How many degrees do you want me to rotate? <input style="font-size:20px;"value="45" onchange="slope(this.value);"/></div>

Carousel prev and next button logic does not work

I am trying to a make carousel using pure Javascript. I successfully manage to slide the carousel and have created left and right buttons.
I took my slide functions and added them to the button on-click event-listener, but I have problems when I implement the function on my buttons. It does not behave as expected. My code is below, how can I fix this?
const images = document.getElementById('imgs'); //here
const allImages = document.querySelectorAll('#imgs img');
const leftBtn = document.getElementById('left');
const rightBtn = document.getElementById('right');
let index = 0;
function changeSliderPage() {
const dot = [...document.getElementsByClassName('star')];
index++;
if (index > allImages.length - 1) {
index = 0
}
imgs.style.transform = `translateX(${-index * 500}px)`;
dot.forEach((dot, i) => {
if (i === index) {
dot.classList.add('active')
} else {
dot.classList.remove('active')
}
});
};
allImages.forEach(i => {
const elem = document.createElement('div');
elem.classList.add('star');
document.body.appendChild(elem)
});
rightBtn.onclick = () => {
changeSliderPage(index + 1);
}
leftBtn.onclick = () => {
changeSliderPage(index - 1);
}
let x = setInterval(changeSliderPage, 100000);
images.onmouseover = () => {
clearInterval(x)
}
images.onmouseout = () => {
x = setInterval(changeSliderPage, 2000);
}
*{
box-sizing: border-box;
}
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.carousel {
overflow: hidden;
width: 500px;
height: 500px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, .3);
border-radius: 5px;
}
.image-container {
display: flex;
transition: transform 300ms linear;
transform: translateX(0);
}
img {
width:500px;
height: 500px;
object-fit: cover;
}
.star{
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 10px;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
background-color: #eeeeee;
}
.star.active{
background-color: red;
}
button{
cursor: pointer;
position: relative;
font-size: 18px;
transition: 0.6s ease;
user-select: none;
height: 50px;
width: 40px;
display: flex;
justify-content: center;
align-items: center;
align-content: center;
top: calc(50% - 25px);
}
button:hover {
background-color: rgba(0,0,0,0.8);
};
button.left {
border-radius: 3px 0 0 3px;
right: 0;
}
button.left {
border-radius: 3px 0 0 3px;
left: 0;
}
<button id="left">❮</button>
<button id="right">❯</button>
<div class="carousel">
<div class="image-container" id="imgs" >
<img src="https://images.unsplash.com/photo-1599736375341-51b0a848f3c7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
<img src="https://images.unsplash.com/photo-1516026672322-bc52d61a55d5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
<img src="https://images.unsplash.com/photo-1573081586928-127ecc7948b0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
<img src="https://images.unsplash.com/flagged/photo-1572850005109-f4ac7529bf9f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt="">
</div>
</div>
Logic that I use with carousels:
for example you have 4 images:
[1][2][3][4]
I have an animation for sliding every image, I add 5th image which is same as image no 1:
[1][2][3][4][1]
Imagine cursor which shows what image is currently displayed, Ill mark cursor as ! !
So at begin:
[!1!][2][3][4][1]
Now the slider moves on...
[1][!2!][3][4][1]
etc...
It moves to last image:
[1][2][3][4][!1!]
And now it has to move under the hood from last image to first image, but without any animation so the whole change is not visible by user:
[!1!][2][3][4][5]
This way you can get inifinite carousel, just need to check in javascript if current image is last one and you want to slide right -> no animation. Same if you are on 1st image and want to slide left.

Updating aria-checked attribute of a button not working on Chrome but on Firefox

I tried to updating aria-checked attribute of a toggle button using JS. It works perfectly fine on Firefox but can't toggle on Chrome.
When I log in JS, apparently the attribute got updated. But not on the actual UI when I viewed with Chrome devtool.
Here's live on codepen.
Please checkout codepen link.
e.target is selecting the span in Chrome, instead of the button on which the event was binded, due to event propagation.
Use e.currentTarget instead of e.target, it will select the button on which the event was originally bound and not any of its child elements.
// Rectangular switch
const rect = document.querySelector("#toggle-rect");
rect.addEventListener("click", e => {
let checked = e.currentTarget.getAttribute("aria-checked") === "true";
console.log(checked);
e.currentTarget.setAttribute("aria-checked", String(!checked));
});
// Rounded switch
const round = document.querySelector("#toggle-round");
round.addEventListener("click", e => {
let checked = e.currentTarget.getAttribute("aria-checked") === "true";
console.log(checked);
e.currentTarget.setAttribute("aria-checked", String(!checked));
});
// Rectangular switch
const rect = document.querySelector("#toggle-rect");
rect.addEventListener("click", e => {
let checked = e.currentTarget.getAttribute("aria-checked") === "true";
console.log(checked);
e.currentTarget.setAttribute("aria-checked", String(!checked));
});
// Rounded switch
const round = document.querySelector("#toggle-round");
round.addEventListener("click", e => {
let checked = e.currentTarget.getAttribute("aria-checked") === "true";
console.log(checked);
e.currentTarget.setAttribute("aria-checked", String(!checked));
});
/* reset button */
button {
background: none;
border: 0;
color: inherit;
padding: 0;
}
/* The switch - the box around the slider */
.switch {
position: relative;
/* display: inline-block; */
width: 60px;
height: 34px;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
/* TODO: put disable color here */
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196f3;
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
/* changing the background while toggling */
[role="switch"][aria-checked="true"] .slider {
background-color: #2196f3;
}
/* toggling the handle */
[role="switch"][aria-checked="true"] .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
<!-- Rectangular switch -->
<button role="switch" aria-checked="false" class="switch" id="toggle-rect">
<span class="slider"></span>
</button>
<!-- Rounded switch -->
<button role="switch" aria-checked="false" class="switch" id="toggle-round">
<span class="slider round"></span>
</button>

Setting conditions for classList.toggle

I have a function that's triggered by onClick. Here's the example. I want to only be able to trigger the function 'slide1' when 'slide2' is not triggered. I tried setting up a conditional statement like this:
function slide1() {
btn1.classList.toggle('slide', btn2.className != 'slide');
}
I also tried an if statement like this:
function slide1() {
if(btn2.className != 'slide') {
btn1.classList.toggle('slide');
}
}
That didn't work either.
I just need a simple way to toggle classes if certain conditions are met; without jQuery or a library. Thanks.
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
function slide1() {
btn1.classList.toggle('slide');
}
function slide2() {
btn2.classList.toggle('slide');
}
* {
margin: 0;
transition: 1s ease;
-webkit-transition: 1s ease;
}
div {
width: 50%;
height: 100vh;
display: block;
position: absolute;
text-align: center;
cursor: pointer;
}
#btn1 {
background: blue;
}
#btn2 {
background: red;
left: 50%;
}
#btn1.slide {
width: 80%;
z-index: 999;
}
#btn2.slide {
width: 80%;
z-index: 999;
left: 20%;
}
<div id="btn1" onClick="slide1();">
left
</div>
<div id="btn2" onClick="slide2();">
right
</div>
UPDATE: Here is an expanded example of the problem I'm dealing with. There are several elements with classes that need to be toggled only under certain circumstances. If 'panel1' is triggered when 'panel2' has already been triggered, then 'panel1' will cover 'panel2'. and the same with 'panel3'.
To answer your question, the proper way to check if an element has a class in JavaScript is element.classList.contains.
So, in your example, you should replace the condition with
if(btn2.className.contains('slide')) {
...
}
As a sidenote, having different functions doing the exact same thing on different elements should be avoided, where possible. Instead of having two functions, you should have only one and use the click event's target:
let halves = document.querySelectorAll("div");
function slide(event) {
// remove `slide` class from both divs:
[].map.call(halves, function(half){
half.classList.remove('slide');
});
// add `slide` class to currently clicked div:
event.target.classList.add('slide')
}
* {
margin: 0;
transition: 1s ease;
-webkit-transition: 1s ease;
}
div {
width: 50%;
height: 100vh;
display: block;
position: absolute;
text-align: center;
cursor: pointer;
}
#btn1 {
background: blue;
}
#btn2 {
background: red;
left: 50%;
}
#btn1.slide {
width: 80%;
z-index: 999;
}
#btn2.slide {
width: 80%;
z-index: 999;
left: 20%;
}
<div id="btn1" onClick="slide(event);">
left
</div>
<div id="btn2" onClick="slide(event);">
right
</div>
On a different note, I assume you're aware the selectors used in both your question and my answer are outrageously generic and should never be used in production ready code.
And as a last note, your CSS is quite faulty but I'm not considering fixing it here, as it wouldn't help anyone except yourself, which goes against the first principle of SO: one answer should help multiple users having the same problem. Here's how I'd have coded your example:
let br = document.querySelector('#blueRed');
br.addEventListener('click', function(event) {
event.target.classList.toggle('slide');
[].map.call(br.querySelectorAll('div'), function(div) {
if (div !== event.target) {
div.classList.remove('slide');
}
});
})
body {
margin: 0;
}
#blueRed {
height: 100vh;
display: flex;
}
#blueRed div {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
transition: flex-grow 1s cubic-bezier(0.4, 0, 0.2, 1);
flex-grow: 1;
background-color: blue;
color: white;
cursor: pointer;
}
#blueRed div:last-child {
background-color: red;
}
#blueRed div.slide {
flex-grow: 3;
}
<div id="blueRed">
<div>left</div>
<div>right</div>
</div>
Fiddle here. Should be prefixed.
I think I understand your objective...
I condensed the functions into one and start off one button with the className = 'slide'. If one button is clicked then the class slide always alternates between the two buttons.
Demo
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
function slide() {
btn1.classList.toggle('slide');
btn2.classList.toggle('slide');
}
* {
margin: 0;
transition: 1s ease;
-webkit-transition: 1s ease;
}
div {
width: 50%;
height: 100vh;
display: block;
position: absolute;
text-align: center;
cursor: pointer;
}
#btn1 {
background: blue;
}
#btn2 {
background: red;
left: 50%;
}
#btn1.slide {
width: 80%;
z-index: 999;
}
#btn2.slide {
width: 80%;
z-index: 999;
left: 20%;
}
<div id="btn1" onClick="slide();" class='slide'>
left
</div>
<div id="btn2" onClick="slide();">
right
</div>

Why do the changes (to CSS properties) caused by JQuery event handler appear only momentarily?

JSFiddle here.
$(document).ready(function() {
var numberOfItems = $('.item').length;
if (numberOfItems > 4) {
$('.wrapper').mouseover(function() {
$('a.next-arrow').css('display', 'block');
});
$('.wrapper').mouseleave(function() {
$('a.next-arrow').css('display', 'none');
});
}
/**
*
**/
$('a.next-arrow').click(function() {
var i = 1;
while (i <= numberOfItems) { //1, 5
if ($('div.item' + i).css('display').toLowerCase() == 'inline-block') {
$('div.item' + i).css('display', 'none');
break;
}
i = i + 4;
}
});
});
* {
padding: 0px;
border: 0px none;
background: transparent none repeat scroll 0% 0%;
font-size: 100%;
vertical-align: baseline;
}
.wrapper {
position: relative;
white-space: nowrap;
overflow: hidden;
}
div.item {
/*position:absolute;*/
display: inline-block;
width: 25%;
height: 25vw;
}
.wheat {
background-color: wheat;
}
.pink {
background-color: pink;
}
.beige {
background-color: beige;
}
.gainsboro {
background-color: gainsboro;
}
.coral {
background-color: coral;
}
.crimson {
background-color: crimson;
}
.item1 {
left: 0%;
}
.item2 {
left: 25%;
}
.item3 {
left: 50%;
}
.item4 {
left: 75%;
}
.item5 {
left: 100%;
}
.item6 {
left: 125%;
}
.previous-arrow,
.next-arrow {
width: 30px;
height: 50%;
top: 50%;
position: absolute;
display: block;
opacity: 0.7;
/*color: transparent;*/
background-repeat: no-repeat;
margin-top: -30px;
display: none;
}
.previous-arrow {
background-image: url(a2.png);
left: 0px;
}
.next-arrow {
background-image: url(b2.png);
right: 0px;
}
.previous-arrow,
.next-arrow {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<a class="previous-arrow" href=""><</a><!--
--><div class="item item1 wheat">a.</div><!--
--><div class="item item2 pink">a.</div><!--
--><div class="item item3 beige">a.</div><!--
--><div class="item item4 gainsboro">a.</div><!--
--><div class="item item5 coral">a.</div><!--
--><div class="item item6 crimson">a.</div><!--
--><a class="next-arrow" href=""><</a>
</div>
In this SSCCE, I want to use the JQuery to handle the click event on .next-arrow, and in the handler, I want to hide the .item1 (for this example - I have over-simplified to demonstrate my problem). When it is hidden, the .item5 should will into the screen (which was previously overflowed out of the screen).
That does happen, but then:
In the code snippet in SO editor, which can be seen above, it shows only momentarily and then the screen goes blank.
In JSFiddle, linked above, as well as on my computer, it appears only momentarily and then the screen goes back to its initial appearance, that is the .item1 appears again, making the .item4 overflow out of the screen.
I have tried and failed to figure out what is happening. Why is this happening? What am I doing wrong?
If I understand correctly, you just need to prevent the default action of clicking the link (currently it reloads the page).
Pass event (You can use any name) to your function, and use preventDefault().
$('a.next-arrow').click(function(event) {
event.preventDefault();
// etc

Categories