2012-03-05 23 views
0

JavaScriptを初めて使用しています。下にリンクしているWebページを作成して、私が習っているクラスの練習にしました。毎回画像とボタンが読み込まれない

JavaScript Product Catalog

正しく、それならば、すべての負荷を正常に動作するようだが、半分の画像やボタンのいずれかがロードされません。時間、そして時にはサムネイル負荷はなく、フルサイズ(マウスオーバー)画像がロードされません。 。 FirefoxやIEでは、最初の読み込み時にのみ発生するように見えます(ブラウザが開いている限り)、それ以降は正常に読み込まれます。しかし、Chromeでは、1ページのリロードごとにランダムに動作し続けます。ページを10回連続して更新すると、ボタンや画像(またはその両方)が読み込まれない2つのインスタンスが表示されることがあります。

これは私のコードに問題があると想定しています。サーバーに他の問題は一度もなかったからです。何か案は?

ありがとうございます!

<!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

+0

私のff10とキャッシュを無効にしてこの動作を再現することはできません。すべての要求に対応します。 – Corubba

+0

@コルーバチェックしていただきありがとうございます。どんな理由であれ、問題はChromeにのみ存在するようです。しかし、以下の答えで私が説明するように、私は最終的にこれが私のスクリプトの競合状態の結果であることを認識しました。 – The111

答えて

0

これは時間がかかりましたが、最終的にこの問題の底に達しました。これは、複数の非同期要求の競合状態で、同じ要素を移入することでした。私はこれが可能だったと考えられていなかったので、私は最初に行くことが予想1は、要素に最初にHTMLを追加します。

element.innerHTML = "first text"; 

ながら、私は二HTMLを追加する第二に行くと予想要求:

element.innerHTML += "second text"; 

明らかにこれらの要求があるため、私は=+=使用方法により、順不同で行けば、結果は「2つ目のテキストは、」私のイメージは半分の時間をロードしていなかった理由は、本質的である、上書きされることをになります。 (どちらの場合でも+=を使用したとしても、以下のコードが示すように、ランダムに順序付けされた要素の問題があります)。

FirefoxやIEでは何らかの理由で競合状態が問題になることはありませんでした。おそらく、これらのブラウザには、要求が開始された順に完了するように強制することによって、そのような状態を防ぐための何かがありますか?それとも、それはちょうど愚かな運です。しかし、Chromeでは、要求は常に順不同で終了します。下記のはるかに簡単なコードがはっきりと示されています。 Chromeでは、半分の時間でHTML出力として「フーバー」が得られますが、残りの半分は「BARFOO」になります。スクリプトで参照しているtestx.jsonファイルはダミー(空の)ファイルです。

この状況では、他のタスクを完了した後、最初のセットアップのコールバック関数によって2番目のセットアップ関数が呼び出されるため、競合状態が簡単に修正されます。もっと複雑な状況では、他の典型的な競合状態のセーフガード(mutexとsemaphores)も同様に動作すると思います。

<!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> 
関連する問題