2011-04-29 88 views
30

Điều này nghe có vẻ giống như một câu hỏi thực sự noob-ish, nhưng đó là bởi vì tôi khá mới ở JS. Tôi không thể tìm thấy bất kỳ thông tin nào về điều này ở bất cứ nơi đâu, vì vậy tôi nghĩ rằng tôi muốn hỏi cộng đồng.Vòng lặp vô hạn JavaScript?

Làm cách nào để tạo vòng lặp vô hạn trong JavaScript? Tôi đang cố gắng tạo một trình chiếu, mà tôi đã làm việc, nhưng tôi không thể lặp lại. Tôi thậm chí không thể làm cho nó lặp lại hai lần.

Mã Tôi đang sử dụng ngay bây giờ là

window.onload = function start() { 
    slide(); 
} 
function slide() { 
    var num = 0; 
    for (num=0;num<=10;num++) { 
     setTimeout("document.getElementById('container').style.marginLeft='-600px'",3000); 
     setTimeout("document.getElementById('container').style.marginLeft='-1200px'",6000); 
     setTimeout("document.getElementById('container').style.marginLeft='-1800px'",9000); 
     setTimeout("document.getElementById('container').style.marginLeft='0px'",12000); 
    } 
} 

Nếu không có sự cho điều trong đó, nó đi qua một lần. Khi tôi đưa vào một, nó hoặc làm cho Firefox khóa lên, hoặc chỉ vòng một lần. Tôi chắc chắn đây là một điều thực sự đơn giản để làm, và thậm chí nếu nó phải là vòng lặp 1.000.000 lần hoặc một cái gì đó thay vì vô hạn, mà sẽ làm việc tốt cho tôi.

Ngoài ra, tôi không muốn sử dụng jQuery hoặc thứ gì đó mà người khác đã tạo. Tôi đang học JavaScript, và đây là một phần để giúp tôi học hỏi, và một phần vì tôi đang cố gắng tạo ra càng nhiều hệ thống dựa trên HTML5 càng tốt.

EDIT: Tôi nghĩ lý do nó đóng băng là bởi vì nó thực hiện mã tất cả cùng một lúc, và sau đó chỉ lưu trữ nó trong bộ nhớ cache hoặc một cái gì đó. Những gì tôi muốn nó làm là đi qua điều này một lần, sau đó bắt đầu lại từ đầu, đó là những gì tôi đã luôn luôn nghĩ vòng ở đâu. Trong kịch bản lệnh "batch" (lệnh nhắc), điều này có thể được thực hiện với lệnh "GOTO". Tôi không biết liệu JS có tương đương hay không, nhưng đó thực sự là mục tiêu của tôi.

+4

Điều gì không sử dụng jQuery phải làm với việc sử dụng HTML5? – Ender

+5

jQuery không giúp bạn học Javascript. Nó ở đó để giúp ẩn các khác biệt (xa quá nhiều) trong mọi triển khai javascript của mỗi trình duyệt. Tin tôi đi, bạn vẫn sẽ bị bẩn tay với Javascript, ngay cả với sự giúp đỡ của jquery. –

+5

Ồ, và hầu hết các trình duyệt không cho phép bạn chạy một vòng lặp vô hạn trong javascript. Sẽ rất dễ dàng để thực hiện các cuộc tấn công DoS đối với mọi người nếu họ làm vậy. Sau một thời gian/số lần hoạt động nhất định, họ sẽ bật lên các cuộc đối thoại cảnh báo rằng tập lệnh có thể bị lỗi và cho phép người dùng hủy bỏ tập lệnh. –

Trả lời

52

Cách tiếp cận chính xác là sử dụng một bộ hẹn giờ. Sử dụng setInterval, bạn có thể đạt được những gì bạn muốn như sau:

window.onload = function start() { 
    slide(); 
} 
function slide() { 
    var num = 0, style = document.getElementById('container').style; 
    window.setInterval(function() { 
     // increase by num 1, reset to 0 at 4 
     num = (num + 1) % 4; 

     // -600 * 1 = -600, -600 * 2 = -1200, etc 
     style.marginLeft = (-600 * num) + "px"; 
    }, 3000); // repeat forever, polling every 3 seconds 
} 
+0

