簡體   English   中英

調試一個簡單的Javascript錯誤

[英]Debugging a simple Javascript error

我試圖使用java腳本向下移動帶有Id(topleft)的div容器,但我的java腳本代碼有問題。 從邏輯上講,它應該工作,有人可以檢查嗎?

HTML代碼

<html>
    <title>Test</title>
    <head>
        <link rel="stylesheet" type="text/css" href="style.css">
        <script type="text/javascript" src="javascript.js"></script>
    </head>
    <body>
        <div  id="container">
            <div onclick="start()" id="topleft"></div>
            <div id="topright"></div>
            <div id="bottomleft"></div>
            <div id="bottomright"></div>
        </div>

    </body>
</html>

CSS代碼

#container {
    width: 400px;
    height: 400px;
    background-color: red;
    margin: 0 auto;
    position: relative
}
#topright, #topleft,#bottomright, #bottomleft {
    width: 50px;
    height: 50px;
    background-color: black;
    position: absolute;
}
#bottomright, #bottomleft {
    bottom:0;/*175*/
}
#topright, #topleft {
    top:0; /*175*/
}
#bottomleft, #topleft {
    left:0; /*175*/
}
#bottomright, #topright {
    right:0; /*175*/
}

JavaScript代碼

mt=0;
function move(){
    topleft=document.getElementById("topleft");
    for (n=0;n<=175;n++){
        topp=topleft.style.top;
        topp=parseInt(topp);
        topp++
        topleft.style.top=topp+"px"
    }
}

function start(){
    setInterval("move()",1);
}

任何人都可以糾正它嗎?

該代碼存在幾個問題,我懷疑#4和#7會導致最直接的問題:

  1. setInterval("move()"1); 是一個語法錯誤,所以這就是它沒有運行的原因。 您需要在1之前使用逗號:( 您已編輯問題以解決此問題)

     setInterval("move()", 1); // Comma -----------^ 
  2. 你沒有宣布你的mtntoplefttopp變量,你就topleft 全球恐怖的 topp 始終聲明您的變量,並在它們有意義的最內層范圍內聲明它們。

  3. 將字符串傳遞給setInterval是不好的做法; 它需要引擎進行隱式編譯,並且該編譯的范圍可能不是您所期望的(盡管您的代碼是引用的 - 例如,如果move確實是全局的 - 它將起作用)。 只需使用函數參考:

     setInterval(move, 1); 
  4. 您在topleft.style.top (間接)上使用parseInt ,但是topleft元素沒有任何style屬性,因此topleft.style.top"" 所以你得到NaN ,這NaN 元素上的style屬性不反映CSS,它只反映元素的style屬性中的內容。 查看getComputedStyle (適用於基於標准的瀏覽器)或currentStyle (適用於較舊的IE)。

  5. 使用帶有parseInt的基數幾乎總是最好的,例如: parseInt(topp, 10)而不僅僅是parseInt(topp)

  6. FWIW,如果setInterval有效,那么代碼將非常頻繁地運行(盡管不是每一毫秒; 規范說引擎應該將低於4值視為4 ,並且在任何情況下它都受實現和單個JavaScript UI線程的影響忙於其他事情)。

  7. 對循環中的元素進行一系列更改而不會屈服於瀏覽器將不會為這些元素設置動畫。 而不是循環,記住n並在每次調用時僅移動元素一位。 每次move返回時,都會為瀏覽器提供更新UI的機會。

這是一個我做過的最小修改的示例(不處理舊的IE的currentStyle ): Live Copy | 直播源

<!doctype html>
<html>
  <title>Test</title>
  <head>
    <style>
      #container {
        width: 400px;
        height: 400px;
        background-color: red;
        margin: 0 auto;
        position: relative
      }
      #topright, #topleft,#bottomright, #bottomleft {
        width: 50px;
        height: 50px;
        background-color: black;
        position: absolute;
      }
      #bottomright, #bottomleft {
        bottom:0;/*175*/
      }
      #topright, #topleft {
        top:0; /*175*/
      }
      #bottomleft, #topleft {
        left:0; /*175*/
      }
      #bottomright, #topright {
        right:0; /*175*/
      }
    </style>
  </head>
  <body>
    <div  id="container">
      <div id="topleft"></div>
      <div id="topright"></div>
      <div id="bottomleft"></div>
      <div id="bottomright"></div>
    </div>
    <script>
      (function() {
        var delay = 10;
        var topleft = document.getElementById("topleft");
        var currentPos = parseInt(getComputedStyle(topleft).top, 10);

        topleft.addEventListener("click", function() {
          // Start
          setTimeout(move, delay);
        });

        function move(){
          if (currentPos <= 175) {
            ++currentPos;
            topleft.style.top = currentPos + "px";
            setTimeout(move, delay);
          }
        }
      })();
    </script>
  </body>
</html>

筆記:

  • 我把代碼放在一個范圍函數中,以避免創建全局變量。

  • 我把代碼放在最后,就在結束</body>標記之前,所以所有元素都存在於運行時。

  • 我使用了一系列setTimeout而不是setInterval的鏈式(optionaly,在這種情況下,它確實是一個偏好的問題)。

  • 答案開頭列表中的各種內容。

  • 我每次回調只做一次更改,所以瀏覽器有時間做動畫。

  • 我將動畫幀之間的delay設為變量( delay )並將其設置為10 您可以使用適合您的任何值,如果您使用低於4值,請在上面的列表中注意#6。

  • 我使用addEventListener來掛接事件而不是使用onclick屬性。 在標記中使用onclick屬性需要您創建全局函數,這通常不是一個好主意。 (在IE的舊版本 - 包括IE8 - 你必須使用attachEvent 。或者你可以做topleft.onclick = function() { ... };但這是相當有限的[你只能有一個處理程序]。)

正如說TJ克勞德取代了

function start(){
    setInterval("move()"1);
}

function start(){
    setInterval(move, 1);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM