jQuery Mobile 1.4 infinite scrolling: Window scroll not firing - jquery-mobile

In jQuery Mobile 1.4, why isn't $(window).scroll firing? Here's a non-working example trying to detect when the user has scrolled to the end of the page:
http://jsfiddle.net/5x6T2/
$(document).on('pagecontainershow', function () {
$(window).scroll(function () {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("Bottom reached!");
}
});
});
This was all working fine in jQuery Mobile 1.3 prior to the deprecation of pageshow:
http://jsfiddle.net/Demr7/
$(document).on('pageshow', '.ui-page', function() {
$(window).scroll(function () {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("Bottom reached!");
}
});
});
Anybody know what to do?

You don't have to use any third party plugin to achieve infinity scrolling. You simply need to listen to either scrollstart or scrollstop and do some math.
What you need is $(window).scrollTop(), $.mobile.getScreenHeight(), $(".ui-content").outerHeight(), $(".ui-header").outerHeight() and $(".ui-footer").outerHeight().
When $(window).scrollTop()'s value matches the value of viewport's height minus content div's height plus toolbars height, it means you have reached the bottom of the page.
Note that you should remove 1px of retrieved height of each fixed toolbars.
Attach scrollstop listener to document and then define heights variables.
$(document).on("scrollstop", function (e) {
/* active page */
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage"),
/* window's scrollTop() */
scrolled = $(window).scrollTop(),
/* viewport */
screenHeight = $.mobile.getScreenHeight(),
/* content div height within active page */
contentHeight = $(".ui-content", activePage).outerHeight(),
/* header's height within active page (remove -1 for unfixed) */
header = $(".ui-header", activePage).outerHeight() - 1,
/* footer's height within active page (remove -1 for unfixed) */
footer = $(".ui-footer", activePage).outerHeight() - 1,
/* total height to scroll */
scrollEnd = contentHeight - screenHeight + header + footer;
/* if total scrolled value is equal or greater
than total height of content div (total scroll)
and active page is the target page (pageX not any other page)
call addMore() function */
if (activePage[0].id == "pageX" && scrolled >= scrollEnd) {
addMore();
}
});
Demo (1)
(1) Tested on iPhone 5 Safari Mobile

Related

Detect the scrolling to bottom of the page using Dart

I could detect scroll reaches to bottom by using Javascript
$(window).on("scroll", function() {
var scrollHeight = $(document).height();
var scrollPosition = $(window).height() + $(window).scrollTop();
if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
// when scroll to bottom of the page
}
});
But I cannot find document.height in Dart.
How can I get height of document and compare with window.scrollY?
I think, although I always had trouble understanding the various heights, that document.body.clientHeight should work (i.e. I have used it once)
_updateScrollInfo([_]) {
if (window.innerHeight + window.scrollY >= document.body.clientHeight) {
print("at bottom");
}
}
window.onScroll.listen(_updateScrollInfo);
DartPad example: https://dartpad.dartlang.org/6fcfb715e4090a1aafe4

Scroll To Top button that only appears when you reached the end of the page

I think this is rather easy achieved, but I couldn't find out how to- and couldn't find much documentary about it.
I hate those 'scroll to top' buttons that appear after you already scrolled just 300px. Like I'm that lazy to scroll to top on myself. Therefor I would like to have a scroll to top button that only appears when you reached the bottom of the page (minus 100vh (100% viewport height).
Let's take in account the button is called .scrollTopButton and it's CSS is opacity: 0 and it's position: fixed on default.
How would I make the button appear when you reached the bottom of the page, minus 100vh and scroll along?
I was thinking of comparing the body height minus 100vh with (window).scrollTop().
var vH = $(window).height(),
bodyMinus100vh = ($('body').height() - vH);
if (bodyMinus100VH < $(window).scrollTop) {
$('.scrollTopButton').toggle();
};
Fixed it myself. Quite easy, honestly.
$(window).scroll(function () {
var vH = $(window).height(),
bodyHeight = ($(document).height() - (vH * 2)),
// When you open a page, you already see the website as big
// as your own screen (viewport). Therefor you need to reduce
// the page by two times the viewport
scrolledPX = $(window).scrollTop();
if (scrolledPX > bodyHeight) {
$('.scrollTopButton').css('opacity', '1');
} else {
$('.scrollTopButton').css('opacity', '0')
};
});

