iPhone Scrollbars with iScroll
Since we've had web browsers and JavaScript, we've been intent on replacing native browser functionalities, and for many reasons. Whether it be that the native look or functionality is ugly, doesn't work the same across browsers, or isn't as feature-rich as it should be, we've always pushed the browser's limits to do better. One functionality we've tried desperately to emulate is scrollbars. iScroll , a fairly new scrolling lib, has done an exceptional job in emulating scrolling both within desktop and mobile browsers. iScroll also allows for scrolling of elements with overflow on older versions of Mobile Safari. Let's have a look at iScroll!
The HTML
iScroll requires a two-DIV pattern for declaring where iScroll will be used. The first DIV is the wrapper, the second DIV is the scrollable area:
<div id="wrapper">
<div id="scroller">
<div style="padding:15px 30px;"> <!-- padding for content --> <!-- content goes here --> </div>
</div>
</div>
iScroll will create and inject the scrollbar within the wrapper DIV. The content is held within the scroller DIV.
The CSS
The CSS is where iScroll can get a bit fuzzy. For iScroll to work optimally, both the wrapper and scroller DIVs need to be positioned absolutely and be styled to widths of 100%:
#wrapper {
position:absolute;
z-index:1;
top:0;
bottom:0;
left:0;
width:100%;
overflow:auto;
}
#scroller {
position:absolute; z-index:1;
/* -webkit-touch-callout:none;*/
-webkit-tap-highlight-color:rgba(0,0,0,0);
width:100%;
padding:0;
}
As a result, the third DIV of the structure needs the contain enough padding-right to keep the text and scrollbar far enough way from each other. Be sure to position those elements properly or iScroll wont work at all (as I found out the hard way) !
The JavaScript
The most obvious piece of using iScroll is including its .js file:
<script type="text/javascript" src="iscroll/src/iscroll.js"></script>
With iScroll now available within the page, the next step is creating the iScroll instance that suits the needs of your desired usage. The most simple of uses provides only the wrapper ID:
var scroller = new iScroll('wrapper');
Awesome; the page's native scrollbar disappears and is replaced by an iOS-style scrollbar! But like every good JavaScript lib, iScroll provides a host of features that allow you to customize your scrollbar. Options include setting flags for bounce, momentum, fade and hide settings, and whether scrollbars should be allowed both vertically and horizontally. Here's another example of how you can create a pull-to-refresh scrollbar:
var myScroll,
pullDownEl, pullDownOffset,
pullUpEl, pullUpOffset,
generatedCount = 0; function pullDownAction () {
setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production!
var el, li, i;
el = document.getElementById('thelist'); for (i=0; i<3; i++) {
li = document.createElement('li');
li.innerText = 'Generated row ' + (++generatedCount);
el.insertBefore(li, el.childNodes[0]);
} myScroll.refresh(); // Remember to refresh when contents are loaded (ie: on ajax completion)
}, 1000); // <-- Simulate network congestion, remove setTimeout from production!
} function pullUpAction () {
setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production!
var el, li, i;
el = document.getElementById('thelist'); for (i=0; i<3; i++) {
li = document.createElement('li');
li.innerText = 'Generated row ' + (++generatedCount);
el.appendChild(li, el.childNodes[0]);
} myScroll.refresh(); // Remember to refresh when contents are loaded (ie: on ajax completion)
}, 1000); // <-- Simulate network congestion, remove setTimeout from production!
} function loaded() {
pullDownEl = document.getElementById('pullDown');
pullDownOffset = pullDownEl.offsetHeight;
pullUpEl = document.getElementById('pullUp');
pullUpOffset = pullUpEl.offsetHeight; myScroll = new iScroll('wrapper', {
useTransition: true,
topOffset: pullDownOffset,
onRefresh: function () {
if (pullDownEl.className.match('loading')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
} else if (pullUpEl.className.match('loading')) {
pullUpEl.className = '';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
}
},
onScrollMove: function () {
if (this.y > 5 && !pullDownEl.className.match('flip')) {
pullDownEl.className = 'flip';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
this.minScrollY = 0;
} else if (this.y < 5 && pullDownEl.className.match('flip')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
this.minScrollY = -pullDownOffset;
} else if (this.y < (this.maxScrollY - 5) && !pullUpEl.className.match('flip')) {
pullUpEl.className = 'flip';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Release to refresh...';
this.maxScrollY = this.maxScrollY;
} else if (this.y > (this.maxScrollY + 5) && pullUpEl.className.match('flip')) {
pullUpEl.className = '';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
this.maxScrollY = pullUpOffset;
}
},
onScrollEnd: function () {
if (pullDownEl.className.match('flip')) {
pullDownEl.className = 'loading';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
pullDownAction(); // Execute custom function (ajax call?)
} else if (pullUpEl.className.match('flip')) {
pullUpEl.className = 'loading';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Loading...';
pullUpAction(); // Execute custom function (ajax call?)
}
}
}); setTimeout(function () { document.getElementById('wrapper').style.left = '0'; }, 800);
}
Since we live in the world of AJAX-driven websites that allow content to come and go, calling the refresh method is all you need to do for iScroll to reevaluate the scrollbar position and size:
// When the AJAX is done, refresh the scrollbar sizing and positioning...
scroller.refresh();
It's also important to point out that iScroll allows zooming and pinching, as well as snapping to elements:
var myScroll = new iScroll('wrapper', {
/* snap: true, */ // Would snap logically
snap: "p", // Snaps to each "P" tag
momentum: false,
hScrollbar: false,
vScrollbar: false
});
Lastly, iScroll-Lite is available for those looking to support only mobile browsers (iScroll allows for desktop support as well). The mischievous part of me would prefer iOS-style scrollbars instead of native browser scrollbars!
Possibly my favorite part of iScroll is that it's a standalone library; no external JavaScript library is required. iScroll has many configuration parameters so I encourage you to visit the iScroll page to check out everything you can do. Matteo Spinelli's iScroll is an outstanding piece of work; grab iScroll and start controlling your scrollbars today!
原文 http://davidwalsh.name/iphone-scrollbars
this is a demo .
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>上拉下拉动态加载例子</title>
<link href="css/jquery.mobile.structure-1.3.2.css" rel="stylesheet" type="text/css"/>
<link href="css/jquery.mobile-1.3.2.css" rel="stylesheet" type="text/css"/>
<script src="js/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$("#list").bind('pageinit', function () {
$.ajax({
type: "get",
async: false,
url: "http://www.57lehuo.com/index.php?a=index&m=api&method=itemsSearchGet&keyword=连衣裙&sign=5cb85c3eed22c1908e05c584813c8dd2",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"itemsSearchGet",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(json){
var content='';
$.each( json['result'], function(i, n){
var url=n.url!='undefined'?n.url:'';
var bimg=n.bimg!='undefined'?n.bimg:'';
var title=n.title!='undefined'?n.title:'';
content = content + "<li>";
content = content + "<a target=\"_blank\" href=\"http://s.click.taobao.com/t?e=zGU34CA7K%2BPkqB05%2Bm7rfGGjlY60oHcc7bkKOQiRddrNEyGLx31dnc6%2Fz%2BaQS2UNDUWpebTcEEjBuk1W5odmLS8%3D&pid=mm_30949159_0_0\">";
content = content + "<img src=\""+bimg+"_100x100.jpg\" />";
content = content + "<h2>";
content = content + "连衣裙";
content = content + "</h2>";
content = content + "<p>";
content = content + title;
content = content + "</p>";
content = content + "</a>";
content = content + "</li>";
});
$("#thelist").append(content).listview('refresh');
},
error: function(){
//alert('fail');
}
});
});
$("#list").bind("pagebeforeshow", function(){
setTimeout(loaded, 10);
});
//http://www.57lehuo.com/index.php?a=index&m=api&method=itemsListGet×tamp=12121512&cid=773&sign=8d6fda3f30ea3517341e1820cd719784 }) </script>
<script src="js/jquery.mobile-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/iscroll.js"></script> <script type="text/javascript"> var myScroll,
pullDownEl, pullDownOffset,
pullUpEl, pullUpOffset,
generatedCount = 0; /**
* 下拉刷新 (自定义实现此方法)
* myScroll.refresh(); // 数据加载完成后,调用界面更新方法
*/
var p=2;
function pullDownAction () {
$.ajax({
type: "get",
async: false,
url: "http://www.57lehuo.com/index.php?a=index&m=api&method=itemsSearchGet&keyword=连衣裙&p="+p+"",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"itemsSearchGet",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(json){
var content='';
$.each( json['result'], function(i, n){
var url=n.url!='undefined'?n.url:'';
var bimg=n.bimg!='undefined'?n.bimg:'';
var title=n.title!='undefined'?n.title:'';
content = content + "<li>";
content = content + "<a target=\"_blank\" href=\"http://s.click.taobao.com/t?e=zGU34CA7K%2BPkqB05%2Bm7rfGGjlY60oHcc7bkKOQiRddrNEyGLx31dnc6%2Fz%2BaQS2UNDUWpebTcEEjBuk1W5odmLS8%3D&pid=mm_30949159_0_0\">";
content = content + "<img src=\""+bimg+"_100x100.jpg\" />";
content = content + "<h2>";
content = content + "连衣裙";
content = content + "</h2>";
content = content + "<p>";
content = content + title;
content = content + "</p>";
content = content + "</a>";
content = content + "</li>";
});
$("#thelist").prepend(content).listview('refresh');
},
error: function(){
// alert('fail');
}
});
p++;
myScroll.refresh(); //数据加载完成后,调用界面更新方法 Remember to
} /**
* 滚动翻页 (自定义实现此方法)
* myScroll.refresh(); // 数据加载完成后,调用界面更新方法
*/
function pullUpAction () {
setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production!
/*
var el, li, i;
el = document.getElementById('thelist'); for (i=0; i<3; i++) {
li = document.createElement('li');
li.innerText = 'Generated row ' + (++generatedCount);
el.appendChild(li, el.childNodes[0]);
}
*/
var content = "";
for (var i=1;i<3;i++){
content = content + "<li>";
content = content + "<a href=\"#\">";
content = content + "<img src=\"images/album-bb.jpg\" />";
content = content + "<h2>";
content = content + "下拉新增内容<br/>"+new Date();
content = content + "</h2>";
content = content + "<p>";
content = content + "Broken Bells";
content = content + "</p>";
content = content + "</a>";
content = content + "</li>";
}
$("#thelist").append(content).listview('refresh'); myScroll.refresh(); // 数据加载完成后,调用界面更新方法 Remember to refresh when contents are loaded (ie: on ajax completion)
}, 1000); // <-- Simulate network congestion, remove setTimeout from production!
} /**
* 初始化iScroll控件
*/
function loaded() {
//清除所占的内存空间
if(myScroll!=null){
myScroll.destroy();
} pullDownEl = document.getElementById('pullDown');
pullDownOffset = pullDownEl.offsetHeight;
pullUpEl = document.getElementById('pullUp');
pullUpOffset = pullUpEl.offsetHeight;
myScroll = new iScroll('wrapper', {
useTransition: true, //默认为true
//useTransition: false,
topOffset: pullDownOffset,
onRefresh: function () {
if (pullDownEl.className.match('loading')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = '下拉刷新...';
} else if (pullUpEl.className.match('loading')) {
pullUpEl.className = '';
pullUpEl.querySelector('.pullUpLabel').innerHTML = '上拉加载更多...';
}
},
onScrollMove: function () {
if (this.y > 5 && !pullDownEl.className.match('flip')) {
pullDownEl.className = 'flip';
pullDownEl.querySelector('.pullDownLabel').innerHTML = '松手开始更新...';
this.minScrollY = 0;
} else if (this.y < 5 && pullDownEl.className.match('flip')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = '下拉刷新...';
this.minScrollY = -pullDownOffset;
} else if (this.y < (this.maxScrollY - 5) && !pullUpEl.className.match('flip')) {
pullUpEl.className = 'flip';
pullUpEl.querySelector('.pullUpLabel').innerHTML = '松手开始更新...';
this.maxScrollY = this.maxScrollY;
} else if (this.y > (this.maxScrollY + 5) && pullUpEl.className.match('flip')) {
pullUpEl.className = '';
pullUpEl.querySelector('.pullUpLabel').innerHTML = '上拉加载更多...';
this.maxScrollY = pullUpOffset;
}
},
onScrollEnd: function () {
if (pullDownEl.className.match('flip')) {
pullDownEl.className = 'loading';
pullDownEl.querySelector('.pullDownLabel').innerHTML = '加载中...';
pullDownAction(); // Execute custom function (ajax call?)
} else if (pullUpEl.className.match('flip')) {
pullUpEl.className = 'loading';
pullUpEl.querySelector('.pullUpLabel').innerHTML = '加载中...';
pullUpAction(); // Execute custom function (ajax call?)
}
}
});
setTimeout(function () { document.getElementById('wrapper').style.left = '0'; }, 800);
} //初始化绑定iScroll控件
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false); //document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
document.addEventListener('DOMContentLoaded', loaded, false);
</script>
<link rel="stylesheet" type="text/css" href="css/iscroll.css">
</head>
<body> <div data-role="page" id="list">
<div id="header"><a href="#">产品列表页</a></div>
<div id="wrapper">
<div id="scroller">
<div id="pullDown">
<span class="pullDownIcon"></span><span class="pullDownLabel">Pull down to refresh...</span>
</div>
<ul data-role="listview" data-icon="false" id="thelist">
<li><a href="#">
<img src="data:images/album-p.jpg">
<h3> Amadeus Phoenix</h3>
<p>Phoenix</p></a>
</li>
</ul>
<div id="pullUp">
<span class="pullUpIcon"></span><span class="pullUpLabel">Pull up to refresh...</span>
</div>
</div>
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar" data-grid="a">
<ul>
<li><a href="index.html" class="ui-btn-active" data-ajax="false">首页</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>
demo 下载
iPhone Scrollbars with iScroll的更多相关文章
- iScroll 4.2.5 中文API
概况 资料来源 http://cubiq.org/iscroll-4 http://www.cnblogs.com/wanghun/archive/2012/10/17/2727416.html ht ...
- jquery——移动端滚动条插件iScroll.js
官网:http://cubiq.org/iscroll-5 demo: 滚动刷新:http://cubiq.org/dropbox/iscroll4/examples/pull-to-refresh/ ...
- iScroll.js 用法参考 (share)
分享是传播.学习知识最好的方法 以下这篇文章是iScroll.js官网的中文翻译,尽管自己英文不好,但觉得原作者们翻译的这个资料还是可以的,基本用法介绍清楚了.如果你英文比较好的话,可以看看官网的资料 ...
- iScroll.js 用法参考
本文原文链接:http://www.cnblogs.com/duanhuajian/archive/2013/04/08/3008323.html 概要 iScroll 4 这个版本完全重写了iScr ...
- 自己写的,然后配合zepto+iscroll的上拉加载
/** * Created by jl on 2016/3/28. *///初始化绑定iScroll控件var actHtml="";var myScroll, pullUp ...
- iScroll.js插件使用方法
iScroll.js 用法参考 (share) 分享是传播.学习知识最好的方法 以下这篇文章是iScroll.js官网的中文翻译,尽管自己英文不好,但觉得原作者们翻译的这个资料还是可以的,基本用法介绍 ...
- iscroll.js 手机上下滑动 加载更多
html <!DOCTYPE html> <html> <head> <title>下拉上拉刷新页面代码</title> <meta ...
- iScroll示例,下拉刷新,上拉刷新
iScroll示例,下拉刷新,上拉刷新 <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...
- iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决(转)
移动平台的活,兼容问题超多,今儿又遇到一个.客户要求在弹出层容器内显示内容,但内容条数过多,容器显示滚动条.按说是So easy,容器设死宽.高,CSS加属性 overflow:scroll; -we ...
随机推荐
- MarketServer 日志
2014.04.29 1. 发现有时候会跳出 Exception Infomations: 用户异常信息:Socket未连接 跟踪后发现的一次情况是: 服务器根据客户端请求从后台读取数据后,写数据 ...
- 用生产者消费模型爬取智联招聘python岗位信息
爬取python岗位智联招聘 这里爬取北京地区岗位招聘python岗位,并存入EXECEL文件内,代码如下: import json import xlwt import requests from ...
- Java并发编程,互斥同步和线程之间的协作
互斥同步和线程之间的协作 互斥同步 Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLo ...
- Mybatis中分页存在的坑1
站在巨人的肩膀上 https://www.cnblogs.com/esileme/p/7565184.html 环境:Spring 4.2.1 Mybatis 3.2.8 pagehelper 5.1 ...
- rpm、yum(转)
rpm http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/10/08/2203153.html yum http://www.cnblogs ...
- typescript学习笔记(一)----基础类型
1.使用typescript前第一个操作就是全局配置typescript环境 ---------------npm install -g typescript 2.typescript(以下称为ts, ...
- java数据结构----树
1.树:树通常结合了有序数组和链表的优点,在树中查找数据项的速度和在有序数组中查找一样快,并且插入数据项和删除数据项的速度也和链表一样快. 2.树由边连接的节点而构成.节点一般代表着一些实体,节点间的 ...
- TabBar背景颜色设置
// 第一种方式 // [[UITabBar appearance] setBarTintColor:[UIColor blackColor]]; // [UITabBar appearance].t ...
- php—Spl库常用数据结构基本用法
数据结构之一 : 栈 //zhan $stack = new SplStack(); $stack->push('data1'); $stack->push('data2'); echo ...
- Codeforces Round #396 (Div. 2) C
Mahmoud wrote a message s of length n. He wants to send it as a birthday present to his friend Moaz ...