I am using Handlebars http://handlebarsjs.com/ and Masonry https://masonry.desandro.com/ to get some JSON data and add it to the dom every 5 mins using Jquery prepend.
The problem I am having is the first time I add the data to the dom Masonry works fine and displays horizontally
eg.
but 5 mins later when the new data gets added it just drops it vertically. It is supposed to prepend and move the other elements across.
eg.
function to add to dom.
function AddToDom() {
console.log("AddToDom");
setTimeout(function() {
cardContainer.prepend(compiledCardTemplate(model)).masonry({
itemSelector: '.grid-item',
columnWidth: '.grid-item',
// percentPosition: true,
horizontalOrder: true,
fitWidth: true
});
}, 1000);
}
I am using setTimeout as a delay from the retrieval of data to adding to dom.
edit:
After suggestions from Ali, I tried this
function AddToDom() {
setTimeout(function() {
let $items = compiledCardTemplate(model);
cardContainer.append($items).masonry('prepended', $items);
}, 1000);
}
but I am getting this error
masonry not initialized. Cannot call methods, i.e. $().masonry("prepended")
edit: for clarity
let cardContainer = $(".wrapper");
let cardTemplate = $("#card-template").html();
let compiledCardTemplate = Handlebars.compile(cardTemplate);
let model = {
posts: []
}
edit: called functions
// docuemnt init
$(document).ready(function () {
GetData();
AddToDom();
setInterval(AddToDom, 50000);
});
Any help much appreciated.
Thanks in advance.
Assuming your cardContainer is a Masonry Grid, to add to the start (prepend to start) more items to the Grid you need to call Masonry#prepended().
The above snippet can be written as:
function addToDOM(model) {
setTimeout(function() {
var $item = $(compiledCardTemplate(model));
$cardContainer
.prepend($item) // to prepend to DOM node
.masonry('prepended', $items); // to notify masonry
}, 1000);
}
Solved the issue with code below (Many thanks to #riyza-ali)
function AddToDom() {
setTimeout(function () {
let items = compiledCardTemplate(model);
let $items = $(items);
let grid = wrapper.masonry({
itemSelector: '.grid-item',
columnWidth: '.grid-item',
horizontalOrder: true,
fitWidth: true
});
grid.prepend($items).masonry('prepended', $items);
}, 1000);
setTimeout(AddToDom, 50000);
}
Related
I put these code at the last lows before </body>
<script type="text/javascript">
var $grid = $('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 230
});
$grid.masonry(); //not work
function test() {
$grid.masonry(); //it work
}
</script>
when I run the page, show this:
http://i.stack.imgur.com/P3OgW.jpg masonry is not working.
Now I change the webbrowser(chrome/IE/Firefox)width, is work. http://i.stack.imgur.com/ZumGW.jpg
So, I create a function name test with code " $grid.masonry();" and run it, it work.
I'm surprised that the javascript will run after the page has load ready as unually, but here i must run the function test manually to achieve it.
what’s going on?
/************************ and still not working ***************************/
<script type="text/javascript">
$(document).ready(function() {
var $grid = $('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 230
});
$grid.masonry(); // not work
console.log('the code is running!'); // it work
});
function test() {
var $grid = $('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 230
});
$grid.masonry(); // it work
}
</script>
/*****************************************************************/
OK,I found a way to resolved it but not elegant. like this:
var timeId = setTimeout(function() {
$grid.masonry();
}, 100);
I am trying to compile a basic jQuery plugin which shows a div upon provided options when invoking:
select if a checkbox should be checked after X milliseconds or after X px on scroll,
if one of those two options are selected, set a delay value or scroll distance in px
otherwise do nothing
Example of desired options invoke:
$(document).ready( function() {
$('#testInput').testing({
myMethod : delay,
myValue : 2000
});
});
My current progress here: JSFiddle (it's not much as currently I'm still at a beginning of the learning curve)
After some fiddling i managed to get this working (kinda). Plugin seems to be working fine. Except there is some bug with the scroll function which i have to sort it out additionaly - it loops and changes checkbox states indefinitely instead just once.
Here is a working fiddle
And modified code:
(function($) {
$.fn.testing = function( options ) {
// Settings
var settings = $.extend({
delay : null,
delayTime : null,
scrolling : null,
scrollDist : null
}, options);
return this.each( function() {
var self = this;
// Timeout
setTimeout(function (){
$(self).prop('checked', settings.delay);
}, settings.delayTime);
// Scroll
if ($(window).scrollTop() > settings.scrollDist) {
$(this).prop('checked', settings.scrolling);
};
});
}
}(jQuery));
// Plugin invoke
$(window).on("load resize scroll",function(){
$('#testInput').testing({
delay : false,
delayTime : null,
scrolling : true,
scrollDist : 20,
});
});
I have tried to built a continuous content slider in jQuery.
If you don't hover over it, then it works fine, it slides (even though I feel like I made it happen in a wrong way).
When you hover it then it stops, but only for 2 seconds. As you'd imagine, it should stay stopped until the cursor is removed. Maybe the interval is not cleared properly?
Generally the whole thing works improperly when you starts to hover/unhover.
Here's a demo of my plugin: http://jsfiddle.net/T5Gt3/
(function ($) {
$.fn.productSlider = function(options) {
var defaults = {
speed: 2000
};
var config = $.extend(defaults, options);
this.each(function() {
var $this = $(this),
$scrollable = $this.find('#content-product-slider-inner'),
timeLeft;
function animateScrollable() {
$scrollable.animate({ left: '-120px' }, config.speed, 'linear', function() {
$scrollable.css({ left: '0px' }).find('a:first-child').remove().appendTo($scrollable);
});
};
animateScrollable();
var timer = setInterval(animateScrollable, config.speed);
$scrollable.mouseover(function() {
$scrollable.stop();
clearInterval(timer);
});
$scrollable.mouseout(function() {
animateScrollable();
var timer = setInterval(animateScrollable, config.speed);
});
});
return this;
};
})(jQuery);
Any help would be greatly appreciated.
$(".event_list_inner_wrapper").live({
mouseenter: function () {
$(this).find('.front_side').fadeOut(600).hide();
$(this).find('.back_side').fadeIn(600).show();
},
mouseleave: function () {
$(this).find('.back_side').fadeOut(600).hide();
$(this).find('.front_side').fadeIn(600).show();
}
});
That's code I used for a project that was similar to your description. Basically, bind the mice events, and do your thing.
I'm using jQuery Mobile, I have a bunch of javascript code that is executed like this
$(document).on("pageshow", function () {
$(function () {
var $container;
$container = $(".items-section");
return $container.imagesLoaded(function () {
$container.masonry({
itemSelector: "article.hlisting"
});
return $container.masonry({
isFitWidth: true
});
});
});
});
But since I'm retrieving objects via ajax and redrawing them on screen, some of the same code needs to be also executed inside of a $(document).on("scrollstop", function()
My question is. How can I refactor the code in order to be called on two cases?
If it's exactly the same code that you want to be called then just pass multiple, space separated events as the first argument:
$(document).on("pageshow scrollstop", function() {
// your code here
});
I am implementing David DeSandro's JQuery Masonry plugin for a site i'm trying to build. I am trying to run a callback on the masonry function so that i can scroll to the relevant part in the page after it runs but for some reason can't get it to work when I have the animation turned on. The docs can be seen at http://desandro.com/demo/masonry/docs/#options. When I run the following code it works fine and the alert only happens once the masonry function has run:
$wall.masonry(
{
columnWidth: 216,
itemSelector: '.box:not(.invis)',
animate: false
},
function()
{
alert("Finished?");
}
);
However when i run the following code with the animation options included the alert runs before the animation has finished:
$wall.masonry(
{
columnWidth: 216,
itemSelector: '.box:not(.invis)',
animate: true,
animationOptions: {
duration: speed,
queue: false
}
},
function()
{
alert("Finished?");
}
);
I would really appreciate any pointers anyone can give me as to how to prevent the alert happening until the animation has completed as i'm stumped! Thanks so much for your help,
Dave
There's something you can do, but it to work in your sense requires a small hack:
The object to animationOptions passed can take a complete property, which defines a function which will be fired after the animation is complete.
The problem is, this will be the case for each and every of your blocks, since every block is animated separately. But you could get around this like so:
var boxCount = $wall.find('box').size(),
counter = 0,
onComplete = function() {
if (counter < boxCount) counter++;
else {
alert("Finished?"); // <-- Here goes your actual callback!
counter = 0;
}
}
$wall.masonry({
columnWidth: 216,
itemSelector: '.box:not(.invis)',
animate: true,
animationOptions: {
duration: speed,
queue: false,
complete: onComplete
}
});