jQuery chaining .load() requests?

2020-03-26 06:40发布

问题:

So I was working with jQuery's .load() just now and it looks like we can't configure $("#example").load('./uri.ext #ID') to chain as such:

$("#example").load('./uri.ext #ID1').load('./uri.ext #ID2').load('./uri.ext #ID3')

Which of course would be useful if we had a template file of DIVs or something to dynamically build a page and not store the HTML in a string variable or something along those lines... plus, we could keep several of these in one file.

Ideally I would like to nest things as such with that command:

<div id="example">
    <div id="ID1">
        <div id="ID2">
            <div id="ID3">
            </div>
        </div>
    </div>
</div>

The problems I'm getting are two-fold. First, the async : true property of the request causes the next request to fire and the placement doesn't preform as intended. I had then attempted to run nested $("#example").load('./uri.ext #ID1').ajaxCompletes(function () {/next .load() in sequence/})` which ended up in a recursive trap that didn't end and kept sending requests for those files.

Any thoughts on how to accomplish what I'm after with a syntax/method like I had attempted? Also, if this isn't a problem and just a misunderstanding on my part of jQuery's chaining, an explanation I would be very thankful for any explanation into that.

回答1:

You would need to nest them in the callback functions to achieve this:

$('#example').load('./uri.ext #ID1', function() {
  $('#ID1').load('./uri.ext #ID2', function() {
    $('#ID2').load('./uri.ext #ID3', function() {
      // load successful
    });
  });
});

EDIT for ES6 standards:

 $('#example').load('./uri.ext #ID1', () => {
      $('#ID1').load('./uri.ext #ID2', () => {
        $('#ID2').load('./uri.ext #ID3', () => {
          // load successful
        });
      });
    });


回答2:

Upvoted the question and the answer.

I'm providing a slightly more elegant solution using a recursive call in case others want to build on it. Note that this doesn't directly answer the context of the original question. It's in the context of my own solution, but the idea is the same.

var App = App || {};

App.Quiz = (function ($) {
    "use strict";

    var _templates = [{ target: "#quiz_main_template", url: "/UserControls/Quiz/Quiz_Main.tmpl.htm" },
        { target: "#quiz_media_left_template", url: "/UserControls/Quiz/Quiz_Media_Left.tmpl.htm" },
        { target: "#quiz_media_right_template", url: "/UserControls/Quiz/Quiz_Media_Right.tmpl.htm" },
        { target: "#quiz_no_media_template", url: "/UserControls/Quiz/Quiz_No_Media.tmpl.htm" }]

    function loadTemplates(templates, callback) {
        if (templates.length) {
            var nextTemplate = templates.pop();
            $(nextTemplate.target).load(nextTemplate.url, loadTemplates(templates, callback));
        } else {
            callback.call();
        }
    }

    function init() {
        loadTemplates(_templates, function () { alert("Done!");})
    }

    return {
        init: init
    };
})(jQuery);

$(function () {
    App.Quiz.init();
});