2010-02-25 24 views
10

Tôi đang gặp sự cố với việc tạo đối tượng Javascript và gọi phương thức trong đối tượng đó bằng cách sử dụng setTimeout. Tôi đã thử cách giải quyết khác nhau, nhưng luôn luôn trong phần thứ hai của vòng lặp của tôi phạm vi trở thành đối tượng cửa sổ chứ không phải là đối tượng tùy chỉnh của tôi. Cảnh báo: Tôi khá mới ở javascript.Phương thức gọi đối tượng tùy chỉnh với setTimeout mất phạm vi

mã của tôi:

$(function() { 
slide1 = Object.create(slideItem); 
slide1.setDivs($('#SpotSlideArea')); 
slide1.loc = 'getSpot'; 
slide2 = Object.create(slideItem); 
slide2.setDivs($('#ProgSlideArea')); 
slide2.loc = 'getProg'; 
slide2.slide = 1; 
setTimeout('triggerSlide(slide1)', slide1.wait); 
setTimeout('triggerSlide(slide2)', slide2.wait); 
}); 

function triggerSlide(slideObject) { 
slideObject.changeSlide(slideObject); 
} 

var slideItem = { 
div1: null, 
div2: null, 
slide: 0, 
wait: 15000, 
time: 1500, 
loc: null, 
changeSlide: function(self) { 
    this.slide ? curDiv = this.div1:curDiv = this.div2; 
    $(curDiv).load(location.pathname + "/" + this.loc, this.slideGo(self)); 
}, 
setDivs: function(div) { 
    var subDivs = $(div).children(); 
    this.div1 = subDivs[0]; 
    this.div2 = subDivs[1]; 
}, 
slideGo: function(self) { 
    if(this.slide) { 
    $(this.div2).animate({ 
    marginLeft: "-300px" 
    }, this.time); 
    $(this.div1).animate({ 
    marginLeft: "0" 
    }, this.time); 
    setTimeout('triggerSlide(self)', this.wait); 
    } else {  
    $(this.div1).animate({ 
    marginLeft: "300px" 
    }, this.time); 
    $(this.div2).animate({ 
    marginLeft: "0" 
    }, this.time); 
    setTimeout('triggerSlide(self)', this.wait); 
    } 
    this.slide ? this.slide=0:this.slide=1; 
} 
} 

nỗ lực mới nhất của tôi đã xây dựng các chức năng helper triggerSlide để tôi có thể cố gắng để vượt qua các tham chiếu đến các đối tượng thông qua các phương pháp của tôi, nhưng ngay cả điều đó dường như không làm việc.

tôi có thể sử dụng setInterval và nó hoạt động, tuy nhiên:

  1. tôi muốn đảm bảo các hình ảnh động đã hoàn thành trước khi bộ đếm thời gian khởi động lại
  2. Tôi không biết làm thế nào để có được xung quanh vấn đề này theo cách đó. :)

Trả lời

15

Điều này cần được đọc cho các lập trình viên Javascript bắt đầu với ngôn ngữ (và với Stackoverflow).

Không giống như Java, không có chức năng "ràng buộc" nội tại đối với bất kỳ đối tượng nào, bất kể chúng được khai báo như thế nào. Ràng buộc của bối cảnh đối tượng chỉ xảy ra ở thời gian gọi hàm. Vì vậy, khi bạn chuyển một tham chiếu đến một hàm tới một cái gì đó như "setTimeout", nó không quan trọng chút nào là bạn nhận được hàm từ một số đối tượng. Nó chỉ là một hàm, và "setTimeout" sẽ gọi nó với ngữ cảnh mặc định — đối tượng window.

Có nhiều cách để xử lý vấn đề này (và tôi sẽ không gọi nó là "vấn đề"; đó là một thực tế của ngôn ngữ và một ngôn ngữ rất mạnh). Nếu bạn đang sử dụng một khuôn khổ của một số loại nó sẽ dễ dàng hơn.

Một điều khác: bạn đang ràng buộc trình xử lý thời gian chờ và khoảng thời gian của mình dưới dạng chuỗi chứa mã. Đó là một thực hành khá xấu, vì vậy bạn nên quen với việc tạo thành các biểu thức hàm — nghĩa là các biểu thức có giá trị là các hàm.

Đối xử lý "slideItem" của bạn, ví dụ, bạn có thể làm điều này:

// ... 
setTimeout(function() { slideItem.changeSlide(); }, 5000); 

Bằng cách đó, chức năng gọi bằng cơ chế thời gian chờ sẽ luôn luôn gọi "changeSlide" với bạn "slideItem" đối tượng như bối cảnh. Bạn không cần tham số "tự" đó trong "changeSlide" vì "this" sẽ trỏ tới đối tượng phù hợp.

[sửa] Tôi lưu ý rằng bạn đang thực tế làm cho một số sử dụng jQuery, đó là một điều tốt.

+0

Mã +1 trong chuỗi thường được tránh trừ khi thật cần thiết. Điều đó bao gồm 'hàm mới '(' một số mã ');', 'setTimeout (" doSomething() ", 0);' và mọi người yêu thích, 'eval (' một số mã ');'. Hai cái đầu tiên mà tôi * không bao giờ thấy được điều cần thiết, thứ ba chỉ cho JSON và các biểu thức toán đầu vào :-) –

+0

Tôi đã thử ở trên, và nó hoạt động cho cuộc gọi ban đầu, nhưng các cuộc gọi lặp lại hành động (các lệnh setTimeout() trong slideGo() vẫn không hoạt động Tôi đã định dạng chúng như ở trên, nhưng sử dụng nó ở vị trí của slideItem ở trên, tức là setTimeout (function() {this.changeSlide();}, this.wait); Tôi nhận được một lỗi trong Firebug rằng this.changeSlide() không phải là một hàm.Tôi biết sớm trong phương thức slideGo 'this' đang tham chiếu đến slideItem của tôi, tuy nhiên nó không xuất hiện khi cuộc gọi setTimeout thứ hai xảy ra. –

+0

Tôi cũng nên đề cập đến rằng tôi đã thử thêm rằng = điều này trong đầu của phương pháp slideGo của tôi, tuy nhiên mà dường như để có được thêm vào trong một phạm vi toàn cầu chứ không phải là chỉ trong phương pháp này.Tôi có nhiều đối tượng trên trang để chỉ tạo một trang chúng animate, được kích hoạt bởi mỗi setTimeout. –

0

Tôi không thể kiểm tra mã này ngay bây giờ, nhưng việc này có hữu ích không?

setTimeout(function(){triggerSlide(slide1)}, slide1.wait); 
+0

Ugg. Tại sao bạn chuyển nó thành một chuỗi? – Pointy

+0

Trái ngược với những gì? Chỉ định tên hàm? – lance

+0

Có, chỉ định tên hàm hoặc chức năng ẩn danh. Trong ví dụ của bạn, nó sẽ làm việc tốt để lấy đi các dấu ngoặc kép hoàn toàn.Tuy nhiên, cơ chế của anh ấy là không cần thiết phức tạp, và nó thực sự nên được thực hiện khác nhau. – Pointy

0

Đây là jQuery, đúng không? Có một tham số gọi lại là animate(); chuyển nó thành hàm bạn muốn gọi sau khi hoạt ảnh hoàn tất và jQuery sẽ chú ý gọi nó. Các cuộc gọi lại sẽ nắm bắt phạm vi bạn muốn tốt.

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