admin管理员组文章数量:1221774
such a situation:
1 background layer, 4 pictures that should replace each other in this background layer – in a time interval (4 sec) with a soft transition (1,5 sec), and 4 links/buttons which should trigger the necessary picture background on mouseover. The changed background should stay until the mouse leaves the button.
The problem: if I bring the mouse over a link while a transition (no matter how it's triggered), the called background picture is set straight away and by a hard transition. How to prevent it?
I'm gonna put here shortened code where only the relevant things are:
HTML:
<div class="bg-image" id="bg-image-de-de"></div>
<a class="experience-now" data-lang="DE" id="sphere1" onmouseover="imageOne();" onmouseleave="backToChangeBG();">Image 01</a>
<a class="experience-now" data-lang="DE" id="sphere2" onmouseover="imageTwo();" onmouseleave="backToChangeBG();">Image 02</a>
<a class="experience-now" data-lang="DE" id="sphere3" onmouseover="imageThree();" onmouseleave="backToChangeBG();">Image 03</a>
<a class="experience-now" data-lang="DE" id="sphere4" onmouseover="imageFour();" onmouseleave="backToChangeBG();">Image 04</a>
CSS:
.bg-image {
background-image: url(../_img/Picture1.jpg);
transition-duration: 1500ms !important;
transition-property: background-image;
width: 100%;
height: calc(100% - 50px);
background-position: top center;
background-repeat: repeat-y;
background-size: cover;
background-blend-mode: normal;
background-color: #e6e6eb;
position: fixed;
}
JS:
var interval = 4;
var bilderurl = new Array("_assets/_img/Picture1.jpg", "_assets/_img/Picture2.jpg", "_assets/_img/Picture3.jpg", "_assets/_img/Picture4.jpg");
var bilder = new Array();
let element = document.getElementById("bg-image-de-de");
for (i = 0; i < bilderurl.length; i++)
{
bilder[i] = new Image;
bilder[i].src = bilderurl[i];
}
i = 0;
function changebg()
{
i++;
if (i == bilderurl.length) i = 0;
element.style.backgroundImage = "url(" + bilderurl[i] + ")";
}
window.setInterval("changebg()", 1000 * interval);
function imageOne() {
element.style.backgroundImage = "url(_assets/_img/Picture1.jpg)";
element = null;
};
function imageTwo() {
element.style.backgroundImage = "url(_assets/_img/Picture2.jpg)";
element = null;
};
function imageThree() {
element.style.backgroundImage = "url(_assets/_img/Picture3.jpg)";
element = null;
};
function imageFour() {
element.style.backgroundImage = "url(_assets/_img/Picture4.jpg)";
element = null;
};
function backToChangeBG() {
element = document.getElementById("bg-image-de-de");
};
Please help me, it really should be possible. Thankx in previous. Yours, Peter
such a situation:
1 background layer, 4 pictures that should replace each other in this background layer – in a time interval (4 sec) with a soft transition (1,5 sec), and 4 links/buttons which should trigger the necessary picture background on mouseover. The changed background should stay until the mouse leaves the button.
The problem: if I bring the mouse over a link while a transition (no matter how it's triggered), the called background picture is set straight away and by a hard transition. How to prevent it?
I'm gonna put here shortened code where only the relevant things are:
HTML:
<div class="bg-image" id="bg-image-de-de"></div>
<a class="experience-now" data-lang="DE" id="sphere1" onmouseover="imageOne();" onmouseleave="backToChangeBG();">Image 01</a>
<a class="experience-now" data-lang="DE" id="sphere2" onmouseover="imageTwo();" onmouseleave="backToChangeBG();">Image 02</a>
<a class="experience-now" data-lang="DE" id="sphere3" onmouseover="imageThree();" onmouseleave="backToChangeBG();">Image 03</a>
<a class="experience-now" data-lang="DE" id="sphere4" onmouseover="imageFour();" onmouseleave="backToChangeBG();">Image 04</a>
CSS:
.bg-image {
background-image: url(../_img/Picture1.jpg);
transition-duration: 1500ms !important;
transition-property: background-image;
width: 100%;
height: calc(100% - 50px);
background-position: top center;
background-repeat: repeat-y;
background-size: cover;
background-blend-mode: normal;
background-color: #e6e6eb;
position: fixed;
}
JS:
var interval = 4;
var bilderurl = new Array("_assets/_img/Picture1.jpg", "_assets/_img/Picture2.jpg", "_assets/_img/Picture3.jpg", "_assets/_img/Picture4.jpg");
var bilder = new Array();
let element = document.getElementById("bg-image-de-de");
for (i = 0; i < bilderurl.length; i++)
{
bilder[i] = new Image;
bilder[i].src = bilderurl[i];
}
i = 0;
function changebg()
{
i++;
if (i == bilderurl.length) i = 0;
element.style.backgroundImage = "url(" + bilderurl[i] + ")";
}
window.setInterval("changebg()", 1000 * interval);
function imageOne() {
element.style.backgroundImage = "url(_assets/_img/Picture1.jpg)";
element = null;
};
function imageTwo() {
element.style.backgroundImage = "url(_assets/_img/Picture2.jpg)";
element = null;
};
function imageThree() {
element.style.backgroundImage = "url(_assets/_img/Picture3.jpg)";
element = null;
};
function imageFour() {
element.style.backgroundImage = "url(_assets/_img/Picture4.jpg)";
element = null;
};
function backToChangeBG() {
element = document.getElementById("bg-image-de-de");
};
Please help me, it really should be possible. Thankx in previous. Yours, Peter
Share Improve this question edited Feb 7 at 15:59 Peter asked Feb 7 at 15:55 PeterPeter 112 bronze badges2 Answers
Reset to default 0The transitions aren't perfect so you'll probably need to fine tune it. background-image
is janky, it's easier to use an <img>
. Details are commented in the example.
// Define global variables
let tick = null;
let idx = 0;
let int = 4000;
// Array of image urls
const pix = ["https://i.ibb.co/bBGX3Sq/static.gif", "https://i.ibb.co/c1PtcM7/matrix1.gif", "https://i.ibb.co/FHRS8Gx/stars.gif", "https://i.ibb.co/wc356r0/atat.gif"];
// Reference <html>
const root = document.documentElement;
// Reference <img>
const img = document.images[0];
// Reference <section>
const sec = document.querySelector("section");
// Reference <nav>
const nav = document.querySelector("nav");
// Array of <a>
const lnx = Array.from(document.links);
// Initial fadeOut and auto image change
setTimeout(fadeOut, 2500);
tick = setInterval(next, int);
/**
* This function moves the images forward.
*/
function next() {
fadeIn();
setTimeout(fadeOut, 2000);
idx++;
if (idx >= pix.length) {
idx = 0;
}
setImg(idx);
}
/**
* This function sets the src of <img>
*/
function setImg() {
img.src = pix[idx];
}
/**
* This function fades <section> in.
*/
function fadeIn() {
sec.classList.remove("fade");
}
/**
* This function fades <section> out.
*/
function fadeOut() {
sec.classList.add("fade");
}
/**
* This function changes transition duration of
* fading animation from 3.5s to 0.5s.
*/
function blink() {
root.style.setProperty("--time", "0.5s");
}
/**
* This function changes transition duration of
* fading animation from 0.5s to 3.5s.
*/
function unblink() {
root.style.setProperty("--time", "3.5s");
}
/**
* "pointerenter" event handler disables the setInterval()
* function when the user moves the pointer into
* <nav>.
* @param {object} e - Event object
*/
nav.onpointerenter = function(e) {
clearInterval(tick);
setTimeout(fadeIn, 500);
};
/**
* "pointerleave" event handler enables setInterval()
* function when the user moves the pointer out
* of <nav>.
* @param {object} e - Event object
*/
nav.onpointerleave = function(e) {
setTimeout(fadeIn, 100);
tick = setInterval(next, int);
setTimeout(fadeOut, 100);
unblink();
};
/**
* Each <a> is registered to the "pointerenter"
* event. Event handler hoverLink() is called
* when the user moves the pointer into an <a>.
*/
lnx.forEach(l => {
l.onpointerenter = hoverLink;
});
/**
* "pointerenter" event handler for each <a>.
* When the user moves the pointer into an <a>
* The corresponding image appears.
* @param {object} e - Event object
*/
function hoverLink(e) {
blink();
idx = lnx.indexOf(this);
setTimeout(fadeOut, 0);
setTimeout(setImg, 500);
setTimeout(fadeIn, 750);
}
:root {
/* This custom property is the transition
* durtion for the fading animation.
*/
--time: 3.5s;
font: 2ch/1.5 "Segoe UI"
}
main {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
margin: 0.5rem auto;
background: #000;
}
section {
width: 100%;
aspect-ratio: 16 / 9;
background: #000;
opacity: 1;
transition: opacity var(--time);
}
nav {
padding: 5px 10px;
border: 1.5px grey solid;
}
img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: contain
}
a {
display: inline-block;
}
a+a {
margin-left: 0.5rem;
}
/**
* This class is the trigger for all fading
* animations.
*/
.fade {
opacity: 0;
}
<main>
<section>
<img src="https://i.ibb.co/bBGX3Sq/static.gif">
</section>
<nav>
<a href="#">Image 01</a>
<a href="#">Image 02</a>
<a href="#">Image 03</a>
<a href="#">Image 04</a>
</nav>
</main>
The following snippet attempts to capture the essence of your problem. It transitions between two background colors depending on which radio button is pressed.
But the color is not immediately applied in the event handler. Instead, a color
variable is updated with the desired color, and this is applied only
- if there is no transition running
- or when the transition has ended.
If you switch back and forth between the radio buttons while a transition is running, only the last color will be applied.
let color;
window.addEventListener("transitionstart", function() {
d.className = 'transition';
});
window.addEventListener("transitionend", function() {
d.className = '';
d.style.backgroundColor = color;
});
function setColor(c) {
color = c;
if (d.className === '') d.style.backgroundColor = color;
}
div {
height: 8em;
border: solid 3px transparent;
transition: background-color 1500ms;
}
div.transition {
border-color: black;
}
<div id="d"></div>
<label><input type="radio" name="color" onclick="setColor('red')">Red</label><br>
<label><input type="radio" name="color" onclick="setColor('white')">White</label>
版权声明:本文标题:javascript - How to prevent CSS transitions from interrupting each other by any JS triggers? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1739308163a2157457.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论