jetpack infinite scroll and isotope relayout - scroll

How to relayout page when new elements are added by infinite scroll.
jetpack said you can relayout page with this event. (we trigger an event after posts are appended. To make use of this event, simply catch the post-load event when it fires on document.body:)
( function( $ ) {
$( document.body ).on( 'post-load', function () {
// New posts have been added to the page.
} );
} )( jQuery );
How to relayout page with isotope. I am using isotope for masonry layout.

$( document.body ).on( 'post-load', function () {
$container.masonry().isotope( {
resizable: true,
itemSelector: '.grid-item',
layoutMode : 'masonry',
gutter: 0
} );
$container.isotope('reloadItems');
isotope( 'reLayout', true );
} );

Related

.click function ask me twice for confirmation

I have this issue, maybe you guys can help me fix it.
Botton Delete:
<button type="button" class="del-trade">Delete</button>
Ajax code:
$(function(){
$("#modaledittrade").on("show.bs.modal", function (e) {
$('.del-trade').click(function(){
var id = $(e.relatedTarget).attr( "data-id" );
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
});
});
The code is give me loop twice... I mean ask me for function confirm() twice.
Video demo: http://sc.sny.pt/sJH6
On what I see, I think reason is because you create multiple instance of onclick event:
first time you delete (when modal is shown) create onclick event and the
second time that create a second event.
This should work :
$(function(){
/*$("#modaledittrade").on("show.bs.modal", function (e) {
}); */
$('.del-trade').click(function(){
var id = $(e.relatedTarget).attr( "data-id" );
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
});
You can pull the click event out, and this will still work as expected, using on:
$(document).on("click", '.del-trade', function(e){
var id = $(e.relatedTarget).attr( "data-id" ); // can still get ID same way
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
EDIT: Or, when the modal is hidden, turn off the delete click action:
$("#modaledittrade").on("hide.bs.modal", function (e) {
$('.del-trade').off("click");
});
$("#modaledittrade").on("show.bs.modal", function (e) {
$('.del-trade').on("click", function(e) { .. });
});

Mootools Add click event with Drag.Cart

I use this example under jsfiddle.net, to build a drag&drop system and if I create a click event on shirts images (draggables), this event doesn't work.
How to combine drag and click events to the draggables elements with Mootools?
window.addEvent('domready', function(){
$$('.item').addEvent('mousedown', function(event){
//event.stop();
// `this` refers to the element with the .item class
var shirt = this;
var clone = shirt.clone().setStyles(shirt.getCoordinates()).setStyles({
opacity: 0.7,
position: 'absolute'
}).inject(document.body);
var drag = new Drag.Move(clone, {
droppables: $('cart'),
onDrop: function(dragging, cart){
dragging.destroy();
if (cart != null){
shirt.clone().inject(cart);
cart.highlight('#7389AE', '#FFF');
}
},
onEnter: function(dragging, cart){
cart.tween('background-color', '#98B5C1');
},
onLeave: function(dragging, cart){
cart.tween('background-color', '#FFF');
},
onCancel: function(dragging){
dragging.destroy();
}
});
drag.start(event);
});
// This doesn't work
$$('.item').addEvent('click', function(event){
console.log('click');
});
});
the event.stop(); will preventDefault and stopPropagation so the mousedown won't bubble into click.
furthermore, it clones and applies stuff to a new element and somewheere along the lines, mootools-more will stop the event once again.
so replace the event.stop with this.fireEvent('click', event); to bubble it up manually - though strictly speaking, a click is on mouseup and you kind of need to wait for that instead.
http://jsfiddle.net/dimitar/qsjj1jpe/4/

tap event fired after taphold jQuery Mobile 1.1.1

I am developing an app for iOS using Phonegap bundled with jQuery Mobile 1.1.1. I have a div on my page that is listening for both tap and taphold events.
The problem I am facing is that the tap event is fired after the taphold event once I lift my finger. How do I prevent this?
A solution is provided here but is this the only way to do this? Kinda nullifies the whole point of having two different events for tap & taphold if you need to use a boolean flag to differentiate the two.
Following is my code:
$('#pageOne').live('pageshow', function(event) {
$('#divOne').bind('taphold', function (event) {
console.log("TAP HOLD!!");
});
$('#divOne').bind('tap', function () {
console.log("TAPPED!!");
});
});
Would greatly appreciate the help. Thanks!
Simply set this at the top of your document or anywhere before you define your even:
$.event.special.tap.emitTapOnTaphold = false;
Then you can use it like this:
$('#button').on('tap',function(){
console.log('tap!');
}).on('taphold',function(){
console.log('taphold!');
});
[Tried and Tested]
I checked jQuery Mobile's implementation. They are firing the 'tap' event after 'taphold' every time on 'vmouseup'.
Workaround would be not to fire the 'tap' event if the 'taphold' has been fired. Create a custom event or modify the source as per you need as follows:
$.event.special.tap = {
tapholdThreshold: 750,
setup: function() {
var thisObject = this,
$this = $( thisObject );
$this.bind( "vmousedown", function( event ) {
if ( event.which && event.which !== 1 ) {
return false;
}
var origTarget = event.target,
origEvent = event.originalEvent,
/****************Modified Here**************************/
tapfired = false,
timer;
function clearTapTimer() {
clearTimeout( timer );
}
function clearTapHandlers() {
clearTapTimer();
$this.unbind( "vclick", clickHandler )
.unbind( "vmouseup", clearTapTimer );
$( document ).unbind( "vmousecancel", clearTapHandlers );
}
function clickHandler( event ) {
clearTapHandlers();
// ONLY trigger a 'tap' event if the start target is
// the same as the stop target.
/****************Modified Here**************************/
//if ( origTarget === event.target) {
if ( origTarget === event.target && !tapfired) {
triggerCustomEvent( thisObject, "tap", event );
}
}
$this.bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
$( document ).bind( "vmousecancel", clearTapHandlers );
timer = setTimeout( function() {
tapfired = true;/****************Modified Here**************************/
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
}, $.event.special.tap.tapholdThreshold );
});
}
};
You can use stopImmediatePropagation() method of jquery to solve this issue. According to the explanation in jquery api, stopImmediatePropagation() method
"Keeps the rest of the handlers from being executed and prevents the
event from bubbling up the DOM tree."
put this in your taphold event handler... this suggestion assumes o is a jQuery object that fired the taphold
jQuery(o).one('tap click', function(){ return false; });
the binding to the one method will fire the event only once. returning false will stop the execution of that event if it was an < a > tag.
Since swipe, triggers taphold then I was able to keep it simple with:
$(c).bind("taphold",function(e){
if(e.target.wait){
e.target.wait = false;
}else{
alert("fire the taphold");
}//eo if not waiting
});
$(c).bind("swipe",function(e){
e.target.wait = true;//taphold will come next if I don't wave it off
alert(e.target.text+"("+e.target.attributes.dataId.value+") got swiped");
return false;
});
To support tap too then I'd defer the wait clear until the tap event which will also always fire.
I still have problems, with jquery-mobile's taphold, I solved the problem of the click called after taphold, putting a timeout on the element.
JQM 1.4 with emitTapOnTaphold = false;
Example:
$(".element").on("taphold", function () {
        // function her
         setTimeout (function () {
             $(this).blur();
         400);
});
$.event.special.tap = {
tapholdThreshold: 750,
setup: function() {
var thisObject = this,
$this = $( thisObject );
$this.bind( "vmousedown", function( event ) {
if ( event.which && event.which !== 1 ) {
return false;
}
var origTarget = event.target,
origEvent = event.originalEvent,
/****************Modified Here**************************/
tapfired = false,
timer;
function clearTapTimer() {
clearTimeout( timer );
}
function clearTapHandlers() {
clearTapTimer();
$this.unbind( "vclick", clickHandler )
.unbind( "vmouseup", clearTapTimer );
$( document ).unbind( "vmousecancel", clearTapHandlers );
}
function clickHandler( event ) {
clearTapHandlers();
// ONLY trigger a 'tap' event if the start target is
// the same as the stop target.
/****************Modified Here**************************/
//if ( origTarget === event.target) {
if ( origTarget === event.target && !tapfired) {
triggerCustomEvent( thisObject, "tap", event );
}
}
$this.bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
$( document ).bind( "vmousecancel", clearTapHandlers );
timer = setTimeout( function() {
tapfired = true;/****************Modified Here**************************/
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
}, $.event.special.tap.tapholdThreshold );
});
}
};
#Akash Budhia: Thanks for your solutions.
It's great, sounds it work for me!

$newElems.imagesLoaded is not a function When I using lightbox in Masonry

I am making a music sharing website like pinterest.
I use Masonry to make the grid layout and Infinite-Scroll load the next page. When I click a music album, it pops a lightbox (using fancybox) and loads some information with ajax.
On the first page, everything goes right. But after I click one music album, closed it and scrolled down the page, the new loaded part has this problem: $newElems.imagesLoaded is not a function
I'm not sure how to fix this.
Any help will be appreciated!
Here is my code:
var $container = $('#container');
// masonry init
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.item',
columnWidth: 100
});
});
// ancybox fancybox
function init(){
$("a.inline").fancybox({
'transitionIn' : 'fade',
'transitionOut' : 'none',
'speedOut' : 0,
'hideOnOverlayClick': true,
'hideOnContentClick': false,
'overlayColor' : '#FFF',
'overlayOpacity' : 0.5,
'showCloseButton' : true,
'showNavArrows' : false
});
}
init();
$container.infinitescroll({
// infinitescroll init
navSelector : '#page-nav',
nextSelector : '#page-nav a',
itemSelector : '.item',
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// infinitescroll callback
function( newElements ) {
var $newElems = $( newElements ).css({ opacity: 0 });
$newElems.imagesLoaded(function(){
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, {
isAnimated: false
}, function () {
// for new loaded part
init();
});
});
}
);

imagesLoaded method not working with JQuery masonry and infinite scroll

I've been using JQuery masonry and now I'm adding infinite scroll. There are images in nearly every masonry "brick" and before I was using infinite scroll the images loaded fine and everything was great. I added the next part of the javascript for the infinite scroll and added the imagesLoaded method inside but when the new bricks are appended they come out all piled on top. My assumption is that I am not adding the imagesLoaded method properly in the infinite scroll callback but I haven't been able to find my error. Here's the code
<script type="text/javascript">
$(function(){
var $container = $('#container');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector : '.tile',
columnWidth : 240
});
});
var $container = $('#container');
$container.infinitescroll({
navSelector : ".flickr_pagination",
// selector for the paged navigation (it will be hidden)
nextSelector : "a.next_page",
// selector for the NEXT link (to page 2)
itemSelector : "div.tile"
// selector for all items you'll retrieve
},
// trigger Masonry as a callback
function( newElements ) {
var $newElems = $( newElements );
$container.imagesLoaded(function() {
masonry( 'appended', $newElems );
});
}
);
});
</script>
The first JQuery masonry call works fine and hasn't been touched. It's the second part where there seems to be a problem. Thanks for the help and let me know if you need more information.
Here's the answer
$(function(){
var $container = $('#container');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector : '.tile',
columnWidth : 240
});
});
$container.infinitescroll({
navSelector : '.flickr_pagination', // selector for the paged navigation
nextSelector : 'a.next_page', // selector for the NEXT link (to page 2)
itemSelector : '.tile', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
}
);
});
The problem was I was calling .imagesLoaded() on $container in the infinite scroll callback function and I should have been calling it on $newElements.

Resources