2012-03-05 18 views
0

我是JavaScript新手。我創建了下面鏈接的網頁,作爲我正在參加的課程的練習。圖像和按鈕每次都不加載

JavaScript Product Catalog

看來工作確定,如果一切正確加載,但一半的時間無論是圖像或按鈕不加載,有時縮略圖加載,但全尺寸(鼠標懸停)圖像不加載。在Firefox或IE中,它似乎只發生在第一次加載時,之後(只要瀏覽器保持打開狀態),它會在每次都成功加載。但是在Chrome瀏覽器中,它會繼續隨機地爲每一個頁面重新加載。只需連續刷新頁面10次,您可能會看到一些情況,其中按鈕或圖像(或兩者)不加載。

我認爲這是我的代碼的問題,因爲我從來沒有任何其他的服務器問題。有任何想法嗎?

謝謝!

<!DOCTYPE html> 

<html> 
<head> 
    <meta charset = "utf-8"> 
    <style type = "text/css"> 
     .box { border: 1px solid black; padding: 4px } 
    </style> 
    <title>Product Catalog</title> 
    <script> 

    var catalogDiv; 
    var summaryRequest; 
    var descriptionsRequest; 
    var thumbsRequest; 
    var imagesRequest; 

    function showLargeImage(imageElement) 
    { 
     imageElement.style.display = "none"; 
     imageElement.nextSibling.style.display = "inline"; 
    } 

    function showThumb(imageElement) 
    { 
     imageElement.style.display = "none"; 
     imageElement.previousSibling.style.display = "inline"; 
    } 

    function showDesc(descButton) 
    { 
     if (descButton.nextSibling.style.display == "none") { 
     descButton.nextSibling.style.display = "block"; 
     } else { 
     descButton.nextSibling.style.display = "none"; 
     } 
    } 

    function getDescriptions() 
    { 
     try 
     { 
     descriptionsRequest = new XMLHttpRequest(); 
     descriptionsRequest.addEventListener("readystatechange", 
      loadDescriptions, false); 
     descriptionsRequest.open("GET", "descriptions.json", true); 
     descriptionsRequest.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     descriptionsRequest.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function loadDescriptions() 
    { 
     if (descriptionsRequest.readyState == 4 
     && descriptionsRequest.status == 200) 
     { 
     var descriptions = JSON.parse(descriptionsRequest.responseText); 
     for (var i = 0; i < descriptions.length; i++) { 
      var infoDiv = document.getElementById(descriptions[i].id + 
       "-info-inner"); 

      var descButton = document.createElement("button"); 
      infoDiv.appendChild(descButton); 
      descButton.type = "button"; 
      descButton.textContent = "show description"; 
      descButton.setAttribute("onclick", "showDesc(this)"); 

      var desc = document.createElement("fieldset"); 
      desc.style.display = "none"; 
      desc.style.margin = "10px"; 
      infoDiv.appendChild(desc); 
      desc.innerHTML = "<br>" + descriptions[i].text + "<br><br>" ; 
     } 
     } 
    } 

    function getImages() 
    { 
     try 
     { 
     imagesRequest = new XMLHttpRequest(); 
     imagesRequest.addEventListener("readystatechange", 
      loadImages, false); 
     imagesRequest.open("GET", "images.json", true); 
     imagesRequest.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     imagesRequest.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function loadImages() 
    { 
     if (imagesRequest.readyState == 4 && imagesRequest.status == 200) 
     { 
     var images = JSON.parse(imagesRequest.responseText); 
     for (var i = 0; i < images.length; i++) { 
      var imageDiv = document.getElementById(images[i].id + 
       "-image-inner"); 
      imageDiv.innerHTML += "<img style=\"display:none;\"" + 
       "src=\"" + images[i].filename+ "\">"; 
      imageDiv.lastChild.setAttribute("onmouseout", 
       "showThumb(this)"); 
     } 
     } 
    } 

    function getThumbs() 
    { 
     try 
     { 
     thumbsRequest = new XMLHttpRequest(); 
     thumbsRequest.addEventListener("readystatechange", 
      loadThumbs, false); 
     thumbsRequest.open("GET", "thumbs.json", true); 
     thumbsRequest.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     thumbsRequest.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function loadThumbs() 
    { 
     if (thumbsRequest.readyState == 4 && thumbsRequest.status == 200) 
     { 
     var thumbs = JSON.parse(thumbsRequest.responseText); 
     for (var i = 0; i < thumbs.length; i++) { 
      var imageDiv = document.getElementById(thumbs[i].id + 
       "-image-inner"); 
      imageDiv.innerHTML = "<img style=\"display:inline;\"" + 
       "src=\"" + thumbs[i].filename+ "\">"; 
      imageDiv.firstChild.setAttribute("onmouseover", 
       "showLargeImage(this)"); 
     } 
     } 
    } 

    function setupDivsRequest() 
    { 
     try 
     { 
     summaryRequest = new XMLHttpRequest(); 
     summaryRequest.addEventListener("readystatechange", 
      setupDivsResponse, false); 
     summaryRequest.open("GET", "summary.json", true); 
     summaryRequest.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     summaryRequest.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function setupDivsResponse() 
    { 
     if (summaryRequest.readyState == 4 && summaryRequest.status == 200) 
     { 
     var summary = JSON.parse(summaryRequest.responseText); 

     for (var i = 0; i < summary.length; i++) { 

      var productDiv = document.createElement("div"); 
      var productImageOuterDiv = document.createElement("div"); 
      var productImageInnerDiv = document.createElement("div"); 
      var productInfoOuterDiv = document.createElement("div"); 
      var productInfoInnerDiv = document.createElement("div"); 

      catalogDiv.appendChild(productDiv); 
      productDiv.appendChild(productImageOuterDiv); 
      productDiv.appendChild(productInfoOuterDiv); 
      productImageOuterDiv.appendChild(productImageInnerDiv); 
      productInfoOuterDiv.appendChild(productInfoInnerDiv); 

      productDiv.id = summary[i].id; 
      productDiv.className = "box"; 

      productImageOuterDiv.id = summary[i].id + "-image-outer"; 
      productImageOuterDiv.style.cssFloat = "left"; 

      productImageInnerDiv.id = summary[i].id + "-image-inner"; 
      productImageInnerDiv.style.height = "250px"; 
      productImageInnerDiv.style.width = "250px"; 
      productImageInnerDiv.style.display = "table-cell"; 
      productImageInnerDiv.style.verticalAlign = "middle"; 
      productImageInnerDiv.style.textAlign = "center"; 

      productInfoOuterDiv.id = summary[i].id + "-info-outer"; 
      productInfoOuterDiv.style.height = "250px"; 

      productInfoInnerDiv.id = summary[i].id + "-info-inner"; 
      productInfoInnerDiv.style.float = "left"; 
      productInfoInnerDiv.style.padding = "10px"; 

      productInfoInnerDiv.innerHTML = summary[i].title + "<br>"; 
      productInfoInnerDiv.innerHTML += summary[i].price + "<br><br>"; 
     } 
     } 
    } 

    function start() 
    { 
     catalogDiv = document.getElementById("catalog"); 
     setupDivsRequest(); 
     getThumbs(); 
     getImages(); 
     getDescriptions(); 
    } 

    window.addEventListener("load", start, false); 
    </script> 
</head> 
<body> 
    <h1>Mouse over a product thumbnail for a larger picture.</h1> 
    <div id = "catalog"></div> 
</body> 
</html> 
+0

至少您發佈了足夠的代碼以便能夠看到發生了什麼。 – adeneo 2012-03-05 00:11:36

+0

我無法用我的ff10和禁用緩存重現此行爲。適用於每一個請求。 – Corubba 2012-03-05 00:57:55

+0

@corubba感謝您的檢查。無論出於何種原因,這個問題似乎只出現在Chrome中。但是,正如我在下面的答案中解釋的那樣,我最終意識到這是我腳本中競賽狀況的結果。 – The111 2012-03-05 10:05:41

回答

0

花了很長時間,但我終於到了這個問題的底部。這是多個異步請求之間的爭用條件,以填充相同的元素。我沒有考慮到這是可能的,所以我希望誰先走人會第一個HTML添加元素:

element.innerHTML = "first text"; 

雖然我預計要第二次將添加第二個HTML請求:

element.innerHTML += "second text"; 

顯然,如果這些請求走出去的順序,因爲我用=+=的方式,結果將是「第二個文本」被覆蓋,這基本上是爲什麼我的影像不是裝一半的時間。 (即使我在兩種情況下都使用了+=,但我仍然會遇到隨機排序元素的問題,如下面的代碼所示)。

無論出於何種原因,競爭條件似乎在Firefox或IE中似乎都不重要。也許在這些瀏覽器中有一些東西試圖通過強制請求按照它們開始的順序完成來抵禦這種情況?或者,也許這只是運氣不好。但在Chrome中,請求將始終以隨機順序完成。下面更簡單的代碼清楚地說明了這一點。在Chrome中,有一半時間你會得到「FOOBAR」作爲HTML輸出,但另一半時間你會得到「BARFOO」。我在腳本中引用的testx.json文件是虛擬(空)文件。

在完成其他任務後,我的第二個設置函數由第一個設置的回調函數調用,這種情況很容易解決。在更復雜的情況下,我猜想其他典型的競爭條件保護(互斥和信號量)也會起作用。

<!DOCTYPE html> 

<html> 
<head> 
    <script> 

    var testDiv; 
    var request1; 
    var request2; 

    window.addEventListener("load", start, false); 

    function start() 
    { 
     testDiv = document.getElementById("test-div"); 
     setup1(); 
     setup2(); 
    } 

    function setup1() 
    { 
     try 
     { 
     request1 = new XMLHttpRequest(); 
     request1.addEventListener("readystatechange", 
      response1, false); 
     request1.open("GET", "test1.json", true); 
     request1.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     request1.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function response1() 
    { 
     if (request1.readyState == 4 && request1.status == 200) 
     { 
     testDiv.innerHTML += "FOO"; 
     } 
    } 

    function setup2() 
    { 
     try 
     { 
     request2 = new XMLHttpRequest(); 
     request2.addEventListener("readystatechange", 
      response2, false); 
     request2.open("GET", "test2.json", true); 
     request2.setRequestHeader("Accept", 
      "application/json; charset=utf-8"); 
     request2.send(); 
     } 
     catch (exception) 
     { 
     alert("Request Failed"); 
     } 
    } 

    function response2() 
    { 
     if (request2.readyState == 4 && request2.status == 200) 
     { 
     testDiv.innerHTML += "BAR"; 
     } 
    } 

    </script> 
</head> 
<body> 
    <div id = "test-div"> </div> 
</body> 
</html> 
相關問題