jQuery mobile panel between header and footer

jQuery mobile panel usually convers part of the page from top to bottom:
<div data-role="panel">...</div>
The demos page has left table of content panel that is limited between the header and the footer - not from top to bottom:
http://demos.jquerymobile.com/1.4.3/intro/
How to limit the panel between the header and the footer?
How is it done in CSS?
You need first to calculate height of viewport, header and footer. Subtract height of both toolbars from viewport's height will give you the height of space between both toolbars. Also, push the panel down by overriding top style of the panel.
/* active page */
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage"),
/* viewport */
screen = $.mobile.getScreenHeight(),
/* header - whether it's fixed */
header = $(".ui-header", activePage).hasClass("ui-header-fixed") ? $(".ui-header", activePage).outerHeight() - 1 : $(".ui-header", activePage).outerHeight(),
/* footer - whether it's fixed */
footer = $(".ui-footer", activePage).hasClass("ui-footer-fixed") ? $(".ui-footer", activePage).outerHeight() - 1 : $(".ui-footer", activePage).outerHeight(),
/* math 101 */
panelheight = screen - header - footer;
/* update "min-height" and "top" */
$('#panelID').css({
'top': header,
'min-height': panelheight
});
Demo

How to check if jQM popup fits user's viewport?

So I've managed to add scrollbars to large jQM popups with css('overflow-y', 'scroll'). But how to do this only when the popup is larger than the user's viewport?
I'm trying with the jquery-visible plugin but I can't get it to respond:
http://jsfiddle.net/mmRnq/124/
$('#test-button').on('click', function(e) {
$('#confirmDialog').popup('open');
// https://stackoverflow.com/questions/20791374/jquery-check-if-element-is-visible-in-viewport
if(!$('#confirmDialog').visible(true)) {
alert('Popup not fully visible - add overflow scrolling');
$('#confirmDialog').css('overflow-y', 'scroll');
}
});
You can use
overflow-y: auto
This makes the scrollbar only visible when it is needed.
Updated FIDDLE
UPDATE:
You can also just make the content of the popup scrollable so the titlebar remains in view:
#confirmDialog .ui-content {
overflow-y: auto;
}
$('#confirmDialog').on({
popupbeforeposition: function() {
var maxHeight = $(window).height() - 120;
$('#confirmDialog .ui-content').height(maxHeight);
}
});
DEMO
I had a popup too large, although it was because of a searchable list. As I wanted to keep the search field at the top whilst scrolling the list only, I had to do this:
$("#confirmDialog").on({
popupbeforeposition: function (e, ui) {
var maxHeight = $(window).height() - 100 + "px";
$("#confirmDialog .ui-content").css("max-height", maxHeight);
},
popupafteropen: function (e, ui) {
var maxHeight = $(window).height() - 150 + "px";
$("#confirmDialog .ui-content ul").css("max-height", maxHeight).css("overflow-y", "scroll");
}
});
Remember do not perform arithmetic on maxHeight once assigned as it's a string, so this doesn't work:
$("#confirmDialog .ui-content").css("max-height", maxHeight - 50);

Unbind or remove functions?

I'm having some difficulty with the accordion UI.
I want a set of divs to be an accordion when the window is a certain size (below 1024) and just divs (above 1024)
The code that I have works if the window is greater than 1024 and then I resize to a smaller window. But if I expand the window it won't turn off the accordion.
Here's the code, what am I not getting right?
<script type="text/javascript">
var width = $(window).width();
$(document).ready(function() {
if (width < 1024){
$('#accordion').accordion();
}
});
$(window).resize(function() {
var width = $(window).width();
if (width < 1024) {
$('#accordion').accordion();
} if (width > 1024) {
$('.accordion').remove();
}});
</script>
Two things in the code you posted:
The method to get rid of an accordion is not .remove() but .destroy().
You changed from an id selector ("#accordion") to a class selector (".accordion"). It's possible for that to work--assuming the elements have both that id and that class--but not recommended; you should be consistent about the selectors within a given function/context.

Resources