Pull down to refresh on mobile web browser [closed] - html

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I am giving mobile support for a web application. I have a requirement in my application that pull down screen to refresh the page to get the latest updates. I have seen this feature in iPhone native applications and it was also implemented in twitter and foursquare mobile sites.
I have seen some posts here but i unable to understand what exactly they are saying..
I am very new to this environment. please guide me in doing this feature.
Is there any javascript libraries or jqueries are there for this feature?

Essentially, pull to refresh has only been implemented publicly using a hijacked javascript scrolling mechanisms, like iScroll. This is how Twitter is doing it - with some sort of js webkit css3 scrolling library. But, you'll notice even on an iPhone 4, twitter's scrolling in mobile web is janky and not 100% natural.
Yesterday, I wrote a scroll to refresh handler for overflow: scroll components. Now that iPhone is supporting overflow: scroll, we don't have to hijack the scrolling any longer. This will be especially true when Apple fixes the current iOS -webkit-overflow-scrolling: touch bugs.
I can't yet provide my code open source, but here's the interface to do it, with some comments.
(function(window, $, undefined) {
var hasTouch = 'ontouchstart' in window,
startEvent = hasTouch ? 'touchstart' : 'mousedown',
endEvent = hasTouch ? 'touchend' : 'mouseup';
var STATES = {
...
};
var CLASS_NAMES = {
...
};
var PullToReload = function(callback, wrapper, instructionsContent) {
// create all the dom elements and append the right before a content wrapper, but after a primary main wrapper.
// <div class="mainWrapper" style="overflow: scroll; height: 600px;"><div class="pullToReloadWrapper"></div><div class="contentWrapper"></div></div> is the markup.
// Check if the main wrapper's height is bigger than the content wrapper's height. If so, then change the main wrapper height to be the height of the content wrapper.
// scroll main wrapper by the reload wrapper's height.
// set state to pull
// invoke initEvents()
};
PullToReload.prototype.setState = function(state) {
// set the state of either pull, update, or release. Change CSS classes and content.
}
// boiler plate event handling switch
PullToReload.prototype.handleEvent = function(e) {
switch (e.type) {
case startEvent:
this.start(e);
break;
case "scroll":
this.scroll(e);
break;
case endEvent:
this.end(e);
break;
}
};
PullToReload.prototype.initEvents = function() {
// add event listeners for startEvent and endEvent with method "this"
// calling this in an event listener automatically calls handleEvent()
};
PullToReload.prototype.start = function() {
// start listening to on scroll for the wrapper
};
PullToReload.prototype.end = function(e) {
// remove scroll event listener
// if the current state is in release, then set state to update and invoke the callback,
// else the state is in pull, then invoke reset()
};
PullToReload.prototype.scroll = function(e) {
// if current scroll position is almost to the top, change state to release.
// else put it back to pull state.
};
PullToReload.prototype.reset = function() {
// animate scroll to height of reload component.
// put css classes back to the beginning
};
})(window, jQuery, I);
This solution works on iOS5, Safari, Chrome, and probably others. I had to use jQuery in a couple places, mainly animating the scroll.
This solution doesn't require a css3 scroll handler, but just overflow: scroll;

Start by learning JavaScript, XHttpRequests and then touch events.
The pull to refresh is nothing more than a trigger to XHR (AJAX) call that appends new data on the selected element you want.
But if you want a short answer, check Cubiq's iScroll 4 at http://cubiq.org/iscroll-4
Best scrolling JS ever.
Here is the example: http://cubiq.org/dropbox/iscroll4/examples/pull-to-refresh/

Related

How to keep fixed html element visible on bottom of screen when the soft keyboard is open on iOS Safari?

