我编写了一个简单的模块来应用 animate.css 库中的 css 类。类在 html 元素数据属性中定义,但出于某种原因,所有动画仅在页面上唯一时才有效,否则将实现动画仅到具有它的类的最后一个元素。
更新。 devtools 中的调试器显示模块遍历每个节点,但仍仅将非唯一动画应用于最后一个节点。
例子:
<h2 id="1" class="module_animate-box" data-animate-trigger="scroll" data-animate-script='{"class":"zoomIn","position":"700"}'>Hello</h2>
<h2 id="2" class="module_animate-box" data-animate-trigger="scroll" data-animate-script='{"class":"zoomIn","position":"1000"}'>World</h2>
如果您在页面上两次使用类“zoomIn”,则只有 id="2"会起作用。
import "./animate.css";
//check full list of availiable classes here: https://github.com/daneden/animate.css/blob/master/README.md
export default class animationModule {
constructor({
selector
}) {
this.selector = selector;
this.nodes = Array.from(document.querySelectorAll(selector));
this.init();
}
getCoords(e) {//get coords of an element
let coords = e.getBoundingClientRect();
return coords;
}
getTriggerEvent(e){//get the appropriate function by it's trigger type
switch(e.dataset.animateTrigger){
case "scroll":
return this.onScroll
break;
case 'hover':
return this.onHover
break;
case 'moved':
return this.onMouseMove//sort of parallax
default:
return "loaded"
}
}
onScroll(e,repeats,animationTriggerYOffset,isOutOfViewport,animationType){//if trigger === scroll
e.style.animationIterationCount = repeats;//set iteration limits of animation
window.onscroll= function(){
(window.pageYOffset >= animationTriggerYOffset && !(window.pageYOffset > isOutOfViewport.bottom)) ?//check if target el is in the trigger position and not out of the viewport
e.classList.add('animated', 'infinite', animationType.class) ://toggles on classes if everything is ok
e.classList.remove('animated', 'infinite', animationType.class)// toggles off classes if lower the defined trigger position or out of viewport
repeats = e.dataset.animateRepeat;//reset iteration for animation
}
}
onHover(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType){//if trigger === hover
e.style.animationIterationCount = repeats;//set iteration for animation
e.addEventListener('mousemove', ()=> {
e.classList.add('animated', 'infinite', animationType.class);
})
e.addEventListener('animationend', function () {//resets animation iteration
e.classList.remove('animated', 'infinite', animationType.class)
})
}
onMouseMove(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType){
//in data-animate-script set values{"pageX":"#","pageY": "#"} the less the number the bigger the amplitude. negative numbers reverse the movement
window.addEventListener('mousemove',(m) => {
e.style.transform = `translate(${m.pageX * -1 / animationType.pageX}px, ${m.pageY * -1 / animationType.pageY}px)`
})
}
init() {
this.nodes.forEach(e => {
console.log(e.dataset)
let animationType = JSON.parse(e.dataset.animateScript);//define class name of animation needed to apply
let repeats = e.dataset.animateRepeat || 'infinite';//define number of iterations for animation (INFINITE by default)
let animationTriggerYOffset = animationType.position || 0;//defines YOffset to trigger animation(0 by default)
let isOutOfViewport = this.getCoords(e);//sets coords of an element from getCoords function
let action = this.getTriggerEvent(e);//get appropriate function depending on data-animate-trigger value
action(e, repeats, animationTriggerYOffset, isOutOfViewport, animationType);//call appropriate function per each node
})
}
}
// Module data and attributes
// .module_animate-box - class that defines animation target
// data-animate-trigger - animation trigger(possible values: "scroll", "hover", "moved"(watches mouse movement))
// data-animate-repeat - number of repetitions (infinite by default)
// data-animate-script - JSON description of animation. example: '{"class":"wobble","position":"300"}' - will add class wobble when pageYoffset===300
最佳答案
我在下面遇到了一些麻烦,但我敢打赌这是在 window.onscroll 中编写的特定对象
祝你好运!
关于javascript - 如果页面上的动画类不是唯一的,动画模块将停止正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58079541/