Tại sao bóng (vật) của tôi không co lại / biến mất?


208

http://jsfiddle.net/goldrunt/jGL84/42/ đây là từ dòng 84 trong fiddle JS này. Có 3 hiệu ứng khác nhau có thể được áp dụng cho các quả bóng bằng cách bỏ dòng 141-146. Hiệu ứng 'nảy' hoạt động như bình thường, nhưng hiệu ứng 'asplode' không làm gì cả. Tôi có nên bao gồm chức năng 'thu nhỏ' bên trong chức năng mã hóa không?

// balls shrink and disappear if they touch
var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
    function asplode(p) {
        setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

12
asplodekhông được khai báo trong phạm vi toàn cầu (hoặc cụ thể, không được xác định trong phạm vi có thể truy cập update); kiểm tra bàn điều khiển của chúng tôi.
apsillers

39
May mắn thay, đó là balls.splice()với một p.
m59

1
bạn có lỗi Uncaught ReferenceError: asplode is not defined. Chức năng asplode()không nhìn thấy được.
Anto Jurković

2
asplodekhông ở trong phạm vi phù hợp, setIntervalsẽ nhận được một tham chiếu chức năng, splicecần một chỉ mục - hoặc có thể thế giới đang thu hẹp lại với bạn jsfiddle.net/5f85b
bentytree

3
Đó là một câu hỏi hoàn toàn khác. Điều duy nhất họ có điểm chung là những quả bóng. Và JavaScript. Và chú ý. Oh và, xin vui lòng, nếu bạn muốn làm cho trò đùa, ít nhất là phải trang nhã. (Nhưng họ sẽ bị xóa bất kể.)
BoltClock

Câu trả lời:


65

Mã của bạn có một vài vấn đề.

Đầu tiên, theo định nghĩa của bạn:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }

    function asplode(p) {
         setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

asplodelà cục bộ của phạm vi bên trong shrinkvà do đó không thể truy cập được mã updatenơi bạn đang cố gắng gọi nó. Phạm vi JavaScript dựa trên chức năng, vì vậy updatekhông thể thấy asplodevì nó không nằm trong shrink. ( Trong bảng điều khiển của bạn , bạn sẽ thấy một lỗi như : Uncaught ReferenceError: asplode is not defined.)

Trước tiên, bạn có thể thử thay vì di chuyển ra asplodengoài shrink:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
}

function asplode(p) {
     setInterval(shrink(p),100);
     balls.splice(p, 1);
}

Tuy nhiên, mã của bạn có thêm một số vấn đề nằm ngoài phạm vi của câu hỏi này:

  • setIntervalmong đợi một chức năng. setInterval(shrink(p), 100)nguyên nhân setIntervalđể có được giá trị trả lại của ngay lập tức được gọi shrink(p) . Bạn có thể muốn

    setInterval(function() { shrink(p) }, 100)
  • Mã của bạn for (var i = 0; i < 100; i++) { p.radius -= 1; }có thể không làm những gì bạn nghĩ nó làm. Điều này sẽ ngay lập tức chạy hoạt động giảm dần 100 lần, và sau đó hiển thị trực quan kết quả. Nếu bạn muốn kết xuất lại quả bóng ở mỗi kích thước mới, bạn sẽ cần thực hiện từng lần giảm riêng lẻ trong một cuộc gọi lại thời gian riêng biệt (như một setIntervalthao tác).

  • .splicemong đợi một chỉ số số, không phải là một đối tượng. Bạn có thể lấy chỉ mục số của một đối tượng với indexOf:

    balls.splice(balls.indexOf(p), 1);
  • Vào thời điểm khoảng thời gian của bạn chạy lần đầu tiên, balls.splicecâu lệnh đã xảy ra (chính xác là nó đã xảy ra khoảng 100ms trước đây). Tôi cho rằng đó không phải là những gì bạn muốn. Thay vào đó, bạn nên có một hàm giảm dần được gọi liên tục setIntervalvà cuối cùng thực hiện balls.splice(p,1)sau đó p.radius == 0.


21
setInterval(shrink(p),100);

Điều này không làm những gì bạn nghĩ nó làm. Cuộc gọi này shrink, vượt qua nó p, và sau đó chuyển kết quả đến setInterval. shrink(p)trả về undefined, vì vậy dòng này không thực sự đặt bất cứ thứ gì vào một khoảng.

Bạn có thể muốn:

setInterval(function(){
    shrink(p)
}, 100);

1
@ tereško: Tôi có thể sống với điều đó :)
Rocket Hazmat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.