0

I am working on a slideshow in which my solution is add a class to a slide every interval. After that, I check if the animation is end then remove the class and set the slide's display to none.

However, in order to support old browsers, I have to add prefixes to these events, so I wrote my own function to control the prefixes and check if the events are fired. Below is my code:

// JavaScript Document
"use strict";
window.addEventListener('load', function(){
    /*Declaring variables*/
    var slideContainer = document.getElementsByClassName('slider-wrapper')[0],
        slidesList = document.getElementsByClassName('slide'),
        currSlide = 0,
        waitdur = slideContainer.children[0].getAttribute('data-waitdur'),
        canNavigate = true;

/*Fix javascript mod bug*/
Number.prototype.mod = function(n) {
    return ((this % n) + n) % n;
};

/*Initialize slides' settings*/
function slideInit() {
    for (var i = 0; i < slidesList.length; i ++) {
        slidesList[i].style.display = "none";
    }
    slidesList[currSlide].style.display = "block";
}

/*Set container height*/
function setContainerHeight() {
    var activeWidth = 0;
    for (var i = 0; i < slidesList.length; i ++) {
        if (slidesList[i].style.display === "block") {
            activeWidth = slidesList[i].clientHeight;
        }
    }
    return activeWidth;
}

/*Main function for animation events' prefixes short writting*/
function prefixedAnimation(el, type, callback) {
    var prf = ['webkit', 'moz', 'o', ''];
    for (var i = 0; i < prf.length; i ++) {
        var animation;
        if (prf[i] === '') {
            animation = type.toLowerCase();
        }
        else {
            animation = prf[i] + type;
        }
        el.addEventListener(animation, function(){ callback(this); }, false);
    }
}

/*Control the slide movement (left, right)*/
function slideController(currEl, nextEl, dir) {
    if (dir === "next") {
        currEl.classList.add('slideOutL');
        nextEl.classList.add('slideInL');
    }
    else if (dir === "prev") {
        currEl.classList.add('slideOutR');
        nextEl.classList.add('slideInR');
    }
    prefixedAnimation(currEl, "AnimationStart", function(el){ el = null; canNavigate = false; });
    prefixedAnimation(currEl, "AnimationEnd", function(el) {
        canNavigate = true;
        if (el.classList.contains('slideOutL')) {
            el.classList.remove('slideOutL');
        }
        else if (el.classList.contains('slideOutR')) {
            el.classList.remove('slideOutR');
        }
        el.style.display = "none";
    });
    prefixedAnimation(nextEl, "AnimationStart", function(el) {
        el.style.display = "block";
    });
    prefixedAnimation(nextEl, "AnimationEnd", function(el) {
        if (el.classList.contains('slideInL')) {
            el.classList.remove('slideInL');
        }
        else if (el.classList.contains('slideInR')) {
            el.classList.remove('slideInR');
        }
        el.style.display = "block";
    });
}

/*Auto run slide function, this is where the problem occurs, same event are being fired several times, in the setInterval function*/
function runSlideAuto() {
    var currEl, nextEl;
    setInterval(function(){
        currEl = slidesList[currSlide];
        nextEl = slidesList[(currSlide + 1).mod(slidesList.length)];
        slideController(currEl, nextEl, "next");
        currSlide = (currSlide + 1).mod(slidesList.length);
    }, waitdur);
}

//Main
slideInit();
runSlideAuto();
setInterval(function(){
    slideContainer.style.height = setContainerHeight() + 'px';
}, 1);
});

However, in the setInterval function, the events are fired several times, which may slow down the website. Can someone help me with this issue please? I think the problem may be in the prefixes function, since I don't have any idea for this.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
WebDeg Brian
  • 802
  • 1
  • 7
  • 21
  • You appear to be adding more and more event listeners every time the slide changes. Without rewriting this example entirely, I'd say you need to find a way to check whether (1) you need to add an event rather than just executing the callback, or (2) you can test if the the event listener has already been added and don't add it again. I think the slowness is that the number of animations increases after each slide change. – Cᴏʀʏ Nov 27 '17 at 18:30
  • @Cᴏʀʏ Can I add a class each time an event is being executed and check if the class is exists when I want to add a new event? – WebDeg Brian Nov 27 '17 at 18:31
  • Yeah, you could do that. Or other things mentioned over at https://stackoverflow.com/questions/11455515/how-to-check-whether-dynamically-attached-event-listener-exists-or-not. Or another option would be to add a data attribute to the element. I think you need to decide whether a called to `prefixedAnimation` is required or if you just need to run the callback portion. – Cᴏʀʏ Nov 27 '17 at 21:47

0 Answers0