[英]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會導致最直接的問題:
setInterval("move()"1);
是一個語法錯誤,所以這就是它沒有運行的原因。 您需要在 您已編輯問題以解決此問題) 1
之前使用逗號:(
setInterval("move()", 1); // Comma -----------^
你沒有宣布你的mt
, n
, topleft
和topp
變量,你就topleft
全球恐怖的 topp
。 始終聲明您的變量,並在它們有意義的最內層范圍內聲明它們。
將字符串傳遞給setInterval
是不好的做法; 它需要引擎進行隱式編譯,並且該編譯的范圍可能不是您所期望的(盡管您的代碼是引用的 - 例如,如果move
確實是全局的 - 它將起作用)。 只需使用函數參考:
setInterval(move, 1);
您在topleft.style.top
(間接)上使用parseInt
,但是topleft
元素沒有任何style
屬性,因此topleft.style.top
是""
。 所以你得到NaN
,這NaN
。 元素上的style
屬性不反映CSS,它只反映元素的style
屬性中的內容。 查看getComputedStyle
(適用於基於標准的瀏覽器)或currentStyle
(適用於較舊的IE)。
使用帶有parseInt
的基數幾乎總是最好的,例如: parseInt(topp, 10)
而不僅僅是parseInt(topp)
。
FWIW,如果setInterval
有效,那么代碼將非常頻繁地運行(盡管不是每一毫秒; 規范說引擎應該將低於4
值視為4
,並且在任何情況下它都受實現和單個JavaScript UI線程的影響忙於其他事情)。
對循環中的元素進行一系列更改而不會屈服於瀏覽器將不會為這些元素設置動畫。 而不是循環,記住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.