In a web page I have an input field and a div that is fixed to the bottom of the window (with these CSS properties: position:fixed; and bottom:0;
I made a Codepen to show what I'm talking about: https://codepen.io/anon/pen/xpQWbb/
Chrome on Android keeps the div visible even when the soft keyboard is open:
However, Safari on iOS seems to draw the soft keyboard over the fixed element:
(I should mention I'm testing on the iOS simulator on my Macbook, because I don't have a working iPhone)
Is there a way to make iOS Safari keep the element visible even when the soft keyboard is open, like how Chrome does it?
I recently ran in to this problem when creating a chat input that should stay fixed at the bottom of the page. Naturally the iOS keyboard displayed on top of the chat input. Knowing the exact keyboard height seems more or less impossible. I embarked on a quest to find a solid value to base my calculations on so i can manually position the chat input container above the keyboard. I wanted to find the actual "innerHeight" value, in other words the currently visible area of the webpage. Due to how the iOS keyboard works, the only way to get that value with the keyboard open seems to be to scroll to the very bottom of the page, and then take a sample of "window.innerHeight".
So, i set up an event listener on my input field on 'click' (since on 'focus' caused a lot of issues for me). This opens the keyboard, which takes a while, so after i set a timeout for 1000ms to make sure (hopefully) that my keyboard is fully open. After 1000ms i quickly scroll to the bottom of the page with javascript, save the value of "window.innerHeight" in this state, and scroll back to where i was. This gives me the actual height of the visible area on the screen.
It seems like the browser window is placed behind the keyboard until you scroll to the very bottom, in which case the whole window 'scrolls up' and the bottom is placed at the top of the keyboard view.
Once i have this value i use currently scrolled value (window.scrollY) plus the value i saved minus the height of my absolute positioned element to determine where to place it. I opted to also hide the input while scrolling since it's flicking around quite a bit. Another downside to this is that you get a quick flick of the page when it does the measurement at the bottom.
Another thing i couldn't solve was the variable height of the address bar. I just made the input a bit higher than i needed so it would have some "padding" at the bottom.
var correctInnerHeight = window.innerHeight;
var isFocused = false;
var docHeight = $(document).height();
var input = $('.myInput');
input.click(function(e){
isFocused = true;
input.css('position', 'absolute');
// Wait for the keyboard to open
setTimeout(function(){
docHeight = $(document).height();
var lastScrollPos = $(document).scrollTop();
// Scroll to the bottom
window.scroll(0, $(document).height());
// Give it a millisecond to get there
setTimeout(function(){
// Save the innerHeight in this state
correctInnerHeight = window.innerHeight;
console.log(correctInnerHeight);
// Now scroll back to where you were, or wish to be.
window.scroll(0, lastScrollPos);
fixInputPosition();
// Make sure the input is focused
input.focus();
}, 1);
}, 1000);
});
input.on('blur', function(){
input.css('position', 'fixed');
input.css('top', 'auto');
input.css('bottom', '');
isFocused = false;
});
$(window).scroll(function(){
fixInputPosition();
});
function fixInputPosition(){
if(isFocused){
var offsetTop = ($(window).scrollTop() + correctInnerHeight) - input.height();
offsetTop = Math.min(docHeight, offsetTop);
input.css('top', offsetTop);
input.css('bottom', 'auto');
}
};
body, html{
margin: 0;
}
html{
width: 100%;
height: 2000px;
}
.myInput{
position: fixed;
height: 30px;
bottom: 0;
width: 100%;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' class='myInput'>
Check out this thread, it talks about a work around that may be more feasible in terms of code. In brief it talks about using the height of the keyboard to move the content into view. All be it a bit hacky it may be difficult to pin down the exact height of the keyboard across devices.
Unfortunately, due to the nature of the IOs Safari keyboard it's not part of the browser viewport so cannot be referenced as you would do typical elements.
#Bhimbim's answer may a good shot too.
Regards,
-B
i experienced this before. What i did back then was :
Make a listener when keyboard is hit.
When keyboard is hit resize you webview's height with screen height - keyboard height.
To do this trick you need to make sure that you html is responsive.
I can show more code in the IOS side, if you're interested i can edit my answer and show you my IOS code. Thank you.
Hi again, sorry, i was mistaken, i thought you were creating apps with webview inside. If you still wanna do this by listening the keyboard i still have work around for you. It may not the perfect way, but i believe this will work if you want to try. Here my suggestion :
You still can have listener from webpage when the keyboard is up. You can put a listener on your textfield by jquery onkeyup or onfocus.
Then you will know when the input is hit and the keyboard will show.
Then you can create a condition in your java script to manipulate your screen.
Hope this give you an insight friend.
#Beaniie thank you !.
Hi Andreyu !. Yes correct, we can not know the keyboard height, not like my case with WebView, I can know the keyboard height through IOS code. I have another work around, not so smart, but might work. You can get the screen size and compare to array of IOS device screen size. Then you might narrowed down the keyboard height by surveying through IOS devices. Good luck friend.
Try using position:absolute and height:100% for the whole page.
When the system displays the keyboard,it plTaces it on top of the app content.
One way is to manage both the keyboard and objects is to embed them inside a UIScrollView object or one of its subclasses, like UITableView. Note that UITableViewController automatically resizes and repositions its table view when there is inline editing of text fields.
When the keyboard is displayed, all you have to do is reset the content area of the scroll view and scroll the desired text object into position. Thus, in response to a UIKeyboardDidShowNotification, your handler method would do the following:
1.Get the size of the keyboard.
2.Adjust the bottom content inset of your scroll view by the keyboard height.
3.Scroll the target text field into view.
Check the Apple developer's guideline to learn more:https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

Cursor/caret bleeding through overlay in IE

I am doing work on and existing website www.shopthethirdfloor.com. Using IE, if you click on the products menu, give focus to the search box and then scroll the search field under the menu overlay that pops up, the search field goes under the overlay, but the cursor continues to blink where the hidden input field is. This only happens in IE. The search and product display is an iframe also. I am thinking this is an ie bug/feature depending if you are a user or microsoft.
I work on the Internet Explorer team, and can assure you that we don't view this as a feature. It's a bug, plain and simple. I've added this question, and your site, to an internal ticket on the issue for the team to review during the next triage.
For the time being you could add a check for the document.documentMode, and apply a bit of functionality to prevent Internet Explorer from showing the caret over the top of unrelated elements. In the following code I use jQuery's $.fn.one method to attach a one-time-use handler during an element's .onFocus event, and then dispose of it during the window's .onScroll event:
if ( document.documentMode && document.documentMode < 12 ) {
$( document ).on( "focus", ":input", function ( event ) {
$( window ).one( "scroll", function () {
event.target.blur();
});
});
}
The results can be seen here: http://jsfiddle.net/yynsbrat/2/
I'll continue to work with the team on resolving this issue from our end, but until this I hope this approach is able to help you in the interim.

header lags behind when scrolling

I tried to find something about this on the net, and although it's a minor issue, I feel as if it impacts the site experience. Furthermore, depending on the browser or speed of your computer, you may not notice this problem.
The issue is I have a fixed header on my site. When scrolling up or down, it seems to lag or drag behind... it stays fixed at the top, but while you scroll it jutters and drags at a different pace.
You can see for yourself, here.
It's doing my head in - it seems to only happen on the portfolio page, and not the home page.
I had same issue on Chrome. Solved it by adding
-webkit-backface-visibility: hidden;
to the header element in my stylesheet;
There is good article regarding this.
Hope this helps.
This may be happening because you're trying to do a fair bit on the window scroll event.
Every time a scroll event fires you've got a parallax scroll function that modifies elements with the parallax class (though there don't seem to be any actual elements with that class). You're also checking whether to add the class that changes your header background.
One thing you can do to improve performance is to do as little as possible inside the actual scroll function.
//Menu contrast happens when user scrolls down
// Save 4 jQuery select operations and 2 function calls per scroll event
var myNav = $('nav');
var heightDiff = $('#bg1').height() - myNav.height();
// Use global variables in the scroll function
$(window).scroll(function () {
if (window.pageYOffset < heightDiff)
{
myNav.removeClass('contrast');
}
else
{
myNav.addClass('contrast');
}
});
You can do something similar with the parallax loop as well.
// Save 2 jQuery select operations and one function call per scroll event
var htmlHeight = $('html').height();
var parallaxElems = $('.parallax');
$(window).scroll(function () {
var scrollpercentage = window.pageYOffset/htmlHeight;
var moveoffset = 350*scrollpercentage; // set parallax coeficcient
parallaxElems.css('background-position-y',(50-moveoffset)+'%');
});
Keep in mind that if you use JavaScript to add new elements to the DOM or modify existing elements, you may have to compute your global variables again.

disable scroll for a div with SVG

I have a SVG chart using d3js. We can add some points to this chart and move it. When I have a big page and so when we need to scroll it, it works with the mouse. But I have an input screen with multi-touch and in more I develop my app for mobile.
The input with the chart and the scroll aren't working together with an input touch. For example if I want to move my point it's the page which scroll and not my point wich move. It's not exactly the same bugs on firefox, IE and my Windows RT app.
You can see a little example here to test if you have an input touch, I guess tablet and smartphone will have the same behaviour than my PC with a touch screen.
I have the following css to simulate a bigger app:
body {
overflow:visible;
width: 2000px;
height: 2000px;
}
There is a way to do this?
I hope you understood my problem :)
I tested this on my phone and tried to research how to force a browser to stop scrolling with little success. The good news is your app allows a mobile user to place a new point really nicely.
To get the project done quick, you might need to create a set of controls that grabs an id of each existing point and allow the mobile user to move the desired point using buttons. The UI for such a set of controls could be minimal and intuitive if done well. You could set the UI to display:none and only show when the screen width/height is iPad size or less.
I finnaly found a solution with the pointer-events property in css
var C1 = document.getElementById("C1"),
evtIn = window.navigator.msPointerEnabled ? "MSPointerDown" : "touchstart",
evtOut = window.navigator.msPointerEnabled ? "MSPointerUp" : "touchend";
C1.addEventListener(evtIn, function () {
d3.select("#C1").style("pointer-events", "all");
d3.select("body").style("overflow", "hidden");
}, false);
C1.addEventListener(evtOut, function () {
d3.select("#C1").style("pointer-events", "none");
d3.select("body").style("overflow", "auto");
}, false);
On touch start I just allow pointer events in my chart et disable overflow and in the other way for the touch end.

