Как остановить функцию JS с помощью mouseout?
Есть функция makeItRain, которая создаёт эффект дождя на странице при её вызове. Есть две кнопки в виде ссылок, на которые при наведении должна вызываться функция makeItRain, а при отведении заканчивается. При наведении никаких проблем не возникло, но makeItRain после отведения мыши от кнопок не останавливается. Для этих целей я использовал mouseover и mouseout, также пробовал использовать setInterval.
let makeItRain = function () {
$(".rain").empty();
let increment = 0;
let drops = "";
let backDrops = "";
while (increment < 100) {
let randoHundo = Math.floor(Math.random() * (98 - 1 + 1) + 1);
let randoFiver = Math.floor(Math.random() * (5 - 2 + 1) + 2);
increment += randoFiver;
drops +=
'<div class="drop" style="left: ' +
increment +
"%; bottom: " +
(randoFiver + randoFiver - 1 + 100) +
"%; animation-delay: 0." +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"><div class="stem" style="animation-delay: 0.' +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"></div><div class="splat" style="animation-delay: 0.' +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"></div></div>';
backDrops +=
'<div class="drop" style="right: ' +
increment +
"%; bottom: " +
(randoFiver + randoFiver - 1 + 100) +
"%; animation-delay: 0." +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"><div class="stem" style="animation-delay: 0.' +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"></div><div class="splat" style="animation-delay: 0.' +
randoHundo +
"s; animation-duration: 0.5" +
randoHundo +
's;"></div></div>';
}
$(".rain.front-row").append(drops);
$(".rain.back-row").append(backDrops);
};
document.addEventListener("mouseover", startInterval);
document.addEventListener("mouseout", stopInterval);
let timer = null;
function startInterval() {
timer = setInterval(document.addEventListener("mouseover", (event) => {
if (event.target.tagName.toLowerCase() === 'a' ||
event.target.tagName.toLowerCase() === 'p') {
makeItRain();
}
}, 1000));
}
function stopInterval() {
document.addEventListener("mouseout", (event) => {
if (event.target.tagName.toLowerCase() === 'a' ||
event.target.tagName.toLowerCase() === 'p' ) {
/* Здесь я пытался разными способами остановить функцию makeItRain */
}
});
}
<body class="back-row-toggle splat-toggle">
<div class="rain front-row"></div>
<div class="rain back-row"></div>
<div class="toggles">
</div>
<div class="container">
<header>
<h1>BEST</h1>
</header>
<div class="btns">
<a id="first" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some<br>Thing</p>
</a>
<a id="second" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some</p>
</a>
</div>
</div>
<script src="west.js"></script>
</body>
Ответы (1 шт):
Автор решения: Rudi
→ Ссылка
Код для запуска дождя по наведению и остановке по отведению мыши
var makeItRain = function(off) {
if(off) return $('.rain').empty();
var increment = 0;
var drops = "";
var backDrops = "";
while (increment < 100) {
var randoHundo = (Math.floor(Math.random() * (98 - 1 + 1) + 1));
var randoFiver = (Math.floor(Math.random() * (5 - 2 + 1) + 2));
increment += randoFiver;
drops += '<div class="drop" style="left: ' + increment + '%; bottom: ' + (randoFiver + randoFiver - 1 + 100) + '%; animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"><div class="stem" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"></div><div class="splat" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"></div></div>';
backDrops += '<div class="drop" style="right: ' + increment + '%; bottom: ' + (randoFiver + randoFiver - 1 + 100) + '%; animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"><div class="stem" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"></div><div class="splat" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"></div></div>';
}
$('.rain.front-row').append(drops);
$('.rain.back-row').append(backDrops);
}
let el = document.getElementsByTagName("a");
for(var i = 0; i < el.length; i++){
el[i].addEventListener('mouseover',()=>{ makeItRain(); });
el[i].addEventListener('mouseout',()=>{ makeItRain(1); });
}
body{
background:black;
}
.container{
position:relative;
color: white;
z-index:999;
}
.btns{
width: fit-content;
}
/*Стили выше добавил*/
.rain {
margin-top: -180px;
position: absolute;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.rain.back-row {
display: none;
z-index: 1;
bottom: 60px;
opacity: 0.5;
}
.back-row-toggle .rain.back-row {
display: block;
}
.drop {
position: absolute;
bottom: 100%;
width: 15px;
height: 120px;
pointer-events: none;
animation: drop 0.5s linear infinite;
}
@keyframes drop {
0% {
transform: translateY(0vh);
}
75% {
transform: translateY(90vh);
}
100% {
transform: translateY(90vh);
}
}
.stem {
width: 1px;
height: 60%;
margin-left: 7px;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.25));
animation: stem 0.5s linear infinite;
}
@keyframes stem {
0% {
opacity: 1;
}
65% {
opacity: 1;
}
75% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.splat {
width: 15px;
height: 10px;
border-top: 2px dotted rgba(255, 255, 255, 0.5);
border-radius: 50%;
opacity: 1;
transform: scale(0);
animation: splat 0.5s linear infinite;
display: none;
}
.splat-toggle .splat {
display: block;
}
@keyframes splat {
0% {
opacity: 1;
transform: scale(0);
}
80% {
opacity: 1;
transform: scale(0);
}
90% {
opacity: 0.5;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.5);
}
}
.toggles {
position: absolute;
top: 0;
left: 0;
z-index: 3;
}
.toggle {
position: absolute;
left: 20px;
width: 50px;
height: 50px;
line-height: 51px;
box-sizing: border-box;
text-align: center;
font-family: sans-serif;
font-size: 10px;
font-weight: bold;
background-color: rgba(255, 255, 255, 0.2);
color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
cursor: pointer;
transition: background-color 0.3s;
}
.toggle:hover {
background-color: rgba(255, 255, 255, 0.25);
}
.toggle:active {
background-color: rgba(255, 255, 255, 0.3);
}
.toggle.active {
background-color: rgba(255, 255, 255, 0.4);
}
.splat-toggle {
top: 20px;
}
.back-row-toggle {
top: 90px;
line-height: 12px;
padding-top: 14px;
}
.single-toggle {
top: 160px;
}
.single-toggle .drop {
display: none;
}
.single-toggle .drop:nth-child(10) {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="toggles">
</div>
<div class="container">
<header>
<h1>BEST</h1>
</header>
<div class="btns">
<a id="first" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some<br>Thing</p>
</a>
<a id="second" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some</p>
</a>
<a id="next" href="">
<p>Some</p>
</a>
</div>
</div>
<div class="back-row-toggle splat-toggle">
<div class="rain front-row"></div>
<div class="rain back-row"></div>
</div>
</body>
Решил переписать без jQuery т.к. считаю не оправданным подключать библиотеку исключительно из-за этой анимации.
var makeItRain = function(off) {
if(off) {
document.querySelector('.rain.front-row').innerHTML="";
document.querySelector('.rain.back-row').innerHTML="";
return
}
var increment = 0;
var drops = "";
var backDrops = "";
while (increment < 100) {
var randoHundo = (Math.floor(Math.random() * (98 - 1 + 1) + 1));
var randoFiver = (Math.floor(Math.random() * (5 - 2 + 1) + 2));
increment += randoFiver;
drops += '<div class="drop" style="left: ' + increment + '%; bottom: ' + (randoFiver + randoFiver - 1 + 100) + '%; animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"><div class="stem" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"></div><div class="splat" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.2' + randoHundo + 's;"></div></div>';
backDrops += '<div class="drop" style="right: ' + increment + '%; bottom: ' + (randoFiver + randoFiver - 1 + 100) + '%; animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"><div class="stem" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"></div><div class="splat" style="animation-delay: 0.' + randoHundo + 's; animation-duration: 0.5' + randoHundo + 's;"></div></div>';
}
document.querySelector('.rain.front-row').insertAdjacentHTML("beforeend",drops);
document.querySelector('.rain.back-row').insertAdjacentHTML("beforeend",backDrops);
}
let el = document.getElementsByTagName("a");
for(var i = 0; i < el.length; i++){
el[i].addEventListener('mouseover',()=>{ makeItRain() });
el[i].addEventListener('mouseout',()=>{ makeItRain(1) });
}
body{
background:black;
}
.container{
position:relative;
color: white;
z-index:999;
}
.btns{
width: fit-content;
}
/*Стили выше добавил*/
.rain {
margin-top: -180px;
position: absolute;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.rain.back-row {
display: none;
z-index: 1;
bottom: 60px;
opacity: 0.5;
}
.back-row-toggle .rain.back-row {
display: block;
}
.drop {
position: absolute;
bottom: 100%;
width: 15px;
height: 120px;
pointer-events: none;
animation: drop 0.5s linear infinite;
}
@keyframes drop {
0% {
transform: translateY(0vh);
}
75% {
transform: translateY(90vh);
}
100% {
transform: translateY(90vh);
}
}
.stem {
width: 1px;
height: 60%;
margin-left: 7px;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.25));
animation: stem 0.5s linear infinite;
}
@keyframes stem {
0% {
opacity: 1;
}
65% {
opacity: 1;
}
75% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.splat {
width: 15px;
height: 10px;
border-top: 2px dotted rgba(255, 255, 255, 0.5);
border-radius: 50%;
opacity: 1;
transform: scale(0);
animation: splat 0.5s linear infinite;
display: none;
}
.splat-toggle .splat {
display: block;
}
@keyframes splat {
0% {
opacity: 1;
transform: scale(0);
}
80% {
opacity: 1;
transform: scale(0);
}
90% {
opacity: 0.5;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.5);
}
}
.toggles {
position: absolute;
top: 0;
left: 0;
z-index: 3;
}
.toggle {
position: absolute;
left: 20px;
width: 50px;
height: 50px;
line-height: 51px;
box-sizing: border-box;
text-align: center;
font-family: sans-serif;
font-size: 10px;
font-weight: bold;
background-color: rgba(255, 255, 255, 0.2);
color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
cursor: pointer;
transition: background-color 0.3s;
}
.toggle:hover {
background-color: rgba(255, 255, 255, 0.25);
}
.toggle:active {
background-color: rgba(255, 255, 255, 0.3);
}
.toggle.active {
background-color: rgba(255, 255, 255, 0.4);
}
.splat-toggle {
top: 20px;
}
.back-row-toggle {
top: 90px;
line-height: 12px;
padding-top: 14px;
}
.single-toggle {
top: 160px;
}
.single-toggle .drop {
display: none;
}
.single-toggle .drop:nth-child(10) {
display: block;
}
<body>
<div class="toggles">
</div>
<div class="container">
<header>
<h1>BEST</h1>
</header>
<div class="btns">
<a id="first" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some<br>Thing</p>
</a>
<a id="second" href="">
<span></span>
<span></span>
<span></span>
<span></span>
<p>Some</p>
</a>
<a id="next" href="">
<p>Some</p>
</a>
</div>
</div>
<div class="back-row-toggle splat-toggle">
<div class="rain front-row"></div>
<div class="rain back-row"></div>
</div>
</body>