Waypoints won't trigger above targeted element after refresh - javascript

I set the optioon triggerOnce to true, it work like a charm if i start srcolling from beginning (top of the page) and start scrolling down.
But if i refresh the page at the bottom of the page and start scrolling up, it wont trigger the above targeted element like it did when scrolling down from the top of the page.
here my code:
$('.anim').each(function(index, elHtml) {
var el = $(this);
// console.log($(this), el);
var _animation = el.data('animation'),
_duration = el.data('duration') ? el.data('duration') : 1000,
_offset = el.data('offset') ? el.data('offset') : 'bottom-in-view';
el.waypoint(function(direction){
el.velocity(_animation, _duration);
if(direction == 'up'){
el.velocity(_animation, _duration);
}
}, {
offset: _offset,
triggerOnce: true
});
});
Please let me know if you have the solution.
Thank you for your time :)

This is because when the page loads and Waypoints are added, they check to see if they have already been passed in the down direction and if they have, it triggers the waypoint. So in your case, you're hitting the waypoints in the down direction and they are being destroyed after the down trigger.
The "workaround" for your use case is to create them disabled using the enabled: false option. Then, after the page is done loading, call enable on the waypoints.

Related

Destroying InfiniteScroll on AJAX page change

We have a website that is running jQuery Infinite Scroll Plugin. The plugin is no longer maintained but it is the only one that really serves our purpose properly. However, the problem I have is that our site is ajax based. On page change the pg-changed trigger is fired against the window, which allows us to check if the Infinite Scroll container is there and enable Infinite Scroll. If the Infinite Scroll container isn't there but $.infscr exists, we will attempt to destroy the previous instance.
The problem I am having is that when changing to another page, it doesn't seem to be getting destroyed properly and sometimes AJAX calls will be made, along with the infscr loading bar displaying. Here is the code I am using to instantiate and destroy the plugin:
$(window).on('pg-changed', function () {
// delete our infinite scroll
if(typeof $.infscr !== 'undefined') {
$('.snap-inner, .infscr').data('infinitescroll', null);
$('.snap-inner, .infscr').infinitescroll('unbind');
$('.snap-inner, .infscr').infinitescroll('destroy');
$('#infscr-loading').remove();
$.infscr.data('infinitescroll', null);
$.infscr.infinitescroll('unbind');
$.infscr.infinitescroll('destroy');
delete $.infscr;
}
// setup our infinite scroll
if($('.infscr').length) {
$.infscr = $('.infscr').infinitescroll({
// define our navigation selectors
navSelector : 'div.infscr-navigation',
nextSelector : 'div.infscr-navigation A:first',
itemSelector : '.infscr-item',
// allow scrolling an overflowed element
behavior : 'local',
bufferPx : 120,
binder : $('.snap-inner'),
dataType : 'html',
loading : {
msg : null,
selector : '.snap-content',
img : 'data:image/gif;base64,TRIMMED',
msgText : '<span class="infscr-loading">Loading...</span>',
}
}, function (arrayOfNewElems) {
// render background images on our new elements
$(this).renderBgImages();
});
}
});
I really hope you can help with this as it has become quite a problem now, firing on scroll, making AJAX calls and displaying the loading bar.
I guess the problem might be that the plugin binds events on elements external to itself. It's hard to say without further debugging (is the plugin deleted or does it fail to do so?). If it does, why would it fail to unbind the events? etc.
When you say, 'on another page', I suppose you are not loading a whole new page (which would 'reset' the javascript.
Though, depending on wether this could work for you, you might want to try unbinding ALL events on the document, and starting fresh.
$(document).add('*').off();
should do so. If it does, you could try to pinpoint what elements/events you need to unbind manually. Let me know if this works or not.

How to set SWIPER start with the first slide?

I have an issue with the swiper (http://www.idangero.us/sliders/swiper/api.php)... I am on page 1 and when I swich to the page 2 I want the slider to start with the first slide. I set mySwiper.swipeTo(0, 0, false); on pagebeforeshow and it doesnt work. the STRANGEST thing is that it works perfectly if I swich to second or third slide (ex mySwiper.swipeTo(1, 0, false) or mySwiper.swipeTo(2, 0, false)) but on the first one (0) it simply doesn't swich. Why is that? I tried every possible thing. It doesn't switch on the first slide, only on others. The only method that works is onpageshow but its ugly because first it shows one slide and after another..
I also tried with mySwiper.swipePrev(); a few times but its blocking on slide 2.. It wont go on the first slide.
UPDATE:
here's the jsfiddle example: http://jsfiddle.net/alecstheone/9VBha/103/
so... if I go to second page and I swipe to the third slide than I right click and go back, than back to page 2 the swiper is still on the slide 3 and it should be on page 1 as I set
mySwiper.swipeTo(0, 1, true);
If I set:
mySwiper.swipeTo(1, 1, true);
or
mySwiper.swipeTo(2, 1, true);
it works... only on 0 it wont...
I also noticed that in the 1.8.0 version of the swiper it works that command, but in the latest (2.6.0) it wont.
const swiper2 = new Swiper('.swiper-container2', {
direction: 'vertical',
slidesPerView: 1,
initialSlide: 2,
});
you can use initialSlide to set first slide
If you look up the method swipeTo() in the library you'll find the following condition:
if (index > (_this.slides.length - 1) || index < 0) return;
Which indicates you can only use this method from index 1.
Why don't you just initialize the plugin without the pageBeforeShow option? It should take the first slide.
UPDATE
Finally got it to work and I also hope the author reads this since this is a terrible library to setup as the configuration parameters go berzerk throughout the whole script.
$(page2).click(function () {
//mySwiper.activeIndex = 0;
//mySwiper.startAutoplay();
//mySwiper.swipeReset();
//mySwiper.reInit(true);
setTimeout(function(){
// to make sure the swiper-wrapper is shown after the animation of $.mobile.changePage()
mySwiper.swipeTo(0);
}, 200);
$.mobile.changePage(page2);
// $("#photo").hide().delay(1000).fadeOut();
// $("#photo").animate({opacity: 0.0}, 1);
});
As you can see, the commented functionality seems straightforward but only brings frustration to the people using this. For me this is a design flaw in naming convention and boolean traps.
I also noticed you set height and width dynamically and I'm sure there "is a way" to let the script calculate these parameters as it uses a polyfill for getComputedStyle(). Or you might try to use CSS3 calc() to take some performance hit out of JS.
Second time I use this library and again I had to use the unminified version to debug the functions and it's parameter setup which doesn't work together very well. Only a set of combinations can make this library work and it's up to the developer to figure this whole bunch out.
Good luck on the script and note that the provided code really helped (very quickly) in understanding the problem.
DEMO
I had the same problem few months after this discussion.
I know it's a ugly way to fix the problem, but its the only way I found :
When you call mySwiper.swipeTo(0), this line below :
if (newPosition === currentPosition) return false;
will return false and not apply the swipe, because newPosition = 0 and currentPosition = 0
so i changed this line on the method to
if (newPosition === currentPosition && newPosition !== 0) return false;
and it works now fine.
Since this does not work
mySwiper.swipeTo(0, 1, false)
you could also force it like
var swiper = new Swiper(
".swiper-container",
slideConfigs
);
swiper.on('beforeInit', function () {
swiper.slideTo(1, 1, false)
swiper.slidePrev(1, false)
})
swiper.init()
And don't forget to add this to your configs
init: false,

jscrollpane scrolltobottom but pause with mouseover on scrollbar

i have finished this code off but im stuck on teh last thing i have to do, when a item is added it auto scrolls to the bottom which is great but what i cannot work out how to do and im sure its simple is when i use the scroll bar i want to stop it jumping to the bottom until i stop using the scroll bar.
you will see in the example ive provided if you click on scrollbar and drag up it keeps jumping down when it adds a new item, i just need to pause that until i stop using the scroll bar if that makes sense.
it uses api.scrollToBottom(); to scroll to the bottom once the new item is added which is correct, but unsure on the condition for mouseover etc... to stop that when those are the conditions.
Hope someone can help me on this, many thanks in advance! :)
JSFiddle here: http://jsfiddle.net/GT7sV/2/
JS
var settings = {
showArrows: true,
verticalArrowPositions: 'os',
horizontalArrowPositions: 'os',
animateScroll: true
};
var pane = jQuery('.scroll-pane');
pane.jScrollPane(settings);
var api = pane.data('jsp');
var i = 1;
api.scrollToBottom();
setInterval(
function()
{
api.getContentPane().append("<li>testing this new item</li>").children(':last').hide().fadeIn(1000);
api.reinitialise();
api.scrollToBottom();
},
1000
);
});
Thanks!
I dont know if this is ok for you but you could try it in different direction. You could load new rows when user scrolls to the bottom:
conversationHeadersScrollPane = $('.scroll-pane').bind(
'jsp-scroll-y',
function(event, scrollPositionY, isAtTop, isAtBottom) {
if (isAtBottom) {
//add new rows for example with ajax call
}
});
edit: there is a function getPercentScrolledY()
so you could before calling scrollToBottom check if user is for example bellow 90%, if not let him read while he scrolls on his own to the bottom.

