JavaScript事件队列

时间:2013-06-01 18:42:59

标签: javascript events

我正在尝试在JavaScript中实现提升。只是最简单的形式。有几个层次和电梯。当用户点击某个级别时,电梯就在那里。如果用户在电梯仍然到达其第一个目的地时点击几个级别,电梯必须记住级别的位置并按顺序停在每个级别。所以最后我写了一些看起来像工作代码的东西。但我认为逻辑是错误的,因为升力有时会中断其当前动作并转到最终指向的目的地。 这是代码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Lift</title>
    <style>
        * {
            -moz-box-sizing: border-box;
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }

        .building {
            width: 400px;
            height: 600px;
            border: 1px solid #CCC;
            margin: auto auto;
        }

        .floors {
            width: 70%;
            height: 600px;
            border: 1px solid #AAA;
            float: left;
        }

            .floors .level {
                width: 100%;
                height: 100px;
                border-bottom: 1px solid #AAA;
                position: relative;
            }

        .lift-shaft {
            width: 30%;
            height: 600px;
            border: 1px solid #AAA;
            float: right;
            position: relative;
        }

        .lift {
            width: 100%;
            height: 100px;
            border: 1px solid blue;
            position: absolute;
            top: 0;
            left: 0;
            -webkit-transition: all 1s ease-in-out;
            -moz-transition: all 1s ease-in-out;
            -o-transition: all 1s ease-in-out;
            transition: all 1s ease-in-out;
        }
    </style>
</head>
<body>
    <div class="building">
        <div class="floors">
            <div class="level"></div>
            <div class="level"></div>
            <div class="level"></div>
            <div class="level"></div>
            <div class="level"></div>
            <div class="level"></div>
        </div>
        <div class="lift-shaft">
            <div class="lift"></div>
        </div>
    </div>

    <script>

        (function () {

            var levels = document.getElementsByClassName('level'),
                theLift = document.querySelector('.lift'),
                position = {},
                animationInProgress = false;

            Array.prototype.forEach.call(levels, function (elem) {
                elem.addEventListener('click', function (e) {
                    position.top = e.target.getBoundingClientRect().top - 10;
                    animateLift(position.top);
                }, false);
            });

            function animateLift(top) {
                if (animationInProgress) {
                    theLift.addEventListener('webkitTransitionEnd', function (e) {                      
                        e.target.style.top = top + 'px';
                        animationInProgress = false;                    
                    }, true);
                }
                else {
                    theLift.style.top = top + 'px';
                    animationInProgress = true;
                    theLift.addEventListener('webkitTransitionEnd', function (e) {                      
                        e.target.style.top = top + 'px';
                        animationInProgress = false;                    
                    }, true);                   
                }
            }

        })();

    </script>

</body>
</html>

1 个答案:

答案 0 :(得分:2)

您只需在动画结束事件后分配。
处理一个!队列!存储级别选择,并具有:
    1)单击以启动动画或堆叠移动
    2)动画结束触发从队列中取出的下一个动作。

此外,您还必须注意不要求两次相同的位置 将停止动画。我通过存储最后请求的位置来做到这一点, 并忽略请求相同目标位置的点击。

这样的事情很有效:

    (function () {

        var levels = document.getElementsByClassName('level'),
            theLift = document.querySelector('.lift'),
            position = {},
            targetPosition = -1,
            animationInProgress = false;

        var StackOfRequestedLevels=[];

       theLift.addEventListener('webkitTransitionEnd', function (e) {                      
              if (StackOfRequestedLevels.length) 
                  theLift.style.top = StackOfRequestedLevels.shift()  + 'px';
           else
               animationInProgress = false;
                }, true);

        Array.prototype.forEach.call(levels, function (elem) {
       elem.addEventListener('click', function (e) {
              position.top = e.target.getBoundingClientRect().top;
              if ( position.top === targetPosition ) return;
              targetPosition = position.top;
              if (!animationInProgress)   
                    theLift.style.top = position.top + 'px';
              else {
                    StackOfRequestedLevels.push (position.top);
                   }
                animationInProgress=true;
            }, false);

        });

    })();