jQuery, автоматически применять функцию к загруженным элементам - PullRequest
3 голосов
/ 02 февраля 2020

Я знаю, что могу запускать функции после вызова ajax, используя опцию успеха, например, для манипулирования загруженным контентом, например

$.ajax({
    url : url,
    ...
    success: function(data, textStatus, jqXHR){
        alert($('#overlay > #popup input').length);
    },
    ...
});

Я также знаю, что могу применять интерактивные события, такие как нажатие ajax загруженный контент через

$(document).on('click','#overlay > #popup',function(e) {
    alert($(e.target).find('input').length);
});

, который работает конечно.

Я пытаюсь найти способ, сделать то же самое предупреждение автоматически, только после того, как контент был загружен, вместо того, чтобы щелкнуть по нему, как это (извините за этот плохой нерабочий пример)

$(document).on('load','#overlay > #popup',function(e) {
    alert($(e.target).find('input').length);
});

ПРИМЕР для объяснения, а не часть вопроса

В конце я хочу применить вычисленные стили к загруженному входу [type = radio], используя jQuery (индивидуальная ширина, в зависимости от атрибута значения, будет автоматически отображаться в css псевдоэлементе ::after {content: attr(value);})

Текущий html выход из php функция

<label class="fl" style="width: 80px;">
    <input type="radio" name="' . $name . '" value="' . $year . '" ' . ($year == date('Y')?'checked="checked"':'') . '/>
</label>

текущий результат выглядит следующим образом

four styled input type radio

, где видимые заголовки являются элементами :: after , Только я хочу - в случае разной длины значения - ширина задается автоматически, а не жестко.

Может кто-нибудь открыть этот узел в моей голове?

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Если вы знаете, какой элемент будет добавлен к завершению ajax, вы можете присоединить к нему MutationObserver. Когда сработает наблюдатель, проверьте, существует ли интересующий вас элемент как потомок:

new MutationObserver((_, observer) => {
  if (popup.querySelector('input')) {
    console.log('Input descendant now exists!');
    // Don't keep the observer active once it's served its purpose:
    observer.disconnect();
  }
}).observe(popup, { childList: true });

// example of asynchronous ajax call
setTimeout(() => {
  popup.innerHTML = '<div>popup content<input></div>';
}, 2000);
<div id="overlay">
  <div id="popup">
  </div>
</div>

Но хотя это возможно , это довольно плохая практика. Если вы знаете, когда будет создан элемент, было бы гораздо лучше поместить все функциональные возможности для этого в обратный вызов ajax success, чем использовать MutationObserver (который обычно следует резервировать только для ситуаций, когда другие параметры невозможно, например, когда у вас нет контроля над кодом).

Для элементов, загруженных после сетевого запроса, вы также можете использовать ajaxComplete с jQuery:

const callback =  () => {
  if (popup.querySelector('input')) {
    console.log('Input descendant now exists!');
    // Don't keep the observer active once it's served its purpose:
    $(document).off('ajaxComplete', callback);
  }
};
$(document).on('ajaxComplete', callback);

// example of asynchronous ajax call
$.get({
  url: 'https://jsonplaceholder.typicode.com/todos/1',
  success() {
    popup.innerHTML = '<div>popup content<input></div>';
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="overlay">
  <div id="popup">
  </div>
</div>
0 голосов
/ 03 февраля 2020

РЕШЕНИЕ на основе ответа @CertainPerformance

$(document).on('ajaxComplete', function(e){
    var i = $('#overlay > #popup').find('input[type="radio"],input[type="checkbox"]');
    i.each(function(index){
        var el = $(this);
        var l = el.closest('label');
        var v = el.attr('value');
        var fs = el.css('font-size');
        $('body').prepend($('<span></span>').attr('id','st'+index).addClass('st').html(v).css({fontSize:fs}));
        var testel = $('body > span#st'+index);
        var w = testel.outerWidth();
        l.css({width:w+30}); /* +30 instead of a padding */
    });
    $('body > span.st').remove();
});

Работает именно так, как я хочу. И все это экономит ajax полезную нагрузку, как и предполагалось.

Вот результат (с бессмысленным содержанием, только для демонстрации)

input radio with nonsense content, for demo only

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...