Подтвердить что ты не робот

Захват события после того, как элемент раздела закончил загрузку

У меня есть div, содержащий разделы:

<div class="Placeafterthis">
</div>
...
<div class="k-content">
<section class="rbs-section" id="id1" name="">
.. // section content
</section>
<section class="rbs-section" id="id2" name="">
.. // section content
</section>
<section class="rbs-section" id="id3" name="">
.. // section content
</section>
</div>

Теперь в основном эти разделы загружаются, когда DOM готов. Есть ли способ проверить, когда определенная часть закончила загрузку? После его полной загрузки мне нужно клонировать этот раздел и поместить его сразу после diva Placeafterthis. Любые предложения о том, как я могу это достичь?

4b9b3361

Ответ 1

Вы можете использовать MutationObserver, чтобы определить, когда узлы добавлены в .k-content, clone с помощью jQuery и добавьте их после .Placeafterthis (demo):

var kContent = $('.k-content'); // the original container in which the items will be placed
var $Placeafterthis = $('.Placeafterthis'); // the cloned elements target marker placeholder

function mutationHandler(mutation) { // the mutation handler will deal with the addition of new nodes to the original container
    var addedNodes = mutation.addedNodes;

    if (!addedNodes.length) { // if no added nodes return
        return;
    }

    $.each(addedNodes, function () { // iterate the add nodes
        var $element = $(this);

        if (!$element.hasClass('rbs-section')) { // if the node doesn't have the right class continue to the next one
            return true;
        }

        var $prevSections = $Placeafterthis.find('~ .rbs-section'); // find if there are already sections append to the target
        var $target = $prevSections.length === 0 ? $Placeafterthis : $prevSections.last(); // if there are sections take the last, if not use the marker

        /** note that using .clone(true) will also clone all jQuery event handlers and data from the original element. If you don't need this behavior, just use .clone() **/

        $target.after($element.clone(true)); // append after the target
    });
}

var observer = new MutationObserver(function (mutations) { // create a new mutation observer
    mutations.forEach(mutationHandler);
});

var config = { // config should include only childList because we just want added nodes 
    childList: true
};

observer.observe(kContent.get(0), config); // watch the original container with the observer

Ответ 2

Я получил код клонирования здесь и, при необходимости, изменил его. Использование async в последнем теге script всегда работает для меня, но используйте его на внешнем script, я просто сделал его встроенным для демонстрационных целей. Самое главное, что script находится в теге закрывающего тела, чтобы избежать блокировки. Прикрепите прослушиватель событий к событию DOMContentLoaded, когда секции должны быть готовы (если в разделах нет iframe...). Я покрасил все границы элементов для удобства просмотра.

ОБНОВЛЕНИЕ:. Прочитав сообщение guest271314, он напомнил мне, что я пренебрег рассмотрением идентификаторов клонов. В качестве клонов у них были одинаковые идентификаторы, поэтому я немного переработал его и добавил немного Звездных войн.

section[id^="id"] {
  border: 3px solid silver;
  width: 200px;
  height: 25px;
}
section[id^="st"] {
  border: 3px solid black;
  width: 200px;
  height: 25px;
}
.kamino-content {
  border: 3px dashed blue;
  width: 200px;
  height: 200px;
}
.Placeafterthis {
  border: 3px dotted orange;
  width: 200px;
  height: 75px;
}
<div class="Placeafterthis">
  Place After This
</div>

<div class="kamino-content">
  <section class="fett-dna" id="id1" name="jango">
    .. // section content
  </section>
  <section class="fett-dna" id="id2" name="jango">
    .. // section content
  </section>
  <section class="fett-dna" id="id3" name="jango">
    .. // section content
  </section>
  Kamino-Content
</div>



<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js"></script>

<!-- You should really do this: <script async src="external.js"></script> -->

<script async>
  document.addEventListener("DOMContentLoaded", cloneLab, false);

  function cloneLab() {
    var vat = $('.kamino-content'),
      squad = $('.fett-dna').size(),
      fett = vat.find('.fett-dna');
    fett.each(function(idx, val) {
      var trooper = $(this).clone();
      trooper.attr("id", "st" + (squad + idx)).attr("name", "stormtrooper");
      trooper.insertAfter('.Placeafterthis');
    });
  }
</script>

Ответ 3

Попробуйте использовать $.get(), добавляя ответ на .k-content, фильтруя id выбранного элемента section при ответе на клонирование, добавьте символ в id, чтобы предотвратить дублирование id в DOM, вставить после .Placeafterthis; define getSections, заданный с помощью объекта jQuery prom как this, рекурсивно вызовите getSections, чтобы вернуть Array.prototype.shift() в массив sections, чтобы возвращать $.get() для каждого элемента в индексе 0 по порядку, иначе, если false возвращаемый оператором !! на section[0] return this.promise()

    // `id`s of `section` elements to append to `.k-content`
    var sections = ["#id1", "#id2", "#id3"];
    // selected `id` to do stuff with
    var selected = sections[1];
    // container
    var container = $(".k-content");
    // `complete` handler for `$.get()` requests
    function selectedId(html, textStatus, jqxhr) {
        // decode `data` : `id` sent with request
        var id = decodeURIComponent(this.url.split("?")[1]).split("=")[1];
        // append `section` to `container`
        container.append($(html).filter(id));
        // if `selected` appended to `container` ,
        // and `selected` is not in `DOM` directly after `.Placeafterthis` element
        // clone `selected` , append after `.Placeafterthis` element
        if (container.find(selected).is("*") 
          && !$(".Placeafterthis + " + selected + "-a").is("*")) {
            var clone = $(selected, container).clone()
                        .attr("id", selected.slice(1) + "-a");
            $(".Placeafterthis").after(clone)
        }
    }

    var getSections = function getSections() {
        var p = sections.shift();
        return !!sections 
               && $.get("http://fiddle.jshell.net/guest271314/rvt8evoy/show/"
               , {"id": p}, selectedId).then(getSections)
    };

    getSections()
    .then(function() {
      console.log("complete")
    })

jsfiddle http://jsfiddle.net/1d6vmdpt/5/

Ответ 4

Если вы поместите свой script после последнего раздела:

<section class="rbs-section" id="id3" name="">
.. // section content
</section>

<script>
  (function() {
    var s3 = document.getElementById("id3");
    ...
  })();
</script>

то он будет вызываться точно после того, как этот элемент и его предшественники появятся в DOM.