javascript - 如何使用 javascript 和 HTML 解决此对象加载问题

标签 javascript html

我正在开发一个网络应用程序,目前我只使用 JavaScript。我试图解决的问题是我有三个不同的对象并且只有一个 HTML 页面。基于用户单击事件,我希望加载所选类别的对象并将其显示在同一页面上。例如,假设用户位于主页,如果他们单击导航栏中的类别 A,则将首先加载该页面,然后脚本将对象加载到数据结构中。最后,将它们显示到 javascript 生成的 HTML 容器中。触发用户单击事件后,不同的类别也会发生相同的情况。更准确地说,我希望能够为不同的对象重用 HTML 页面,而不必为每个类别创建页面。

我已经创建了代码,用于为我想要加载的 n 个对象执行所有数据加载和 HTML 生成。当我位于对象页面时,代码工作正常,但如果从另一个页面触发该事件,则似乎不会发生任何情况。我猜这与页面加载时间有关。

我已经发布了我正在处理的部分的完整代码。

var dataController = (function() {
  var JSONurls = {
    bags: "../JSON/bags.json",
    bc: "../JSON/briefcases.json",
    belts: "../JSON/belts.json",
    accs: "../JSON/accs.json",
  };

  ProductObj = function(name, des, colors, price, pics, type, ID) {
    this.name = name;
    this.description = des;
    this.colors = colors;
    this.price = price;
    this.pics = pics;
    this.type = type;
    this.ID = ID;
  };

  var dataStruc = {
    allProducts: {
      bags: [],
      briefcases: [],
      belts: [],
      accessories: [],
    },
  };

  return {
    addProd: function(obj) {
      var newProd, ID;

      if (dataStruc.allProducts[obj.type].length > 0) {
        ID =
          dataStruc.allProducts[obj.type][
            dataStruc.allProducts[obj.type].length - 1
          ].ID + 1;
      } else {
        ID = 0;
      }

      newProd = new ProductObj(
        obj.name,
        obj.description,
        obj.colors,
        obj.price,
        obj.pics,
        obj.type,
        obj.ID
      );

      dataStruc.allProducts[obj.type].push(newProd);

      return newProd;
    },

    getDataStruct: function() {
      return dataStruc;
    },

    getJsonUrls: function() {
      return JSONurls;
    },

    loadJSON: function(url, cat, callback) {
      var requestURL, request, JsonObj;

      requestURL = url;

      request = new XMLHttpRequest();

      request.open("GET", requestURL);

      request.responseType = "text";

      request.send();

      request.onload = function() {
        JsonObj = JSON.parse(request.response);

        dataStruc.allProducts[cat] = JsonObj[cat];

        callback(cat);
      };
    },
  };
})();

var UIcontroller = (function() {
  var DomStrings = {
    shopCatg: ".shop-catg",
    productCont: ".product-container",
  };

  //public methods
  return {
    // function display the object based on the category based on the event target

    displayObjectToPage: function(cat) {
      var deafultHtml;

      // 1. loop over the product category

      dataController.getDataStruct().allProducts[cat].forEach(function(cur) {
        deafultHtml =
          '<div class="col-lg-4 col-md-6 col-sm-10">' +
          '<img class="img-fluid" src="../img/' +
          cur.type +
          "/" +
          cur.pics[0] +
          '.jpg">' +
          '<h6 class="text-center">' +
          cur.name +
          "</h6>" +
          '<div class="text-center text-muted">' +
          cur.price +
          "</div>" +
          "</div>";

        document
          .querySelector(DomStrings.productCont)
          .insertAdjacentHTML("beforeend", deafultHtml);
      });
    },

    getDomStrings: function() {
      return DomStrings;
    },
  };
})();

var mainController = (function(UIctrl, dataCrtl) {
  var setUpEvents = function() {
    var doneLoading = false;

    var DOM = UIctrl.getDomStrings();

    document.querySelector(DOM.shopCatg).addEventListener("click", function() {
      InitializeData(event, function(cat) {
        UIcontroller.displayObjectToPage(cat);
      });
    });
  };

  InitializeData = function(event, callback) {
    var category = event.target.textContent;

    if (event.target.textContent === "bags") {
      dataController.loadJSON(
        dataController.getJsonUrls().bags,
        category,
        callback
      );
    } else if (event.target.textContent === "briefcases") {
      dataController.loadJSON(dataController.getJsonUrls().bags, "briefcases");
    } else if (event.target.textContent === "belts") {
      dataController.loadJSON(dataController.getJsonUrls().bags, "belts");
    } else {
      dataController.loadJSON(dataController.getJsonUrls().bags, "accs");
    }
  };

  displayObject = function() {};
  return {
    init: function() {
      setUpEvents();
    },
  };
})(UIcontroller, dataController);

mainController.init();

最佳答案

我不确定,但我注意到这个潜在的问题:

request.send();
request.onload = function() {
  // ...
}

我相信当您调用 send 时,请求应该异步启动。如果请求在分配 onload 之前返回,您可能会看到它被跳过。不过,我已经很多年没有直接使用 XHR 了。

通常,您需要在调用 send() 之前添加 onload 回调以避免此问题。

<小时/>

我还刚刚注意到您在此处的回调函数参数中缺少事件:

                                                                       ▽
document.querySelector(DOM.shopCatg).addEventListener("click", function() {
                 ▽ event is undefined
  InitializeData(event, function(cat) {
    UIcontroller.displayObjectToPage(cat);
  });
});

关于javascript - 如何使用 javascript 和 HTML 解决此对象加载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58544006/

相关文章:

javascript - 如何编写动态html标签

javascript - PIXI 中的 mousedown 事件不会被创意笔触发

JavaScript/jQuery : Detect when each individual image loads

html - CSS:字体大小不准确吗?

html - 使用内容 : ""; in SASS (not scss)

javascript - 通过键盘对 Google Charts 表格进行排序

javascript - Ionic 应用程序上的 Webview

javascript - 从 .then 函数分配到更高级别的作用域变量是否存在任何陷阱

javascript - 为什么这个对维基百科的 API 调用只显示少数结果的摘录?

html - 在 html 按钮中包装一个 react-router 链接