【问题标题】:Best practices for loading large HTML templates through Javascript?通过 Javascript 加载大型 HTML 模板的最佳实践?
【发布时间】:2017-05-30 06:33:27
【问题描述】:

search.js

function search_function() {
     $("#search-button").attr('disabled','disabled');
     $("#product-container").empty();
     $(".paging_link").empty();
     $("#product-container").html('<div class="col-xs-12 text-center" style="margin-bottom: 25px; margin-top: 25px;"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i><span class="sr-only">Loading...</span></div>');
     var num;
     $.ajax({
       type: 'POST',
       url: '/api/search.php',
       async: true,
       data: $('#search-capture').serialize() +"&page=1",
       success: function (data) {
         console.log(data);
         $("#product-container").empty();
         array = $.parseJSON(data)
         if(array[1].length > 0)
         {
           num = array[0];
           $.each(array[1], function (index, item) {
             $.ajax({
               type: 'POST',
               url: '/api/item.php',
               data: {item: item},
               async: false,
               success: function (data) {
                 if(data)
                 {
                     $("#product-container").append(data);
                 }
               }
             });
           });
           $("#search-button").removeAttr('disabled');
           history.pushState(null, null, "search.php?search="+$("#search").val()+"&sort="+$("#sort").val()+"&page=1");
         }
         else {
           num = 0;
           $("#search-button").removeAttr('disabled');
           $("#product-container").append('<div class="col-xs-12 text-center" style="margin-bottom: 25px;"><h1>No results for <i>"'+ $("input[name=search]").val() +'"</i>.</h1></div>');
         }
         $(".paging_link").bootpag({
            total: num,
            maxVisible: 5,
            page: 1
         });
      }
     });
   }

/api/item.php

<?php
  include_once("../library/config.php");
  include_once("../library/user.class.php");
  $user = new user($pdo);
  if(isset($_POST['item']))
  {
    $item = $_POST['item'];
    $image_array = json_decode($item['images']);
    $person = $user->person_exists($item['owner_id']);
  }

?>
<div class="col-md-3 col-md-offset-0 col-sm-4 col-sm-offset-0 col-xs-10 col-xs-offset-1" style="margin-bottom: 25px;">
  <div class="col-item">
          <div class="post-img-content">
              <img src="<?php echo $image_array[0]; ?>" style="height: 100%; width: 100%;"/>
              <span class="post-title">
                  <b><?php echo $item['name'];?></b><br>
              </span>
              <?php
              if($item['price'] > $item['sale_price'])
              {
              ?>
              <span class="round-tag">-<?php echo round(($item['price'] - $item['sale_price'])/$item['sale_price'] * 100); ?>%</span>

              <?php
              }
?>
          </div>
          <div class="info">
              <div class="row">
                  <div class="price col-md-12">
                      <h5>Offered By: <a href="/user.php?id=<?php echo $item['owner_id']; ?>"><?php echo $person['firstname']; ?> <?php echo $person['lastname']; ?></a></h5>

<?php
if($item['price'] > $item['sale_price'])
{
?>
<div><b>$<?php echo $item['sale_price']; ?></b> <s class="text-muted">$<?php echo $item['price']; ?></s> <br> + $<?php echo $item['shipping']; ?> Shipping</div>

<?php
}
else {
?>
<div><b>$<?php echo $item['price']; ?></b><br> + $<?php echo $item['shipping']; ?> Shipping</div>
<?php
}
?>
                  </div>
              </div>

              <div class="row">
                <div class="col-sm-10 col-sm-offset-1">
        <hr style="margin-top: 0px; margin-bottom: 10px;">
                </div>
                <div class="col-xs-6">
                  <form class="form" name="add-to-cart">

                  <div class="form-group form-group-sm" style="margin-bottom: 0;">
                    <input type="hidden" name="id" value="<?php echo $item['id'];?>">
                    <input type="hidden" name="quantity" id="quantity" placeholder="quantity" value="1">
                    <input type="hidden" name="action" value="addtocart">
                  <button class="btn btn-default btn-sm btn-block" type="submit" id="search-button"><i class="fa fa-shopping-cart"></i> </button>
                  </div>
                </form>
                </div>
                <div class="col-xs-6">
                  <div class="form-group form-group-sm" style="margin-bottom: 0; margin-top: 0px;">
                  <a href="details.php?id=<?php echo $item['id']; ?>" class="btn btn-default btn-sm btn-block"><i class="fa fa-list"></i></a>
                  </div>
                </div>
              </div>
          </div>
      </div>
</div>

这是我的 Javascript 函数,用于从 api 调用中获取结果,我遇到的问题是加载时间,因为如果首先对 /api/search.php 进行 AJAX 调用以获取我想要显示的项目以及所有数据,例如作为名称、价格、卖家 ID 等。然后它对 /api/item.php 进行另一个 AJAX 调用,我有一个 HTML 模板,我使用 PHP 并使用来自 POST 的数据填充模板,并返回该 html 并将其附加到文本。但是,这使它加载非常缓慢,因为在第二次 AJAX 调用中,我必须将 async 设置为 false 才能以正确的顺序加载项目。我想知道除了通过 Javascript 加载巨大的 HTML 块(我应该这样做吗?)之外,是否有更有效和可行的方法来加载项目项而无需第二次 AJAX 调用(我应该这样做吗?)。

【问题讨论】:

  • 最佳实践绝对是不使用同步 AJAX,我需要一段时间来筛选代码以提出替代方案 - 希望同时会有比我更好更快的人出现:p
  • 是的,它似乎已被弃用,因为它完全破坏了用户体验,但在我可以搜索替代方案之前,这是一个快速修复。
  • 一个(可能)快速修复,因此您不使用同步 ajax - jsfiddle.net/y8vmuq8p
  • 但是由于项目在服务器满足请求时加载,所以项目的顺序不会是有序的,如果你看主帖,我会讨论,这就是为什么 async 是错误的权利现在。编辑:我去看看
  • 不,他们会的,修复确保每个 ajax 都按顺序运行:p

标签: javascript jquery html ajax


【解决方案1】:

您可以按顺序插入占位符元素,然后在 ajax 完成时将其替换为真实内容

所有跨度都按顺序同步添加,因此您拥有最终数据的正确位置

$.each(array[1], function(index, item) {
    var loc = $("#product-container").append("<span/>").children().last();
    // loc is the span just appended
    $.ajax({
        type: 'POST',
        url: '/api/item.php',
        data: {
            item: item
        }
        success: function(data) {
            if (data) {
                loc.replaceWith(data); // replace the span with data
            } else {
                loc.remove(); // remove the no longer needed placeholder
            }
        }
    });
});

注意:我的 jQuery 生锈了,虽然我对方法进行了简单的测试,但我可能把 jQuery 塞进了某个地方

或者,如果您需要在启用搜索按钮和历史推送状态之前等待所有这些 ajax 完成

$.when(array[1].map(function(item) {
    var loc = $("#product-container").append("<span/>").children.last();
    return $.ajax({
        type: 'POST',
        url: '/api/item.php',
        data: {
            item: item
        }
        success: function(data) {
            if (data) {
                loc.replaceWith(data);
            } else {
                loc.remove();
            }
        }
    });
})).then(function() {
    $("#search-button").removeAttr('disabled');
    history.pushState(null, null, "search.php?search=" + $("#search").val() + "&sort=" + $("#sort").val() + "&page=1");
});

【讨论】:

    猜你喜欢
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    相关资源
    最近更新 更多