HTML5 swipe.js css3 transitions; offscreen rendering and caching of page elements

I am building a HTML5 magazine for tablets and desktops with use of swipe.js (http://swipejs.com).
Everything seems to work fine, In one HTML page I have set next to each other fullscreen list elements. The whole magazine is build up in one static html file. I can slide through the pages by swiping on tablets, and by using buttons for the desktop version (consider the example on the swipe.js homepage, but then with fullscreen slides).
The pages are placed next to each other, and have the dimensions of the screen.
[ |0||1||2| .. |i-1||i||i+1| .. |n| ]
The swipe.js transitions are done with help of css3, using the translate3d() css function. In this case, hardware rendering is used.
On desktop (Chrome, Safari, FF), iPad1 and (even better on) iPad2 this has the desired effect I was looking for; smooth transitions. Perfect!
However, on the iPad3, the pages seem to render 'slow' when entered (by transition) for the first time. Even without setting background images (just the color), the 'rendering' of the transitioned page is considered a little 'slow'; the page is build up by 'flickering' blocks.
Assumption:
My assumption is (after reading into the subject), that this is because the browser only renders the elements that are in-screen, and will cache the swiped pages only for a while, cleaning the cache afterwards to control memory management.
My question: Is there a way to control the offscreen rendering and caching, so that I can force (pre) render page elements i-1, i+1 (and flush the cache for all other page elements), to speed up my transition rendering?
Note: In several topics on StackOverflow, 'flickering' of css3 transitions is mentioned. I have implemented the suggested CSS tricks but will not solve my case.
-webkit-backface-visibility: hidden;
-webkit-transform:translate3d(0,0,0);
In the end the solution was a hack of Swipejs in which I added a method 'hideOthers()', setting the style visibility to 'hidden', which unloads the pages from hardware memory:
hideOthers: function(index) {
var i = 0;
var el;
for( i in this.slides ) {
el = this.slides[i];
if ( el.tagName == 'LI' ) {
// Show pages i-1, i and i+1
if ( parseInt(i) == index
|| (parseInt(i) + 1) == index
|| (parseInt(i) - 1) == index
) {
el.style.visibility = 'visible';
}
else {
el.style.visibility = 'hidden';
}
}
}
}
..and added the trigger below as last line in the 'slide()' method
// unload list elements from memory
var self = this;
setTimeout( function() { self.hideOthers(index); }, 100 );
Only the translate3d was needed to toggle the hardware acceleration on (as mentioned in my question above):
-webkit-transform:translate3d(0,0,0);
You can find the result (including iScroll for vertical scrolling) here.
in regards to the webkit backface/translate3d props used to trigger hardware acceleration, I've read that in iOS 6+ these don't work quite the same as in previous versions, and (more importantly) that hardware acceleration needs to be applied not only on the element that is being animated, but also on any element that it is overlapping/overlaps it.
reference (not much): http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
To be fair this is fairly anecdotal, I was myself unable to fix my own flickering issue - due to tight deadlines - but this might be a point in the right direction.