间隔和点击功能问题

时间:2018-05-31 11:39:35

标签: javascript jquery

我正在做一个项目,我们必须提出一个游戏,广场将根据math.random改变位置

我有两个问题

  1. 似乎它正在运行该函数的多个实例,因为在正方形重新定位的几个周期之后 - 它会变得疯狂并且在整个地方移动似乎是随机的间隔。

  2. 第二个问题是,我第二次点击它时,很难让方格div注册。

  3. 链接到JSFiddle:https://jsfiddle.net/ybpdjujb/

    $(document).ready(function test() {
        $(document).on('click', '#target', function clicker() {
            $('#target').css('left', randPosX);
            $('#target').css('top', randPosY);
            clearInterval(fire)
            timeLeft = 2;
        });
    
        //Random
        var bodyWidth = $("#playArea").width();
        var bodyHeight = $("#playArea").height();
        var randPosX = Math.floor((Math.random() * bodyWidth / 1.1));
        var randPosY = Math.floor((Math.random() * bodyHeight / 1.1));
    
        //TIMER
        var timeLeft = 2;
        var elem = document.getElementById('time');
        var timerId = setInterval(countdown, 1000);
    
        function countdown() {
            if (timeLeft == 0) {
                doSomething();
                timeLeft = 5;
            } else {
                elem.innerHTML = timeLeft + ' seconds remaining';
                timeLeft--;
            }
        }
    
        function doSomething() {
            $('#target').css('left', randPosX);
            $('#target').css('top', randPosY);
            clearInterval(timerId);
        }
    
        var fire = setInterval(test, 2000);
    });
    

1 个答案:

答案 0 :(得分:0)

TL; DR :广场正在疯狂的原因是你在两个地方做setInterval()。您执行var fire = setInterval(test, 2000);的地方和执行var timerId = setInterval(countdown, 1000);的地方之一。删除其中一个(并修复一些其他的东西),你的代码就开始工作了。

但是,我们并不想停在那里,如果结构不正确,工作代码很快就会变得难以修改。因此,为了您和程序员社区的利益,让我们看看我们如何重构这些代码。我相信这对未来的编码(和调试)练习很有用。如果这已经是您的常识,请考虑这是一个复习:)

第1步:只添加 document.ready

中的内容

这是一个简单的问题。文档准备好后你想做什么? 三个的事情

  1. 显示正方形
  2. 设置onclick处理程序
  3. 启动计时器
  4. 让我们只保留那些并将其余部分移到document.ready区块之外。你正确完成的一件事是评论你认为应该放在一起的代码区域,让它们转换成函数!在执行此操作时,我们会注意到文件末尾的杂散setInterval(),我们可以将其删除。 您的代码现在应该如下所示(重构已完成,如下所述):

    function doSomething() {
        positionSquareRandomly();
        clearInterval(timerId);
        timeLeft = 2;
        startTimer();
    }
    
    function positionSquareRandomly(){
        var bodyWidth = $("#playArea").width();
        var bodyHeight = $("#playArea").height();
        var randPosX = Math.floor((Math.random() * bodyWidth / 1.1));
        var randPosY = Math.floor((Math.random() * bodyHeight / 1.1));
        $('#target').css('left', randPosX);
        $('#target').css('top', randPosY);
    }
    
    function startTimer(){
        var timeLeft = 2;
        var elem = document.getElementById('time');
        var timerId = setInterval(countdown, 1000);
    }
    
    function countdown() {
        if (timeLeft == 0) {
            doSomething();
        } else {
            elem.innerHTML = timeLeft + ' seconds remaining';
            timeLeft--;
        }
    }
    
    function clicker() {
        doSomething();
    }
    
    $(document).ready(function test() {
        //Display square
        positionSquareRandomly();
    
        // Setup timer
        startTimer();
    
        // Setup click handler
        $(document).on('click', '#target', clicker);
    
    });
    

    第2步:重构我

    1. positionSquareRandomly()应该得到坐标显示正方形。因此,我们将$('#target').css(..)调用移至该方法
    2. 现在,当我们这样做时,clicker()doSomething()看起来非常相似,所以clicker()现在调用doSomething(),然后调整timeLeft,然后定位方块并重置计时器,即清除间隔,重置startTimer()并致电clearInterval(fire)
    3. timeLeft = 5因不需要而消失。 Uncaught ReferenceError: timeLeft is not defined也已消失。
    4. 第3步:重构II

      很好,但现在我们发现没有任何反应!按 F12 打开开发者控制台,单击控制台选项卡。我看到的错误是timeLeft。这是因为在startTimer()中声明了countdown(),但我们也试图在timeLeft中使用它。我们通过在所有函数上声明var elem(使其成为全局函数)来解决这个问题。

      同样,将var timerId = 0声明置于顶部。

      在顶部声明setInterval()elem.innerHTML返回的ID始终为非零,因此这是一个很好的初始值。 (Set timeout example

      那就是它!在倒计时的if部分添加一些有用的var timeLeft = 2; var elem = document.getElementById('time'); var timerId = 0; function doSomething() { positionSquareRandomly(); clearInterval(timerId); timeLeft = 2; startTimer(); } function positionSquareRandomly(){ var bodyWidth = $("#playArea").width(); var bodyHeight = $("#playArea").height(); var randPosX = Math.floor((Math.random() * bodyWidth / 1.1)); var randPosY = Math.floor((Math.random() * bodyHeight / 1.1)); $('#target').css('left', randPosX); $('#target').css('top', randPosY); } function startTimer(){ timerId = setInterval(countdown, 1000); } function countdown() { if (timeLeft == 0) { elem.innerHTML = '0 seconds remaining'; doSomething(); } else { elem.innerHTML = timeLeft + ' seconds remaining'; timeLeft--; } } function clicker() { doSomething(); } $(document).ready(function test() { //Display square positionSquareRandomly(); // Setup timer startTimer(); // Setup click handler $(document).on('click', '#target', clicker); }); ,我们就会得到此代码。

      body {
        height: 100vh;
        margin: 0;
        display: flex;
        background: grey;
      }
      
      .left {
        flex: 1;
        border-right: 1px solid #eeeeee;
        background-color: lightblue;
      }
      
      .right {
        flex: 4;
        margin-top: 45px;
        margin-right: 30px;
        background-color: yellow;
      }

      我们可以做的更多事情,但现在我相信代码清晰,简洁,最重要的是,可维护。