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&timestamp=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的更多相关文章

  1. iScroll 4.2.5 中文API

    概况 资料来源 http://cubiq.org/iscroll-4 http://www.cnblogs.com/wanghun/archive/2012/10/17/2727416.html ht ...

  2. jquery——移动端滚动条插件iScroll.js

    官网:http://cubiq.org/iscroll-5 demo: 滚动刷新:http://cubiq.org/dropbox/iscroll4/examples/pull-to-refresh/ ...

  3. iScroll.js 用法参考 (share)

    分享是传播.学习知识最好的方法 以下这篇文章是iScroll.js官网的中文翻译,尽管自己英文不好,但觉得原作者们翻译的这个资料还是可以的,基本用法介绍清楚了.如果你英文比较好的话,可以看看官网的资料 ...

  4. iScroll.js 用法参考

    本文原文链接:http://www.cnblogs.com/duanhuajian/archive/2013/04/08/3008323.html 概要 iScroll 4 这个版本完全重写了iScr ...

  5. 自己写的,然后配合zepto+iscroll的上拉加载

    /** * Created by jl on 2016/3/28. *///初始化绑定iScroll控件var actHtml="";var myScroll,    pullUp ...

  6. iScroll.js插件使用方法

    iScroll.js 用法参考 (share) 分享是传播.学习知识最好的方法 以下这篇文章是iScroll.js官网的中文翻译,尽管自己英文不好,但觉得原作者们翻译的这个资料还是可以的,基本用法介绍 ...

  7. iscroll.js 手机上下滑动 加载更多

    html <!DOCTYPE html> <html> <head> <title>下拉上拉刷新页面代码</title> <meta ...

  8. iScroll示例,下拉刷新,上拉刷新

    iScroll示例,下拉刷新,上拉刷新 <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...

  9. iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决(转)

    移动平台的活,兼容问题超多,今儿又遇到一个.客户要求在弹出层容器内显示内容,但内容条数过多,容器显示滚动条.按说是So easy,容器设死宽.高,CSS加属性 overflow:scroll; -we ...

随机推荐

  1. CodeForces Canada Cup 2016【A,B,C,D】

    CodeForces 725A: 思路就是如果"最左"不是'>'这个了,那么这个右边的一定不可能到达左边了: 同理最右: CodeForces 725B: 有两个空姐,一个从 ...

  2. Node.js 的回调模式

    我们都知道在javaScript中,如果在head标签里面引入script脚本,在打开web的时候,浏览器会先加载head中的信息,再加载body的信息: 如果head中有link标签,浏览器会开启一 ...

  3. MySQL - 执行sql报错USING BTREE

    问题与分析 在执行sql文件时发现报错如下: You have an error in your SQL syntax; check the manual that corresponds to yo ...

  4. [題解]luogu_P3205/BZOJ_1996 合唱隊

    前言:基本上發題解的都是抄的題解所以 來源:題解 题目描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个 ...

  5. BZOJ2440(容斥+莫比乌斯函数)

    题目本质: 首先有如下结论: 而通过写一写可以发现: 举例来讲,36及其倍数的数,会被1的倍数加一遍,被4的倍数扣一遍,会被9的倍数扣一遍,而为了最终计数为0,需要再加回来一遍,所以在容斥里面是正号. ...

  6. 096 Unique Binary Search Trees 不同的二叉查找树

    给出 n,问由 1...n 为节点组成的不同的二叉查找树有多少种?例如,给出 n = 3,则有 5 种不同形态的二叉查找树:   1         3     3      2      1    ...

  7. 8593 最大覆盖问题 two pointer

    8593 最大覆盖问题 时间限制:50MS  内存限制:1000K提交次数:193 通过次数:88 题型: 编程题   语言: G++;GCC;VC Description 输入格式 第1行是正整数n ...

  8. ueditor单独调用图片上传

    很多人在问ueditor,如何单独使用图片上传功能,但是网上没有一篇能用的文档,没办法,我刚好也需要这个功能,花了3天时间(本人水平太菜,哎)终于知道怎么处理了,发出来给大家共享: 效果如下: 页面效 ...

  9. php pack、unpack、ord 函数使用方法(二进制流接口应用实例)

    在工作中,我也逐渐了解到pack,unpack,ord对于二进制字节处理的强大. 下面我逐一介绍它们.在我们工作中,用到它们的估计不多. 我在最近一个工作中,因为通讯需要用到二进制流,然后接口用php ...

  10. Docker与虚拟机

    Docker与虚拟机 简述 Docker 在容器的基础上,进行了进一步的封装,从文件系统.网络互联到进程隔离等等,极大的简化了容器的创建和维护.使得 Docker 技术比虚拟机技术更为轻便.快捷.下面 ...