bootstrap - jQuery Masonry and Ajax Append Items?
masonry js (13)
Agregué el siguiente código después de append
comando y todo estaba bien:
$grid.imagesLoaded().progress( function() {
$grid.masonry(''layout'');
});
La razón:
Las imágenes descargadas pueden desprenderse de los diseños de mampostería y hacer que los elementos de los elementos se superpongan. imagesLoaded resuelve este problema. imagesLoaded es un script separado que puede descargar en imagesloaded.desandro.com.
Estoy tratando de usar un poco de ajax y el complemento jQuery Masonry para agregar algunos artículos, ¿pero por alguna razón los nuevos elementos no están aplicando la mampostería?
Estoy usando
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 );
}
});
});
Sin embargo, los elementos que se adjuntan posteriormente no tienen la class="masonry-brick"
aplicada, lo que significa que rellenan completamente el posicionamiento.
Encontré una solución que funciona bien para mí. recarga cada medio segundo el diseño de una instancia de mampostería.
//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);
De esta manera, puedes agregar cosas usando ajax, y voilá, hay un diseño de mampostería.
Esta solución funciona para mí:
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);
}
}
});
Lo siguiente ha funcionado para mí. Tengo un ajax que devuelve un conjunto de elementos html (devuelve una vista parcial, desde el ajax) cuando hago clic en el botón Cargar más en mi página web. A continuación se muestra la vista parcial, que se genera dinámicamente.
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>
}
En el método ajax de devolución de llamada exitosa, he hecho lo siguiente, donde "respuesta" es el conjunto de elementos html que obtengo del código html anterior. Donde "divFeedList" es el elemento raíz donde muestro el conjunto de elementos html.
jQuery("divFeedList").append(response).masonry(''reloadItems'', response, true).masonry();
Por favor, hágamelo saber si la respuesta no está clara.
Para Masonry v3.2.2 (más reciente en el momento de esta publicación), esto es lo que funciona:
Asumiendo que newHtml es una cadena como esta:
<li>item 1</li><!--split-->
<li>item 2</li><!--split-->
<li>item 3</li>
Lo procesas así:
$.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);
});
}
¡Me tomó 2 horas descubrir esto!
Parece que la función de masonry
espera un objeto jQuery como su segundo parámetro y no una cadena HTML en bruto. Debería poder solucionar este problema envolviendo el parámetro de devolución de llamada exitosa de la siguiente manera:
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 );
}
});
});
Solo para las personas futuras que encuentran este problema y las soluciones anteriores no funcionan para ellos: encontré un problema con mi selector y el elemento que agregué al no tener el mismo caso, es decir, itemSelector
era .Card
pero estaba agregando <div class="card">
.
Espero que esto ayude.
Te está perdiendo llamada de diseño de mampostería. De acuerdo con los documentos, debe actualizar el diseño, ejecutando .masonry()
después de cada cambio (por ejemplo .masonry(''appended'')
):
$grid.masonry()
.append(elem)
.masonry(''appended'', elem)
// layout
.masonry();
(fuente: http://masonry.desandro.com/methods.html )
Tuve el mismo problema con mi listado de ajax, pude resolverlo llamando a las funciones de reloadItems
& layouts
después de que ajax respondiera:
var mediaItemContainer = $( ''#container'' );
mediaItemContainer.masonry( {
columnWidth: ''210px'',
itemSelector: ''.item''
} );
$( mediaItemContainer ).prepend( ''<div class="item">foo</div>'' );
$( mediaItemContainer ).masonry( ''reloadItems'' );
$( mediaItemContainer ).masonry( ''layout'' );
Tuvo un problema similar y en su lugar usó la siguiente línea (convertida para su código). Lo siento, no recuerdo dónde lo encontré.
En tu código reemplaza esto:
jQuery("#content").append(el).masonry( ''appended'', el, true );
Con este:
jQuery("#content").append(el).masonry( ''reload'' );
se explica claramente aquí 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 );
}
});
});
en su success function
, necesita que su respuesta "html" esté envuelta en un jquery object
y luego agregue usando html()
o append()
.
var $content = $( html );
jQuery("#content").append($content).masonry( ''appended'', $content );
el código final debe ser
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 );
}
});
});
success: function (response) {
if(response.length > 0) {
var el = js(response);
setTimeout(function () {
js("#masonry").append(el).masonry( ''appended'', el).masonry(''layout'');
}, 500);
}
}
funciona bien para mi
var mediaItemContainer = $( ''#container'' );
mediaItemContainer.masonry( {
columnWidth: ''210px'',
itemSelector: ''.item''
} );
$( mediaItemContainer ).prepend( ''<div class="item">foo</div>'' );
$( mediaItemContainer ).masonry( ''reloadItems'' );
$( mediaItemContainer ).masonry( ''layout'' );