Điều này làm việc, cảm ơn bạn :) Đây thực sự là những gì tôi đã cố gắng để làm ban đầu, nhưng không thể tìm ra cách để thêm vào marginLeft. EDIT: câu trả lời này là chính xác những gì tôi muốn, quá, bởi vì nó chỉ đòi hỏi một chỉnh sửa nhanh chóng nếu tôi muốn thêm như 20 slide. Cảm ơn bạn, điều này thật tuyệt. – JacobTheDev

+0

@Rev: vui lòng giúp đỡ, có rất nhiều câu trả lời khó hiểu ở đây vì vậy tôi nghĩ rằng nó sẽ là một ý tưởng tốt để quăng trong giải pháp của tôi :-) –

+0

@Andy Điều này trông tương tự như tôi, với ngoại lệ chính là (tôi nghĩ) của bạn là viết fancier :) –

-2

thử điều này:

window.onload = function start() { 
    slide(); 
} 
function slide() { 
    setInterval("document.getElementById('container').style.marginLeft='-600px'",3000); 
    setInterval("document.getElementById('container').style.marginLeft='-1200px'",6000); 
    setInterval("document.getElementById('container').style.marginLeft='-1800px'",9000); 
    setInterval("document.getElementById('container').style.marginLeft='0px'",12000); 
} 

setInterval cơ bản là một 'vòng lặp vô hạn' và nó sẽ không đen lên trình duyệt. nó chờ đợi thời gian cần thiết, sau đó đi lại một lần nữa

+3

Điều đó sẽ làm cho các cuộc gọi lại khoảng thời gian chồng lên nhau và dẫn đến hiệu ứng không mong muốn. –

+0

@ thats thats tốt hơn nhiều setTimeouts chồng chéo 10X – Neal

+5

@Neal: setTimeouts ban đầu không chồng chéo - chúng được tuần tự tại 3000, 6000, 9000 vv Với cách tiếp cận của bạn, bộ đếm thời gian đầu tiên sẽ cháy tại 3000 ... 6000. .. 9000 ... khi nó phải cháy ở 3000 ... 15000 ... 27000 ... v.v. –

0

Bạn có thể lặp vô hạn một cách dễ dàng đủ thông qua đệ quy.

function it_keeps_going_and_going_and_going() { 
    it_keeps_going_and_going_and_going(); 
} 

it_keeps_going_and_going_and_going() 
+3

Đây không phải là vô hạn, nhưng thay vào đó sẽ sụp đổ sau khi một stackoverflow. – YoYoYonnY

0

Điều quan trọng là không lên lịch tất cả các bức ảnh cùng một lúc, nhưng để lên lịch một pic tiếp theo mỗi khi bạn có pic được hiển thị.

var current = 0; 
var num_slides = 10; 
function slide() { 
    // here display the current slide, then: 

    current = (current + 1) % num_slides; 
    setTimeout(slide, 3000); 
} 

