API重复请求相同的信息

时间:2018-01-13 19:37:32

标签: javascript api

CODE:       var j = 0;

  function loadDesigns(j){
  // Create XHR Object [dont forget to add 'new']
  var xhr = new XMLHttpRequest();
  xhr.open("GET", 'http://www.pat-cooney.com/gd.json', true);

  xhr.onload = function(){
    if (this.status == 200) {
      var designs = JSON.parse(this.responseText);
      var contentOutput = "";
      var contentImages = "";
      var galleryNavOutput = "";

      function addImageNav() {
        for (i = 0; i < 3; i++) {
          galleryNavOutput += '<img id="' + designs[i].classId + '"src="' + designs[i].thumbnail + '">'
        }
      };

      function addContentImages() {
          contentImages += '<img src="' + designs[j].images[0] + '">';
      };

      contentOutput +=
      '<div class="block2">' +
          '<div id="inner">'+
              addContentImages() +
          '</div>' +
      '</div>' +
      '<div class="row">' +
          '<div id="center">' +
              addImageNav() +
          '</div>' +
      '</div>';

      document.getElementById("content").innerHTML = contentOutput;
      document.getElementById("inner").innerHTML = contentImages;
      document.getElementById("center").innerHTML = galleryNavOutput;
    }
  }
  xhr.send();
}
loadDesigns(j);

//.3 sec delay to allow AJAX delivery
setTimeout(function() {
  document.getElementById("one").addEventListener("click", function(){
    setTimeout(function() {loadDesigns(0);},300);
  });
  document.getElementById("two").addEventListener("click", function(){
    setTimeout(function() {loadDesigns(1);},300);
  });
  document.getElementById("three").addEventListener("click", function(){
    setTimeout(function() {loadDesigns(2);},300);
  });
}, 300);

以下是使用代码的codepen:https://codepen.io/Pcooney13/pen/wpXyvX请注意,由于有关API的codepen规则,它不会加载图像所以这里的代码是半工作的:http://www.pat-cooney.com/example.html

在/example.html中,我可以点击底部3个图像中的任意一个,然后更新顶部图像。我的问题是它只能工作一次然后我必须刷新页面。

我多次使用相同的xhr请求同一个小源,这是不是很糟糕?我可以在第一个请求中存储此信息,然后继续使用它,而无需在每次用户点击时调用它吗? 2.使用底部图像的ID可能会干扰每个请求?

我正在使用vanilla JS,对于frankenstein采购,任何帮助都会非常感谢和抱歉

1 个答案:

答案 0 :(得分:1)

这里的问题是: 您将点击处理程序附加到某些元素。然后,当您单击该元素时,将其从页面中删除,并添加具有相同ID的另一个元素。这些具有相同ID的新元素不再具有单击处理程序。更好的方法是将点击处理程序放在body上,并查看单击了哪个元素的id。如果它是您想要的元素之一,那么您将执行ajax调用。

这样做的原因是因为身体永远不会被移除并重新添加到页面中。另一种解决方案是将事件处理程序添加回新创建的元素。

稍微重构一下代码(简化一些事情虽然可以简化更多)并构建一个可行的解决方案会给你这个:

function loadDesigns(j){
  // Create XHR Object [dont forget to add 'new']
  var xhr = new XMLHttpRequest();
  xhr.open("GET", 'http://www.pat-cooney.com/gd.json', true);

  xhr.onload = function(){
  if (this.status == 200) {
      var designs = JSON.parse(this.responseText);

      function addImageNav() {
          var galleryNavOutput = "";
          for (i = 0; i < 3; i++) {
              galleryNavOutput += '<img id="' + designs[i].classId + '"src="' + designs[i].thumbnail + '">'
          }
          return galleryNavOutput;
      }

      function addContentImages() {
          return '<img src="' + designs[j].images[0] + '">';
      }

      contentOutput =
      '<div class="block2">' +
          '<div id="inner">'+
              addContentImages() +
          '</div>' +
      '</div>' +
      '<div class="row">' +
          '<div id="center">' +
              addImageNav() +
          '</div>' +
      '</div>';

      document.getElementById("content").innerHTML = contentOutput;
    }
  }
  xhr.send();
}
loadDesigns(0);

document.body.addEventListener('click', function(e) {
  switch (e.target.id) {
    case 'one':
      loadDesigns(0);
      break;
    case 'two':
      loadDesigns(1);
      break;
    case 'three':
      loadDesigns(2);
      break;
    default:
       return;
  }
});

我还应该注意,这种连接字符串以构建DOM的模式是危险的,更好的方法是单独创建元素(document.createElement)并使用getter和setter添加属性。当您连接字符串以构建DOM(特别是您无法控制的字符串 - 即用户输入)时,您自己打开XSS,攻击者可以在您的页面上运行自己的JS。