Update a jQuery script when user switches to a new tabbed element

I'm having a hard time describing exactly what the problem is.. but the link in question is: http://www.evolutionarycollective.com/events/
You'll notice that when you load the "Calendar" tab, the calendar doesn't show up. If you resize the window, or manipulate the page in some other way, then the calendar appears. The calendar loads fine when it's not within a tab. It's being called in the header with:
<script type='text/javascript'>
jQuery(document).ready(function() {
jQuery('#calendar').fullCalendar({
events: themeforce.events
});
});
</script>
EDIT:
I believe this is the section of the script library that handles the tabs and panes.. (I'm using this with a wordpress theme that calls the tabs via a shortcode)
// jQuery tool's tab creator is not shortcode friendly, transfer the titles to the correct tabs area
jQuery('.bfi_pane').each(function(i) {
var title = jQuery(this).attr('title');
jQuery(jQuery(this).siblings('.bfi_tabs,.bfi_tabs_slide,.bfi_tabs_fade')[0]).append('<div>'+title+'</div>');
});
// Custom slide effect for tabs. slide up then down
jQuery.tools.tabs.addEffect('slide-slide',function(i, done) {
this.getPanes().slideUp(400).eq(i).delay(400).slideDown(400, done);
});
// Custom slide effect for tabs. slide up and down simultaneously
jQuery.tools.tabs.addEffect("slide", function(i, done) {
this.getPanes().slideUp(400).eq(i).slideDown(400, done);
});
// IMPORTANT: SLIDEDOWN JQUERY FIX. we need to assign the correct heights
// so that the slidedown effect doesn't JUMP
jQuery(".bfi_accordion_pane").each(function(i) {
var heightTo = jQuery(this).height();
var paddingTop = parseInt(jQuery(this).css("padding-top").replace('px', ''));
var paddingBottom = parseInt(jQuery(this).css("padding-bottom").replace('px', ''));
var marginTop = parseInt(jQuery(this).css("margin-top").replace('px', ''));
var marginBottom = parseInt(jQuery(this).css("margin-bottom").replace('px', ''));
jQuery(this).css("height", heightTo + paddingTop + paddingBottom + marginTop + marginBottom);
});
// start jQuery tool tabs. we have to do this the long way so we can make
// initialIndex work properly
jQuery(".bfi_tabs_slide").each(function(i) {
var openTab = jQuery(this).attr('rel');
jQuery(this).tabs('> div.bfi_pane', {effect: 'slide-slide', initialIndex: parseInt(openTab, 10)});
});
jQuery(".bfi_tabs_fade").each(function(i) {
var openTab = jQuery(this).attr('rel');
jQuery(this).tabs('> div.bfi_pane', {effect: 'fade', initialIndex: parseInt(openTab, 10)});
});
Is there some way I can somehow refresh the script when that tab lis loaded.. or fire off another document.ready?
Thank you!
The probable explanation is that the full calendar can't figure out its height because when initially created that tab is hidden, which will make it have zero width and height.
Just make the call to .fullCalendar() in a tab switch event handler.
Alternatively use the "off-left" method of hiding tabs, as described in the last few paragraphs of http://jqueryui.com/demos/tabs/

make qtip disappear right away

so I want the following behavior out of qtip:
the qtip should show up when I click on the object (I got this working without problem)...but then I want to have it disappear after a few miliseconds without me having to do anything....how would you go about configuring qtip to do this?
i tried
hide: {
when : 'inactive',
delay : 100,
fixed: false
}
but it's not working....
any help would be appreciated...thanks
If you only want the tooltip to flash on screen:
$(".tooltip").qtip({
content: "Test tooltip",
api: {
// As soon as the qtip is fully visible..
onShow: function (event) {
// Keep a reference to the qtip..
that = this;
// After 1ms (to let things settle down)
setTimeout(function () {
// Hide the qtip
that.hide();
}, 1); // change this value to have it stay on screen longer
}
},
show: "mouseover"
});
I know this is an old question but just in case someone passes by, the right way to do it in qTip2 is: (events instead of api)
events: {
show: function(event, api){
var that = this;
setTimeout(function () {
// Hide the qtip
that.hide();
}, 3000); // change this value to have it stay on screen longer
}
}
I think your code is correct, but the delay is causing problems. 100ms is only 0.1 seconds, so maybe the qtip is taking longer than that time to render, in which it won't exist yet when it's told to hide itself (just a guess).
I would increase the delay (you probably want your users to see the tip for a few seconds anyway) and see if that helps. Here's an example that uses 1000ms: http://jsfiddle.net/andrewwhitaker/dVEYq/

Categories

Resources