【问题标题】:ajax - incremental load of elements from one fileajax - 从一个文件中增量加载元素
【发布时间】:2022-01-15 05:42:18
【问题描述】:

我有一个带有容器的 index.html,我想在点击时通过 ajax 在其中加载内容。它看起来像这样:

<div id="loadcontent"></div>
<div id="more">Load More</div>

而且只有一个包含很多 div 的内容文件:

<div id="1" class="content">One</div>
<div id="2" class="content">Two</div>
<div id="3" class="content">Three</div>
<div id="4" class="content">Four</div>
<div id="5" class="content">Five</div>
<div id="6" class="content">Six</div>
<div id="7" class="content">Seven</div>
<div id="8" class="content">Eight</div>
<div id="9" class="content">Nine</div>
<div id="10" class="content">Ten</div>
<div id="11" class="content">Eleven</div>
<div id="12" class="content">Twelve</div>

这是 jQuery 代码:

$(document).ready(function () {
    var countItem = 0;

    $('#more').click(function(){
        countItem ++;
        $('<div/>').appendTo('#loadcontent').load('content.html #' + countItem)
            .hide()
            .fadeIn(1000);
    });
});

现在,当单击加载更多按钮时,它只加载一个 div,因为它会计算 id。

是否可以使用 ajax 加载接下来的三个或更多 div 并将它们附加到已经加载的 div 中?如果是,我怎样才能让它工作? 例如:第一次点击:1-3,第二次点击:1-6,第三次点击:1-9,等等……

任何帮助将不胜感激。

更新:

我不想一次加载内容,然后使用.show() 或类似的东西显示它。每次点击都应该是一个ajax请求。

【问题讨论】:

  • 只需发出一个请求并将响应存储在一个变量中。然后每次单击都添加到容器中。一遍又一遍地请求同一个文件是没有意义的。
  • 您可以让服务器端文件一次只生成 3 个元素。您传入接收到的总元素数,然后制作一个 ajax 以获取 3 个元素

标签: jquery html ajax


【解决方案1】:

如果您打算加载一个包含所有内容的文件,然后部分显示,则不需要对每个部分都提出请求,只需一次加载所有内容并在需要时显示。

我做了一个通过单击按钮部分显示内容的示例,请参见工作示例here

$(window).ready(function() {
  var $contentContainer = $('.loadcontent');
  var lastShownIndex = 0; // id of latest shown div
  var showPerClick = 3;
  var elementsCount = 0; // total available elements count 

  // function to show elements with passed ids
  var showElements = function(ids) {
    ids.forEach(function(id) {
        $contentContainer.find('#' + id).fadeIn(500);
    });
  }
  // function to generate array [start, start + 1, ..., end]
  var range = function(start, end) {
    return Array.apply(null, Array(end - start + 1)).map(function (_, i) {
        return i + start;
    });
  }
  // function to generate array of unshown divs
  var generateIds = function() {
    if (lastShownIndex >= elementsCount) return [];
    var ids = range(lastShownIndex + 1, Math.min(lastShownIndex + showPerClick, elementsCount));
    lastShownIndex += showPerClick;
    return ids;
  }
  // load content into container
  $contentContainer.load('content.html', function() {
    elementsCount = $contentContainer.find('.content').length;
    showElements(generateIds()); // show elements after page load
  });
  // show items partially by clicking a button
  $('#more').click(function() {
    showElements(generateIds());
    if (lastShownIndex >= elementsCount) { // hide button when no elements are available
        $(this).hide();
    }
  });
});

【讨论】:

  • 这可能是一个解决方案,但是:一次加载内容是我想要避免的,因为这些 div 可能包含具有大文件大小的图像并且有很多 div。我的目的是节省带宽并在需要时请求一定数量的内容。
  • 如果所有内容都在一个文件中,那么没有办法强制jQuery分部分加载文件,无论如何都会被完全加载。您需要将内容拆分为不同的文件,或者编写一个只提供部分文件的服务器端脚本。
  • 那么,这是否意味着当这些 div- 元素没有出现在 DOM 中时,就像他们使用我的问题中提供的代码一样,它们仍然在访问时完全加载?我很好奇。
  • 是的,您可以查看浏览器的开发人员工具,在“网络”选项卡上,您会看到每次都完全下载内容文件(及其所有 div)。但图片仅从必要的 div 加载。
  • @Anton 可以使用slice() 简化这一切
【解决方案2】:

我建议您只发出一个请求并将请求承诺存储在一个变量中。使用slice() 过滤每次添加的新项目

$(function() {
  var contentPromise = null,
    itemsPerClick = 3,
    startIndex = 0,
    $moreButton = $('#more');

 $moreButton.click(function() {
    getContent()
      .then(insertContent)
      .fail(function() {
        console.error("Failed request!")
      });
  });

  function getContent() {
    if (!contentPromise) {
      // store request promise
      contentPromise = $.get('content.html').then(function(resp) {
        // return jQuery object that can easily be sliced
        return $(resp).filter('div');
      })
    }
    return contentPromise;
  }

  function insertContent($content) {
    var endIndex = startIndex + itemsPerClick,
      $newItems = $content.slice(startIndex, endIndex);

    $('<div>').append($newItems)
      .appendTo('#loadcontent')
      .hide()
      .fadeIn(1000);

    // increment start 
    startIndex = endIndex;
    // hide button when none left
    if (startIndex >= $content.length) {
      $moreButton.hide()
    }
  }
});

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多