0

我正在尝试在 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>
4

1 回答 1

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);

        });

    })();
于 2013-06-01T19:39:34.417 回答