【问题标题】:Two methods of looping through Ajax requests for jQuery Then When - which to use?循环遍历 jQuery 的 Ajax 请求的两种方法 Then When - 使用哪个?
【发布时间】:2014-07-19 04:17:19
【问题描述】:

我有一个看似简单的博客项目正在进行中,我试图将Isotope Jquery(用于布局/过滤/排序)、Infinite Scroll 以及通过 Ajax 动态加载所有博客摘录(所以过滤和排序在用户向下滚动页面之前应用于所有摘录(之后它们被加载到 dom 中然后可以访问)。

这个问题主要涉及通过 Ajax 获取博客文章摘录数据,然后将其传递到 Isotope 过滤代码中。我不确定执行此操作的最佳方法,但目前正在尝试使用 ajax 请求遍历每个页面(博客文章摘录),然后整体访问数据。

我遇到了两种不同的方法来遍历 ajax 请求,每种方法都使用 then when jquery 语句。第一种是使用this SO answer 中的方法,另一种是将整个then when 语句放入$.each 语句中。

方法一:

  var pageCount = 15;
  var pageCountArray = [];
  for (var i = 1; i != pageCount; ++i) pageCountArray.push(i);

  var deferreds = [];
  $(pageCountArray).each(function() {
    var pageNumber = this;
      deferreds.push(
        $.get('/page/' + pageNumber)
      )

    $.when.apply($, deferreds)
      .then(function(data){
        console.log(data); 
        // this outputs data as a string from the first page, then a list of objects
        console.log(typeof(data));
        // string
        // 13 - object
    });
  });

略过:关于为什么输出一个字符串然后输出对象的任何想法?

方法二:

  var pageCount = 15;
  var pageCountArray = [];
  for (var i = 1; i != pageCount; ++i) pageCountArray.push(i);

  $(pageCountArray).each(function(data) {
    var pageNumber = this;
      $.when(
        $.get('/page/' + pageNumber)
      ).then(function() {
        console.log(data);
        // this outputs 14 strings of data 
        console.log(typeof(data));
        // 14 - string
      })
  });

我还没有弄清楚如何将 Ajaxed 数据合并到我的 Isotope 过滤器函数中,但我认为我需要先将其解析为 HTML。仍然让我的 javascript 立足……在这种情况下,这些数据类型(对象与字符串)中的一种更容易解析成 HTML 吗?我想这就是我答案的关键吗?

非常需要洞察力。

PS:对于任何可能知道以不同方式实现这一目标的更好方法的人的奖励积分,以某种方式很好地融入同位素/无限滚动(也许以一种更适合玩的方式使用这些插件...我的搜索没有成功)。

PPS:第二种方法感觉更干净......任何人都知道它不是一个好方法的原因(在.each中使用when then循环)?

【问题讨论】:

  • Method2 不需要$.when.then。 Method1 可以使用.done 代替.then。 Method1 和 method2 做了两件完全不同的事情,得到了两个完全不同的结果。您使用的应该基于您想要的结果。一个并不比另一个更好更干净,只是不同而已。

标签: javascript jquery ajax jquery-isotope infinite-scroll


【解决方案1】:

哇,这是一个很大范围的问题,难怪没有任何回应。这是一个很大的问题,所以我会尽力提供帮助。我创建了许多站点,其中包括同位素的排序/过滤,同时使用具有无限滚动的 AJAX 预加载,所以这里是我已经写出的最简单的例子之一......

首先我必须提一下,使用 David DeSandro 的 ImagesLoaded 插件可以更好地实现这一点。这主要是因为它允许您将一个回调函数(事件发生后执行的函数)附加到给定容器中最终图像的加载事件。哇,这太罗嗦了。如何更好地表达......它基本上是在询问容器,你完成加载了吗?不?现在怎么样?你满载了吗?好的,请立即执行此功能...

随着实现,我将在我的 onLoad 事件中开始使用这段代码......

$(function() {

    extendJQ_PreLoad(); //I Will Get To This Function In A Min

    //Use ImagesLoaded Plugin To Control Load Time Sync
    $(container).imagesLoaded(function() {
        cont.isotope({
            itemSelector: ".box", //This is the class I use on all my images to sort
            layoutMode: "masonry",
            isOriginLeft: true,
            isFitWidth: true,
            filter: "*",
            masonry: {
                columnWidth: ".box"
            }
        });
        preLoadNextImgSet(); //I Will Get To This Function In A Min
    });
});

好的,让我们分解一下。 ImagesLoaded 插件会阻止 Isotope 插件实例化,然后再出现要排序/过滤/加载和/或处理的图像。这是第 1 步。第 2 步是然后开始查看实际的同位素插件实例。我告诉它使用 Masonry 插件作为其布局样式,然后我在数组键“masonry”下传入一个带有选项的对象文字。此处名为 masonry 的数组键与您过去通常使用独立的 Masonry 插件(非同位素或同位素 2)进行的任何实例化相同。

看这里的第 3 步将是我开始致电 extendJQ_PreLoad();。这个函数是我写的,让 JQuery 知道我需要扩展它的核心功能,以便能够预加载我给它的任何图像,作为一个数组。就这样……

function extendJQ_PreLoad() {
    $.preloadImages = function(args) {
        for (var i = 0; i < args.length; i++) {
            $("<img />").attr("src", args[i]);
        }
    }    

} //end function

这只是一个简单的迭代器,没有什么花哨的,它允许使用与 DOM 相关的巧妙技巧来预加载图像。如果您以这种方式加载图像,它会加载到内存中,但不会加载到 DOM 中,这意味着它会被加载并隐藏。一旦您将此图像插入到任何地方,它将非常快速地插入,因为它现在已加载到缓存中并等待放置。你可以查看更多关于这个here的信息。

最后要看的是我对预加载函数的调用。这是对 php 文件的一个非常简单的调用,它只是按顺序查找下一组图像(如果有的话)。如果它得到一些图像,那么它开始将其添加到内存中的临时 div 中(同样不在要查看的 DOM 上),现在设置为简单的 DOM 遍历。让我们查看函数来剖析它的功能......

function preLoadNextImgSet() {
    $.post('AjaxController/ajaxPreload_Gallery.php', {currStart: start, currSize: loadSize}, function(data) {
        if(data!="") {
            var y = $(document.createElement("div")).append(data).find("a"),
                found = [];
            y.each(function() {
                found[found.length] = "img/gallery/" + $(this).text();
            });
            $.preloadImages(found);
        }
    });

} //end function

在本例中,我的浏览器窗口中有两个全局变量,它们来自我将声明的 JavaScript。 startloadSize 变量。 start 变量表示我们当前所在的图像列表中的当前位置,loadSize 变量设置每次预加载的图像数量限制。

现在变量已通过$.post 函数设置并发送到 PHP 文件,我们可以使用 PHP 文件按顺序查找合适的图像并将它们加载到内存中等待使用。这里返回给y 变量的任何内容都会被each 函数迭代,然后预加载。一旦这个函数范围退出,虚构的 div 将被删除并发送到垃圾,因为它没有被简单地迭代使用。

好的,现在。这是一段旅程,但我们几乎准备好在这里开始最后的方法。让我们先回过头来看看第一个imagesLoaded 调用在做什么,因为我们知道这些函数中添加的新功能。 DOM-Ready 事件中的imagesLoaded 调用在其最底部有一个调用,用于预加载图像......为什么?这是因为一旦页面加载并且初始图像被加载到同位素容器中,我们现在需要页面使用这个空闲时间来开始加载下一组。因此,换句话说,一旦图像被放置和排序并且高兴地坐在那里,下一个loadSize 数量的图像将被加载并等待您放置它们。

现在是最后一个功能。该函数是一个通用函数,其唯一目的是将当前预加载的图像正式加载到 DOM 中,然后请求加载下一组。然而,究竟什么会调用这个函数呢?这就是延迟加载或无限滚动对我们有用的地方。您需要在页面的某处添加此功能...

    $(window).scroll(function(){
        scrollTop = $(window).scrollTop(),
        windowHeight = $(window).height(),
        docuHeight = $(document).height();

        //AJAX Data Pull
        if(((scrollTop + windowHeight)+35) >= docuHeight){
            getNextImages();
        } 
    });

这个函数是允许无限滚动效果发生的神奇函数。我添加了 35 像素左右的填充(在我的代码中随机添加了 +35),因为有时您希望它加载到接近页面末尾但不完全是页面的实际末尾。

好的,当我们到达页面末尾时,现在已经设置好了,这个函数将想要获取所有下一个图像,就像我们提到的那样。我的功能是这样的……

function getNextImages() {
    cont = $(container);
    $.post('AjaxController/ajaxPortfolio_Gallery.php', {currStart: start, currSize: loadSize}, function(data) {
        if(data!="") {
            //Append New Photos Inside <a> Element Tag
            var y = $(document.createElement("div")).append(data).find("a");
            cont.append(y);
            //Fix Image Layouts
            cont.imagesLoaded(function() {
                //Feed Isotope Layout The New Items
                cont.isotope("appended", y);
                cont.find("a").css({"opacity":"1"});
            });

        } else { unFilled = false; }
    });
}

我已经包含了unFilled 变量,以便在您到达图像末尾时可以设置一个标志。如果没有图像可显示,您不希望它一直尝试加载。

好的,所以。这是很多信息,所以我会尽量继续回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多