2014-09-30 63 views
0

這裏是一個JavaScript初學者:) 摘要:如何使一個事件監聽器依賴於AJAX調用的結果?如果在通話之後添加聽衆,則將在之後添加每個呼叫,從而累積聽衆。如果我在通話之前執行此操作,我怎樣才能將通話結果傳遞給它?聽衆似乎沒有采用用戶定義的參數。使JavaScript事件處理函數依賴於AJAX響應

詳細信息:我想寫一個Web照片瀏覽器,其中的臉部將被標記在照片上。要在照片之間切換,我想使用AJAX。我的PHP腳本以JSON字符串的形式返回圖片文件的名稱和麪(x,y,radius)的座標,例如

{"filename":"im1.jpg","faces":[{"x":129,"y":260,"radius":40},{"x":232,"y":297,"radius":40}]} 

我想根據faces在畫布上繪製圓形,一旦鼠標在照片上。因此我爲mouseover事件創建了一個監聽器。問題是,如果我在AJAX調用後添加偵聽器,畫布會獲取多個偵聽器,並保持從以前的照片中繪製圓圈。所以它看起來像處理程序需要提前定義。但是,我正在努力將AJAX響應傳遞給它。我怎麼能實現它?

我的HTML代碼到目前爲止是這樣的:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8"> 
</head> 
<body> 
<canvas id="canvas" width="100" height="600" 
    style="background-size: 100% 100%; border: 1px solid #FF0000;"></canvas> 
<script> 
    var image = new Image(); 
    var canvas = document.getElementById("canvas"); 
    var context = canvas.getContext("2d"); 

    canvas.addEventListener('mouseout', function(evt) { 
     context.clearRect(0, 0, canvas.width, canvas.height); 
     console.log("Canvas cleared"); 
    }, false); 

    function loadXMLDoc() { 
     var xmlhttp; 
     if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp = new XMLHttpRequest(); 
     } 
     xmlhttp.onreadystatechange = function() { 
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
       var ajaxData = JSON.parse(xmlhttp.responseText); 
       image.src = ajaxData.filename; 
       image.onload = function() { 
        canvas.width = Math.round(canvas.height/image.height * image.width); 
        canvas.style.backgroundImage = "url('" + image.src + "')"; 
       } 
       var faces = ajaxData.faces; 

       canvas.addEventListener('mouseover', function(evt) { 
        console.log("Canvas entered"); 
        console.log("Faces to mark: " + faces.length); 

        for (i = 0; i < faces.length; i++) { 
         context.beginPath(); 
         context.arc(faces[i].x, faces[i].y, 
          faces[i].radius, 0, 2 * Math.PI); 
         context.strokeStyle = "#00BBBB"; 
         context.lineWidth = 1; 
         context.stroke(); 
        } 
       }, false); 

      } 
     } 
     xmlhttp.open("GET", "get_data.php", true); 
     xmlhttp.send(); 
    } 
</script> 

<button type="button" onclick="loadXMLDoc()">Change Content</button> 
</body> 
</html> 

回答

1

您可以remove the old listener添加新的人之前。但更好的方法是將數據保存到事件偵聽器外的變量中,並在每次AJAX響應後更新。然後,由監聽器調用的函數根本不需要改變,它只是引用變量和你的臉部數據。

編輯

您可以在腳本的頂部再添變數:var faces;。您的腳本的其餘部分將可以訪問它,就像其他變量一樣。您最初不需要爲其分配值。現在讓您的mouseover聽衆與您的mouseout聽衆處於同一水平。從服務器獲取數據時,只需將其分配給面:faces = ajaxData.faces;(此處不要使用var,否則它會將面定義爲回調內的局部變量)。現在,上面定義的faces變量將具有該數據,並且偵聽器將有權訪問它。每次您進行AJAX調用時,都會用新的覆蓋舊面部。您可能需要在mouseover偵聽器中添加一項檢查,以確保該變量具有數據。你可以檢查一下這種方式:Ajax回調設置面的價值之前

if (typeof faces == 'object'){ 
    // your for loop can go here 
} 

typeof faces將等於'undefined'

直到您掌握語言如何處理範圍之前,JavaScript將會引起混淆。 Check this out作爲一個很好的起點。

+0

你能舉個例子嗎?我已經嘗試刪除偵聽器,但被卡住了事實,我需要在* AJAX調用之前將其刪除,但是如何在*之前的調用之後知道*的偵聽器?你看,這是我第一次使用AJAX實驗。 我更喜歡第二種方法,但是可以再舉一個例子嗎?我試過了,但在AJAX調用之前創建的監聽器無法訪問在調用期間收到的數據。 – texnic 2014-09-30 23:19:40

+0

有關刪除偵聽器的示例,請查看我原始答案的第一個句子中的鏈接,然後轉到示例。基本上,你需要使用一個命名函數,而不是一個匿名函數。我不認爲這是想要解決這個問題的方式,但很好了解。 – bjudson 2014-09-30 23:46:59

+0

謝謝,它的作品!將調查您的鏈接。 – texnic 2014-09-30 23:56:42