2012-03-05 5 views
0

JavaScript를 처음 사용하고 있습니다. 나는 아래에 링크 된 웹 페이지를 만들어서 내가하는 수업을위한 운동으로 만들었다.매번로드되는 이미지 및 버튼

JavaScript Product Catalog

이 제대로 경우 모든 부하 확인을 작동하는 것 같다,하지만, 시간을 반으로 이미지 또는 버튼 중 하나를로드하지 않으며, 때로는 미리로드되지만 전체 크기 (마우스 오버) 이미지가로드되지 않습니다 . Firefox 나 IE에서는 첫 번째로드에서만 발생하는 것으로 보이고 그 이후 (브라우저가 열려있는 한) 이후에는 항상로드됩니다. 그러나 크롬에서는 매 페이지마다 새로 고침을 반복합니다. 페이지를 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

Atleast는 무슨 일이 벌어지는 지 알 수있는 충분한 코드를 게시했습니다. – adeneo

+0

ff10 및 캐시가 비활성화되어이 동작을 재현 할 수 없습니다. 모든 요청에 ​​대해 작동합니다. – Corubba

+0

@corubba 확인해 주셔서 감사합니다. 어떤 이유로 든 문제는 Chrome에만 나타나는 것 같습니다. 그러나 아래에 나와있는 대답에서 설명 하듯이, 결국 이것이 내 대본의 경쟁 조건의 결과라는 것을 깨달았습니다. – The111

답변

0

오랜 시간이 걸렸지 만 마침내이 문제의 최하부에 도달했습니다. 동일한 요소를 채우는 여러 비동기 요청 사이의 경쟁 조건이었습니다. 나는 이것이 가능했던 생각하지 않았다, 그래서 내가 먼저 갈 것으로 예상 한 요소에 첫 번째 HTML을 추가합니다 :

element.innerHTML = "first text"; 

동안 나는 두 번째 HTML을 추가 둘째 것으로 예상 요청 :

element.innerHTML += "second text"; 

분명히 이러한 요청 때문에 내가 =+= 사용하는 방식, 순서가 가면, 그 결과는 "두 번째 텍스트는"내 이미지는 시간의 절반을로드하지 않은 이유는 본질적으로, 이는 덮어 쓰기됩니다 있다는 것입니다. (비록 두 경우 모두 +=을 사용했다하더라도 아래 코드에서 볼 수 있듯이 무작위로 정렬 된 요소의 문제가 남아 있습니다.)

Firefox 나 IE에서는 어떤 이유에서든 경쟁 조건이 결코 문제가되지 않는 것 같습니다. 아마도 이러한 브라우저에는 요청이 시작된 순서대로 완료되도록 강제하여 이러한 조건을 방지하려고하는 것이 있습니까? 아니면 어쩌면 그것은 바보 같은 행운 일 수도 있습니다. 하지만 Chrome에서는 요청이 계속해서 임의의 순서로 완료됩니다. 아래의 훨씬 간단한 코드가 명확하게 설명됩니다. Chrome에서 절반은 HTML 출력으로 "FOOBAR"를 얻지 만 나머지 절반은 "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>