jQuery Masonry и Ajax добавляют элементы?

Я пытаюсь использовать некоторые 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 ответов


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

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

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

С этого:

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

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


получается, что 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 );
        }
    });
});

var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );

решение


следующее сработало для меня. У меня есть 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 успеха я сделал ниже, где "ответ" - это набор html-элементов, которые я получаю из вышеуказанного html. Где "divFeedList" - корневой элемент, где я показываю набор html элементы.

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

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


у меня была такая же проблема с моим списком 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' );

success: function (response) {
  if(response.length > 0) {
     var el = js(response); 
     setTimeout(function () {
       js("#masonry").append(el).masonry( 'appended', el).masonry('layout');
     }, 500);
  }
}   

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


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

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

причина:

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

источник


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

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

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


Это решение работает для меня:-

  jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    dataType: 'json',
    cache: false,
    success: function(response) {
      if (response.length > 0) {
        var $container = $('#container');
        var msnry = $container.data('masonry');
        var elems = [];
        var fragment = document.createDocumentFragment();
        for (var x in response) {
          var elem = $(response[x]).get(0);
          fragment.appendChild(elem);
          elems.push(elem);
        }
        $container.appendChild(fragment);
        msnry.appended(elems);
      }
    }
  });

только для будущих людей, которые находят эту проблему, и вышеуказанные решения не работают для них: я нашел проблему с моим селектором и элементом, который я добавил, Не имея того же случая, т. е. itemSelector был .Card но я добавлял <div class="card">.

надеюсь, что это помогает.


это ясно объясняется здесь 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 );
        }
    });
});

для кладки 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 часа, чтобы узнать это!


Я нашел решение, которое работает хорошо для меня. он перезагружает каждые полсекунды макет экземпляра кладки.

//initialization of a masonry object:

var msnry = new Masonry("#container",{
itemSelector: '#post',
gutter: 15
}); 

//thread that makes the magic happens:

setInterval(function(){
msnry.reloadItems();
msnry.layout();
},500);

таким образом, вы можете добавлять вещи с помощью ajax, и вуаля, есть макет кладки.