2009-11-05 29 views
0

我試圖測試動態傳遞給圖像標記的URL是否會解析。我使用下面的JavaScript函數:Javascript函數在其子程序完成之前返回

testImageUri = function(src) { 
     var img = new Image(); 
     var imgStatus = false; 

     var goodUri = function() { 
      imgStatus = true; 
     }; 

     var badUri = function() { 
      imgStatus = false; 
     }; 

     img.onload = goodUri; 
     img.onerror = badUri; 
     img.src = src; 

     return imgStatus; 
    } 

功能巴杜裏和goodUri被調用如預期,但他們似乎是「遲到」的testImageUri功能似乎纔得到改變imgStatus變量返回。

在javascript中如何解決這些問題?
如何避免它們?
有沒有一種經驗法則來識別易受此影響的情況?

編輯
謝謝大家的回覆。我想我明白現在發生了什麼。我將按照第一個回覆中的描述來實現該函數,但是如所建議的那樣,還有一個附加的回調參數。

再次感謝。

回答

4

通過設置img.onload和img.onerror,可以將函數附加到這些事件處理程序。該腳本將附加它們,當成功時,執行腳本的其餘部分。正如你已經注意到的,在這些事件實際觸發之前,Javascript不會停止執行。

代替返回imgStatus(這將可能是一個新的功能,我將引用爲doSomething使用),考慮將此doSomething功能的事件處理程序本身,使得它作爲一個回調函數:

testImageUri = function(src) { 
    var img = new Image(); 
    var imgStatus = false; 

    var goodUri = function() { 
     callback_testSuccesful(src); 
    }; 

    var badUri = function() { 
     callback_testFailed(src); 
    }; 

    img.onload = goodUri; 
    img.onerror = badUri; 
    img.src = src; 

    return true; // The event handlers have been added; the return value doesn't say if they fired or not. 
} 

function callback_testSuccesful(src) { } // Function called when the image loaded 
function callback_testFailed(src) { } // Function called when loading failed 
+1

讓testImageUri'的'回調論據更加取勝。 – outis 2009-11-05 12:44:44

+0

img變量在函數中是局部的,所以當您退出函數時,不再有對該對象的引用。它可能會在圖像加載之前收集,因此這些事件永遠不會發生...... – Guffa 2009-11-05 12:48:39

2

您正在將函數作爲事件處理程序添加到圖像元素。這意味着他們保證在你退出testImageUri函數後被調用。只要您處於testImageUri函數內,就不會處理任何事件,因此imgStatus變量將不會及時更新以便返回。

解決方法是將回調函數發送到testImageUri函數中。當事件發生時,您調用回調函數。但是,由於函數在設置圖像源後立即返回,因此必須在函數外部聲明img變量,以便在從函數退出後能夠存活。

var img; 

testImageUri = function(src, callback) { 
    img = new Image(); 

    var goodUri = function() { 
     callback(true); 
    }; 

    var badUri = function() { 
     callback(false); 
    }; 

    img.onload = goodUri; 
    img.onerror = badUri; 
    img.src = src; 
} 
2

試試這個:

var imageMaker= { 
image:null, 
imgStatus: false, 
goodUri:function() { 
      this.imgStatus = true; 
     }, 
badUri:function() { 
      this.imgStatus = false; 
     }, 
testImageUri:function(src) { 
     this.image = new Image(); 
     this.image.onload = this.goodUri; 
     this.image.onerror = this.badUri; 
     this.image.src = src; 
    } 
}  
}; 

//now fire imageMaker.testImageUri(src) 
+0

這將起作用,但是您必須輪詢imgStatus中的更改,並且在發生此情況時不會收到信號。此外,您無法區分初始假值和badUri函數設置的假值之間的差異。 – Guffa 2009-11-05 12:45:56

+0

imgStatus:null應該讓你分辨不同。檢查時使用typeof操作符。 – 2009-11-05 12:54:21

+0

只是爲了避免當多個imageMaker.testImageUri(src) imageMaker.testImageUri(src1)等順序觸發時發生干擾,最好是將imageMaker作爲一個函數返回當前是imageMaker值的對象在我的回答上面? 然後它會是imageMaker()。testImageUri(src)。請指教。 – 2009-11-05 13:05:27

相關問題