Модуль анимации перестает работать правильно, если класс анимации не уникален на странице - PullRequest
1 голос
/ 24 сентября 2019

Я написал простой модуль для применения классов css из библиотеки animate.css. Классы определены в атрибуте data элемента html, но по какой-то причине все анимации работают, только если они уникальны на странице, в противном случае реализована анимациятолько до последнего элемента с его классом.

Upd.Отладчик в 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

1 Ответ

0 голосов
/ 24 сентября 2019

После этого у меня возникли небольшие проблемы, но я готов поспорить, что это что-то специфичное для объекта, которое пишется в window.onscroll

Удачи!

...