jQuery Masonry и Ajax Добавить элементы? - PullRequest
29 голосов
/ 04 января 2012

Я пытаюсь использовать некоторые ajax и плагин jQuery Masonry для добавления некоторых элементов - но по какой-то причине новые элементы не получают кладку?

Я использую

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            jQuery("#content").append(html).masonry( 'appended', html, true );
        }
    });
});

Однако к элементам, которые добавляются впоследствии, не применяется class="masonry-brick", что означает, что они полностью заполняют позиционирование?

Ответы [ 13 ]

41 голосов
/ 04 января 2012

Похоже, что функция masonry ожидает объект jQuery в качестве второго параметра, а не необработанную строку HTML. Вы должны быть в состоянии это исправить, заключив параметр обратного вызова в успех следующим образом:

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            var el = jQuery(html);
            jQuery("#content").append(el).masonry( 'appended', el, true );
        }
    });
});
26 голосов
/ 23 марта 2014
var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );

Раствор

23 голосов
/ 22 мая 2012

Была похожая проблема и вместо этого использовалась следующая строка (преобразованная для вашего кода). Извините, я не помню, где я его нашел.

В вашем коде замените это:

jQuery("#content").append(el).masonry( 'appended', el, true );

С этим:

jQuery("#content").append(el).masonry( 'reload' );

http://masonry.desandro.com/methods.html

5 голосов
/ 30 мая 2016
success: function (response) {
  if(response.length > 0) {
     var el = js(response); 
     setTimeout(function () {
       js("#masonry").append(el).masonry( 'appended', el).masonry('layout');
     }, 500);
  }
}   

у меня отлично работает.

4 голосов
/ 13 июля 2016

Следующее сработало для меня.У меня есть AJAX, который возвращает набор элементов HTML (возвращает частичное представление из AJAX), когда я нажимаю кнопку «Загрузить еще» на моей веб-странице.Ниже приведено частичное представление, которое генерируется динамически.

foreach (var item in Model.SocialFeedList)
{
        <div class="grid-item">
            <div class="grid-inner">
                <div class="img-holder" style="background-image:url(imageURLHere)">
                </div>
                <div class="content-area">
                    <h3><a target="_blank" href="SomeLink">TitleOfTheLink</a></h3>
                    <p>SomeDescription</p>
                    <h5 class="date"><span>Published</span>: 2016/07/13</h5>
                </div>
            </div>
        </div>
}

В ajax-методе обратного вызова я сделал следующее, где «response» - это набор элементов html, которые я получаю из вышеупомянутого html.Где "divFeedList" - это корневой элемент, в котором я показываю набор HTML-элементов.

jQuery("divFeedList").append(response).masonry('reloadItems', response, true).masonry();

Пожалуйста, дайте мне знать, если ответ неясен.

3 голосов
/ 10 марта 2017

Я добавил следующий код после команды append, и все было в порядке:

$grid.imagesLoaded().progress( function() {
    $grid.masonry('layout');
});

Причина:

Загруженные изображения могут сбрасывать макеты кладки и приводить к перекрытию элементов. imagesLoaded решает эту проблему. imagesLoaded - это отдельный скрипт, который можно загрузить по адресу imagesloaded.desandro.com.

источник

1 голос
/ 26 апреля 2016

У меня была такая же проблема с моим списком ajax, я мог решить ее, вызвав reloadItems & layouts функции после ответа ajax:

var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );
1 голос
/ 21 января 2016

Вам не хватает раскладки Masonry. В соответствии с документацией вам необходимо обновить макет, выполняя .masonry() после каждого изменения (например, .masonry('appended')):

$grid.masonry()
  .append(elem)
  .masonry('appended', elem)
  // layout
  .masonry();

(источник: http://masonry.desandro.com/methods.html)

0 голосов
/ 30 мая 2017

здесь четко объяснено https://masonry.desandro.com/methods.html#prepended

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            jQuery("#content").append(html).masonry( 'appended', html, true );
        }
    });
});

в вашем success function, вам нужно, чтобы ваш ответ "html" был заключен в jquery object и затем добавлен с помощью html() или append().

var $content = $( html );
jQuery("#content").append($content).masonry( 'appended', $content );

окончательный код должен быть

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            var $content = $( html );
            jQuery("#content").append($content).masonry( 'appended', $content );
        }
    });
});
0 голосов
/ 21 марта 2015

Для Masonry v3.2.2 (последняя на момент написания этого поста) вот что работает:

Предполагая, что newHtml представляет собой строку, подобную этой:

<li>item 1</li><!--split-->
<li>item 2</li><!--split-->
<li>item 3</li>

Вы обрабатываете ее какэто:

$.get(apiUrl, function(newHtml) {
    var textArr = newHtml.split("<!--split-->");
    var elArr = [];
    $.each(textArr, function(i,v) {
        if (v) {
            elArr.push($(v)[0]);
        }
    });
    $(this).append(elArr);
    $container.waitForImages( function() {
        $container.masonry('appended', elArr);
    });
}

Мне понадобилось 2 часа, чтобы узнать это!

...