Cách khác là sử dụng setInterval, thiết lập chức năng lặp lại thường xuyên (như trái ngược với setTimeout, mà lịch sự xuất hiện tiếp theo mà thôi.

17

Bạn không muốn while(true), mà sẽ bị khóa của bạn . hệ thống

gì bạn muốn thay vào đó là một thời gian chờ mà bộ một thời gian chờ trên chính nó, một cái gì đó như thế này:

function start() { 
    // your code here 
    setTimeout(start, 3000); 
} 

// boot up the first call 
start(); 
1

Bạn đang gọi setTimeout() mười lần liên tiếp, vì vậy tất cả chúng đều hết hạn gần như cùng một lúc.

window.onload = function start() { 
    slide(10); 
} 
function slide(repeats) { 
    if (repeats > 0) { 
     document.getElementById('container').style.marginLeft='-600px'; 
     document.getElementById('container').style.marginLeft='-1200px'; 
     document.getElementById('container').style.marginLeft='-1800px'; 
     document.getElementById('container').style.marginLeft='0px'; 
     window.setTimeout(
      function(){ 
      slide(repeats - 1) 
      }, 
      3000 
     ); 
    } 
} 

này sẽ gọi trượt (10), sau đó sẽ đặt thời gian chờ 3 giây để gọi trượt (9), mà sẽ thiết lập thời gian chờ để gọi trượt (8), vv: những gì bạn thực sự muốn điều này là Khi trình chiếu (0) được gọi, sẽ không có thêm thời gian chờ nào được thiết lập.

+0

Điều này đánh bại điểm của một chương trình ảnh trượt - bạn không rời khỏi thùng chứa tại chỗ trong bất kỳ khoảng thời gian nào trước khi chuyển nó trở về nguồn gốc của nó! –

3

Perhps đây là những gì bạn đang tìm kiếm.

var pos = 0; 
window.onload = function start() { 
    setTimeout(slide, 3000); 
} 
function slide() { 
    pos -= 600; 
    if (pos === -2400) 
    pos = 0; 
    document.getElementById('container').style.marginLeft= pos + "px"; 
    setTimeout(slide, 3000); 
} 
7

Dưới đây là một giải pháp gọn gàng đẹp dành cho bạn: (also see the live demo ->)

window.onload = function start() { 
    slide(); 
} 

function slide() { 
    var currMarg = 0, 
     contStyle = document.getElementById('container').style; 
    setInterval(function() { 
     currMarg = currMarg == 1800 ? 0 : currMarg + 600; 
     contStyle.marginLeft = '-' + currMarg + 'px'; 
    }, 3000); 
} 

Vì bạn đang cố gắng tìm hiểu, cho phép tôi giải thích như thế nào những công việc này.

Trước tiên, chúng tôi khai báo hai biến: currMargcontStyle. currMarg là một số nguyên mà chúng tôi sẽ sử dụng để theo dõi/cập nhật lề trái mà vùng chứa phải có. Chúng tôi tuyên bố nó bên ngoài chức năng cập nhật thực tế (trong một closure), để nó có thể được cập nhật/truy cập liên tục mà không làm mất giá trị của nó. contStyle chỉ đơn giản là một biến tiện lợi cho phép chúng ta truy cập vào các kiểu vùng chứa mà không phải định vị phần tử trên mỗi khoảng thời gian.

Tiếp theo, chúng tôi sẽ sử dụng setInterval để thiết lập chức năng sẽ được gọi 3 giây một lần, cho đến khi chúng tôi yêu cầu dừng lại (có vòng lặp vô hạn của bạn mà không đóng băng trình duyệt). Nó hoạt động chính xác như setTimeout, ngoại trừ nó xảy ra vô hạn cho đến khi bị hủy, thay vì chỉ xảy ra một lần.

Chúng tôi chuyển một số anonymous function đến setInterval, tác vụ này sẽ thực hiện công việc của chúng tôi cho chúng tôi. Dòng đầu tiên là:

currMarg = currMarg == 1800 ? 0 : currMarg + 600; 

Đây là một ternary operator. Nó sẽ chỉ định currMarg giá trị của 0 nếu currMarg bằng 1800, nếu không nó sẽ tăng currMarg bởi 600.

Với dòng thứ hai, chúng tôi chỉ cần gán giá trị đã chọn của chúng tôi cho margin2eft của container s và chúng tôi đã hoàn tất!

Lưu ý: Đối với bản trình diễn, tôi đã thay đổi giá trị âm thành dương, do đó hiệu ứng sẽ hiển thị.

+1

Cũng được mô tả tốt sir. –

+0

Tại sao, cảm ơn bạn! Bạn thưa bạn, là một học giả và một quý ông. – Ender

+5

Pip pip! Điều gì nói rằng chúng ta kỷ niệm sức khỏe tốt của chúng tôi trên một đường ống của tốt nhất tabac chap tốt của tôi? –

Các vấn đề liên quan