Reputation: 61
I have a component.vue file which houses an SVG. The animations for the SVG are defined inside the tags of the file. The script code modifies the behavior of the different parts of SVG.
The problem is when the DOM is re-rendered (when I go to another router-link/Page). I start getting
Uncaught ReferenceError: <SVG's part id> is not defined
in the console. The animation code has setInterval
usage. So there are infinite instances of error - unless I refresh the browser or move back to the page (which has the SVG DOM).
export default {
name: "JackHammer",
mounted() {
var funcs = [
"load",
"addEventListener",
"daysLeft",
"getElementById",
"setInterval",
"getTime",
"getTimezoneOffset",
"floor",
"textContent",
];
var daysLeft;
var frameNumber = 0;
var endDate = new Date(2021, 1, 20, 10, 0, 0, 0);
window.addEventListener(
"load",
function () {
initJackhammer();
},
false
);
function initJackhammer() {
daysLeft = document.getElementById(funcs[2]);
ShowTimeLeft();
window.setInterval(ShowTimeLeft, 1000);
var jackhammerTip = document.getElementById("jackhammerTip");
var jackhammer = document.getElementById("jackhammer");
var jackBody = document.getElementById("jackBody");
var jackArms = document.getElementById("jackArms");
setInterval(animateJackhammer, 40);
}
function ShowTimeLeft() {
// if (!document.getElementById("hoursLeft")) {
// return;
// }
var CurrTime = new Date();
var timeDiff = (endDate - CurrTime) / 1000;
var timeDiffInDays = Math.floor(timeDiff / 86400);
timeDiff -= timeDiffInDays * 86400;
var TimeDiffHours = Math.floor(timeDiff / 3600) % 24;
timeDiff -= TimeDiffHours * 3600;
var TimeDiffMinutes = Math.floor(timeDiff / 60) % 60;
timeDiff -= TimeDiffMinutes * 60;
var TimeDiffSeconds = Math.floor(timeDiff % 60);
daysLeft.textContent = timeDiffInDays;
hoursLeft.textContent = TimeDiffHours;
minutesLeft.textContent = TimeDiffMinutes;
secondsLeft.textContent = TimeDiffSeconds;
}
function animateJackhammer() {
// console.log(jackhammerTip)
if (!document.getElementById("jackhammerTip")) {
return;
}
frameNumber++;
jackhammerTip.setAttribute(
"transform",
"translate(0," + (frameNumber % 3) * -3 + ")"
);
jackhammer.setAttribute(
"transform",
"translate(0," + -Math.sin(frameNumber * 1.5) + ")"
);
var jackBodyAmount = Math.sin(frameNumber) + 2;
jackBody.setAttribute(
"transform",
"translate(0," + -jackBodyAmount + ")"
);
jackArms.setAttribute(
"transform",
"translate(0," + -jackBodyAmount + ")"
);
if (frameNumber == 1000) frameNumber = 0;
}
},
};
I am new to Vuejs and JS as a whole. I want to JS code to suspend when the DOM is removed and again start when its rendered again. What can be the most optimized way to achieve this?
Currently, I am just exiting out of the functions if the DOM element does not exist. Would appreciate a better approach.
Upvotes: 0
Views: 397
Reputation: 1578
Assign your interval to a variable and then ClearInterval(variable)
during the beforeUnmount
step.
Eg.:
let myInterval
[...]
mounted() {
myInterval = setInterval(animateJackhammer, 40);
}
[...]
beforeUnmount(() => {
clearInterval(myInterval);
})
Upvotes: 2
Reputation: 421
export default {
name: "JackHammer",
data() {
return {
timer: null,
}
},
beforeDestroy() {
clearInterval(this.timer);
},
mounted() {
var funcs = [
"load",
"addEventListener",
"daysLeft",
"getElementById",
"setInterval",
"getTime",
"getTimezoneOffset",
"floor",
"textContent",
];
var daysLeft;
var frameNumber = 0;
var endDate = new Date(2021, 1, 20, 10, 0, 0, 0);
window.addEventListener(
"load",
initJackhammer.bind(this),
false
);
function initJackhammer() {
daysLeft = document.getElementById(funcs[2]);
ShowTimeLeft();
window.setInterval(ShowTimeLeft, 1000);
var jackhammerTip = document.getElementById("jackhammerTip");
var jackhammer = document.getElementById("jackhammer");
var jackBody = document.getElementById("jackBody");
var jackArms = document.getElementById("jackArms");
this.timer = setInterval(animateJackhammer, 40);
}
function ShowTimeLeft() {
// if (!document.getElementById("hoursLeft")) {
// return;
// }
var CurrTime = new Date();
var timeDiff = (endDate - CurrTime) / 1000;
var timeDiffInDays = Math.floor(timeDiff / 86400);
timeDiff -= timeDiffInDays * 86400;
var TimeDiffHours = Math.floor(timeDiff / 3600) % 24;
timeDiff -= TimeDiffHours * 3600;
var TimeDiffMinutes = Math.floor(timeDiff / 60) % 60;
timeDiff -= TimeDiffMinutes * 60;
var TimeDiffSeconds = Math.floor(timeDiff % 60);
daysLeft.textContent = timeDiffInDays;
hoursLeft.textContent = TimeDiffHours;
minutesLeft.textContent = TimeDiffMinutes;
secondsLeft.textContent = TimeDiffSeconds;
}
function animateJackhammer() {
// console.log(jackhammerTip)
if (!document.getElementById("jackhammerTip")) {
return;
}
frameNumber++;
jackhammerTip.setAttribute(
"transform",
"translate(0," + (frameNumber % 3) * -3 + ")"
);
jackhammer.setAttribute(
"transform",
"translate(0," + -Math.sin(frameNumber * 1.5) + ")"
);
var jackBodyAmount = Math.sin(frameNumber) + 2;
jackBody.setAttribute(
"transform",
"translate(0," + -jackBodyAmount + ")"
);
jackArms.setAttribute(
"transform",
"translate(0," + -jackBodyAmount + ")"
);
if (frameNumber == 1000) frameNumber = 0;
}
},
};
Upvotes: 0