可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to use some ajax and the jQuery Masonry plugin to add some items - but for some reason the new items aren't getting the masonry applied ?
I'm using
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 );
}
});
});
However the items that are appended subsequently don't have the class="masonry-brick"
applied which means that they stuff up completely the positioning ?
回答1:
Had a similar problem and instead used the following line (converted for your code). Sorry, I don't recall where I found it.
In your code replace this:
jQuery("#content").append(el).masonry( 'appended', el, true );
With this:
jQuery("#content").append(el).masonry( 'reload' );
http://masonry.desandro.com/methods.html
回答2:
It appears that the masonry
function expects a jQuery object as its second parameter and not a raw HTML string. You should be able to fix this by wrapping the success callback parameter like so:
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 );
}
});
});
回答3:
var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
columnWidth: '210px',
itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );
Solution
回答4:
Following has worked for me. I have an ajax which returns set of html items (returns a partial view, from the ajax) when I click a load more button in my web page. Below is the partial view, which is dynamically generated.
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>
}
In the success callback ajax method, I have done the below,where "response" is the set of html items I get from the above html. Where "divFeedList" is the root element where I show the set of html elements.
jQuery("divFeedList").append(response).masonry('reloadItems', response, true).masonry();
Please let me know if the answer is unclear.
回答5:
I had the same problem with my ajax listing, i could solve it by calling reloadItems
& layouts
functions after ajax respond :
var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
columnWidth: '210px',
itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );
回答6:
success: function (response) {
if(response.length > 0) {
var el = js(response);
setTimeout(function () {
js("#masonry").append(el).masonry( 'appended', el).masonry('layout');
}, 500);
}
}
works fine for me.
回答7:
I added the following code after the append
command and everything was fine:
$grid.imagesLoaded().progress( function() {
$grid.masonry('layout');
});
The reason:
Unloaded images can throw off Masonry layouts and cause item elements to overlap. imagesLoaded resolves this issue. imagesLoaded is a separate script you can download at imagesloaded.desandro.com.
source
回答8:
You are missing Masonry layout call. According to the docs you need to refresh the layout, executing .masonry()
after every change (for instance .masonry('appended')
):
$grid.masonry()
.append(elem)
.masonry('appended', elem)
// layout
.masonry();
(source: http://masonry.desandro.com/methods.html)
回答9:
This solution works for me:-
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);
}
}
});
回答10:
Just for future people who find this issue and the above solutions don't work for them: I found an issue with my selector and the element I added not having the same case, i.e. itemSelector
was .Card
but I was appending <div class="card">
.
Hope this helps.
回答11:
it is clearly explained here 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 );
}
});
});
in your success function
, you need your response "html" to be wrapped in a jquery object
and then append using html()
or append()
.
var $content = $( html );
jQuery("#content").append($content).masonry( 'appended', $content );
the final code should be
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 );
}
});
});
回答12:
For Masonry v3.2.2 (latest at the time of this post), this is what works:
Assuming newHtml is a string like this:
<li>item 1</li><!--split-->
<li>item 2</li><!--split-->
<li>item 3</li>
You process it like this:
$.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);
});
}
Took me 2 hours to find out this!
回答13:
I found a solution that works fine for me. it reloads every half second the layout of an instance of masonry.
//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);
this way, you can append things using ajax, and voilá, there is the masonry layout.