Sau cùng ngày, tôi đã thực hiện một cuộn vô hạn trơn tru và kéo để làm mới ứng dụng mẫu sử dụng iscroll4. hai chức năng này đã được triển khai trong một ứng dụng mẫu mà tôi đã tạo. hy vọng nó hữu ích cho cộng đồng nhà phát triển ứng dụng dành cho thiết bị di động này.
đầu tiên người ta cho rằng:
- bạn đã quen thuộc với các chức năng iscroll4 (Không có nhiều của một cos cần thiết đang không phải là một guru hoặc là).
- bạn biết làm thế nào để thực hiện cuộc gọi ajax vào một tập tin json hoặc tệp json/php
tóm tắt ứng dụng của tôi:
khi người dùng tải ứng dụng của tôi, nó làm cho một cuộc gọi ajax để json tập tin/php trên máy chủ của tôi và một số giá trị được trả về.
Vấn đề bản chất: tôi muốn vô hạn di chuyển cùng kéo để làm mới chức năng và tôi không muốn sử dụng bất kỳ khuôn khổ khác nhau từ iscroll4.
giải pháp của tôi:
<!DOCTYPE html>
<html lang="en">
<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">
<link href="http://fonts.googleapis.com/css?family=Headland+One%7COpen+Sans:400,300&subset=latin,cyrillic" rel="stylesheet" type="text/css"></link>
<link href="css/mystylesheet.css" rel="stylesheet">
<style>
/**
*
* Horizontal Scrollbar
*
*/
.myScrollbarH {
position:absolute;
z-index:100;
height:8px;
bottom:1px;
left:2px;
right:7px
}
.myScrollbarH > div {
position:absolute;
z-index:100;
height:100%;
/* The following is probably what you want to customize */
background:-webkit-gradient(linear, 0 0, 100% 0, from(#226BF4), to(#226B8F));
background-image:-moz-linear-gradient(top, #226BF4, #226B8F);
background-image:-o-linear-gradient(top, #226BF4, #226B8F);
border:1px solid #226BF4;
-webkit-background-clip:padding-box;
-moz-background-clip:padding-box;
-o-background-clip:padding-box;
background-clip:padding-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-o-box-sizing:border-box;
box-sizing:border-box;
-webkit-border-radius:4px;
-moz-border-radius:4px;
-o-border-radius:4px;
border-radius:4px;
-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
-moz-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
-o-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
}
/**
*
* Vertical Scrollbar
*
*/
.myScrollbarV {
position:absolute;
z-index:100;
width:8px;bottom:7px;top:2px;right:1px
}
.myScrollbarV > div {
position:absolute;
z-index:100;
width:100%;
/* The following is probably what you want to customize */
background:-webkit-gradient(linear, 0 0, 100% 0, from(#226BF4), to(#226B8F));
background-image:-moz-linear-gradient(top, #226BF4, #226B8F);
background-image:-o-linear-gradient(top, #226BF4, #226B8F);
border:1px solid #226BF4;
-webkit-background-clip:padding-box;
-moz-background-clip:padding-box;
-o-background-clip:padding-box;
background-clip:padding-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-o-box-sizing:border-box;
box-sizing:border-box;
-webkit-border-radius:4px;
-moz-border-radius:4px;
-o-border-radius:4px;
border-radius:4px;
-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
-moz-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
-o-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
}
/**
*
* Pull down styles
*
*/
#pullDown, #pullUp {
background:#fff;
height:40px;
line-height:40px;
padding:5px 10px;
border-bottom:1px solid #ccc;
font-weight:bold;
font-size:14px;
color:#888;
}
#pullDown .pullDownIcon, #pullUp .pullUpIcon {
display:block; float:left;
width:40px; height:40px;
background:url(images/[email protected]) 0 0 no-repeat;
-webkit-background-size:40px 80px; background-size:40px 80px;
-webkit-transition-property:-webkit-transform;
-webkit-transition-duration:250ms;
}
#pullDown .pullDownIcon {
-webkit-transform:rotate(0deg) translateZ(0);
}
#pullUp .pullUpIcon {
-webkit-transform:rotate(-180deg) translateZ(0);
}
#pullDown.flip .pullDownIcon {
-webkit-transform:rotate(-180deg) translateZ(0);
}
#pullUp.flip .pullUpIcon {
-webkit-transform:rotate(0deg) translateZ(0);
}
#pullDown.loading .pullDownIcon, #pullUp.loading .pullUpIcon {
background-position:0 100%;
-webkit-transform:rotate(0deg) translateZ(0);
-webkit-transition-duration:0ms;
-webkit-animation-name:loading;
-webkit-animation-duration:2s;
-webkit-animation-iteration-count:infinite;
-webkit-animation-timing-function:linear;
}
@-webkit-keyframes loading {
from { -webkit-transform:rotate(0deg) translateZ(0); }
to { -webkit-transform:rotate(360deg) translateZ(0); }
}
</style>
</head>
<body style="overflow: hidden;" onload="do_refresh();">
<div class="wrap">
<div id="wrapper">
<div id="scroller">
<div id="pullDown">
<span class="pullDownIcon"></span><span class="pullDownLabel">Pull down to refresh...</span>
</div>
<div class="content">
<input type="hidden" id="last_id">
<div id="responsecontainer"></div>
</div>
<span class="load_more_loading" ></span>
</div>
</div>
</div>
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script src="js/iscroll.js"></script>
<script src="js/pulltorefresh.js"></script>
<script src="js/infinitescroll.js></script>
<script src="js/myinitialloadscript.js"></script>
<script src="js/mymobileframework.js"></script> <!--independent of this script. eg. whormhole from mosync-->
</body>
</html>
tiếp theo là tạo kịch bản myinitialloadscript.js. điều này cho phép tải nội dung vào ứng dụng lần đầu tiên trên trang đó.
function do_refresh()
{
var url = "http://localhost/public_html/landing.php?token=908765789897867567687989089786768980&validator=jhjhjjhjhkhj"; //just url params
// -------------------------------------------
$.ajax({
type: 'GET',
url: url,
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
// Evaluate text as a json expression
converters: {"text jsonp": jQuery.parseJSON},
timeout:30000,
async: true,
jsonp: true,
jsonpCallback: "myJsonMethod",
beforeSend: function()
{
//add loading image i dint bcos the image or values becomes double in a case of network delay
$("#responsecontainer").html("images/loader.gif").show();
},
success: function(data)
{
ajax.parseJSONP(data);
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log(errorThrown);
alert("Could Not Refresh.");
$("#responsecontainer").html("");//remove loading image
//$("#responsecontainer").load("refresh_h.html"); //load a page with refresh option.
}
});
$.ajaxSetup({ cache: false }); //fetch data from db not cache content
}
//if data is fectched successfully then
var ajax = {
parseJSONP:function(data){
$.each(data, function(i, row) {
if (i==0){
$("#responsecontainer").html('');
}
var ul = '<li>'+row.myjsondatakey+'</li>'; //could be <div></div> This only displays your values from db in a styled manner
$(ul).appendTo('#responsecontainer');// append the value to the responsecontainer
//Now watch closely. remember it was assumed you have a json file or json/php file, and in
//most cases you get your json data format from PHP file. so we assume its from a php file.
//also note that php calls to db can have a LIMIT. so in this case my PHP file data LIMIT
//was set to 5. because of infinite scrolling, i need to know the id of the last element
//from my returned data. so i write the following. note that my row.id_comments which is my
//value i want to get was written into an input whose visibility is hidden. this is to
//enable me over write its value when the last id changes.
if (i==4)
{
//set last id value
$('#last_id').val(row.id_comments);
}
});
}
}
tiếp theo là triển khai pulltorefresh.js nhiều điều không thể nói về điều này vì ví dụ trong iscroll4 rõ ràng.
var myScroll,
pullDownEl, pullDownOffset,
pullUpEl, pullUpOffset,
generatedCount = 0;
function pullDownAction() {
var el;
el = document.getElementById('responsecontainer');
var url = "http://localhost/public_html/landing.php?token=78654567897654356789976546789&valid=jhjhjjhjhkhj";
$.ajax({
type: 'GET',
url: url,
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
// Evaluate text as a json expression
converters: {"text jsonp": jQuery.parseJSON},
timeout:30000,
async: true,
jsonp: true,
jsonpCallback: "myJsonMethod",
error: function(){
myScroll.refresh(); //do nofin
},
success: function(data){
//console.dir('success');
ajax.parseJSONP(data);
}
});
$.ajaxSetup({ cache: false }); //fetch data from db not cache content
var ajax = {
parseJSONP:function(data){
$.each(data, function(i, row) {
if (i==0){
$("#responsecontainer").html('');
}
var ul = '<li>'+row.myjsondatakey+'</li>';
$(ul).appendTo(el);
if (i==4)
{
//set last id value
$('#last_id').val(row.id_comments);
}
myScroll.refresh(); // Remember to refresh when contents are loaded (ie: on ajax completion)
});
}
}
}
function loaded() {
pullDownEl = document.getElementById('pullDown');
pullDownOffset = pullDownEl.offsetHeight;
myScroll = new iScroll('wrapper', {
scrollbarClass: 'myScrollbar',
useTransition: true,
topOffset: pullDownOffset,
onRefresh: function() {
if (pullDownEl.className.match('loading')) {
pullDownEl.className = '';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
}
},
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;
}
},
//here is where infinite scroll comes in
onScrollEnd: function() {
//infinite scroll started
if(Math.abs(this.maxScrollY) - Math.abs(this.y) < 10)
{
// Do infinite if scroll is 10px from the bottom.
doInfinite_scroll();
}
//infinite scroll ended
if (pullDownEl.className.match('flip')) {
pullDownEl.className = 'loading';
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
pullDownAction(); // Execute custom function (ajax call?)
}
}
});
setTimeout(function() { document.getElementById('wrapper').style.left = '0'; }, 800);
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function() { setTimeout(loaded, 200); }, false);
và cuối cùng nhưng không kém phần các infinitescroll.js chính nhớ lại rằng trước đây chúng tôi đã đặt một cuộc gọi đến chức năng này trong pulltorefresh.js nơi chúng tôi đã nói nếu thanh cuộn được 10px đến cuối cuộn inifite nên được kích hoạt.Sau đó, chúng tôi có này như bắn để được bắn.
function doInfinite_scroll()
{
var last_id = $('#last_id').val();
var searching = false;
if (!searching) { // only initiate a new ajax request if this variable is false this is to avoid data duplication.
var el;
el = document.getElementById('responsecontainer');
var url = "http://localhost/public_html/landing_more.php?last_id="+last_id+"&token=9876543456789765432456789876543&valid=jhjhjjhjhkhj";
// -------------------------------------------
$.ajax({
type: 'GET',
url: url,
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
// Evaluate text as a json expression
converters: {"text jsonp": jQuery.parseJSON},
timeout:30000,
async: true,
jsonp: true,
jsonpCallback: "myJsonMethod",
error: function(){
myScroll.refresh(); //do nofin
},
beforeSend: function()
{
//add loading image i dint bcos the image or values becomes double in a case of network delay
searching = true; // set variable to true
},
success: function(data){
searching = false; // set variable to false
//console.dir('success');
ajax.parseJSONP(data);
}
});
$.ajaxSetup({ cache: false });//fetch data from db not cache content
var ajax = {
parseJSONP:function(data){
$.each(data, function(i, row) {
var ul = '<ul>'+row.comments+'</ul>';
if (i==1) //bcos its php data limit was set to 2 so its always N-1 i.e yourlimit - 1
{
//resset lastdeed id value
$('#lastdeed_id').val(row.id_comments); //update the value in the hidden input field to enable the next set of data load properly
}
$(ul).appendTo(el);
myScroll.refresh(); // Remember to refresh when contents are loaded (ie: on ajax completion)
});
}
}
}
}
vì vậy chỉ trong trường hợp bạn bị mất với tệp php sẽ trông như thế nào ở đây. Tập tin này là landing.php
<?php
// Prevent caching.
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jan 1996 00:00:00 GMT');
if ((isset($_GET['token'])) && (isset($_GET['valid']))) {
@require_once('connect/connectionfile.php');
$token=htmlspecialchars($_GET['token'],ENT_QUOTES);
$token= mysql_real_escape_string($token);
$valid=htmlspecialchars($_GET['valid'],ENT_QUOTES);
$valid= mysql_real_escape_string($valid);
//now validating the token
$sql="SELECT * FROM bla WHERE blabla='$token'";
$result=mysql_query($sql);
//if token exists
if(mysql_num_rows($result))
{
header('Content-type: application/json');
//valid token
$fakevalue = mysql_fetch_assoc($result);
$uid = $fakevalue['id'];
$results = array();
$query = "SELECT * FROM bla bal WHERE bla bla bla DESC LIMIT 0, 5";
$rsult = mysql_query($query);
while($value = mysql_fetch_assoc($rsult, MYSQL_ASSOC))
$results[] = $value;
{
echo "myJsonMethod".'('.json_encode($results).')'; //ECHO RESULTS IN JSONP FORMAT
}
}
else
{
//Invalid token
header('Content-type: application/json');
echo "myJsonMethod({\"token\":".utf8_encode(json_encode('failed'))."})";
}
}
else {
header('Content-type: application/json');
echo "myJsonMethod({\"token\":".utf8_encode(json_encode('Invalid token check parameters'))."})";
}
?>
tập tiếp theo này là dành cho di chuyển vô hạn và nó được gọi là landing_more.php
<?php
// Prevent caching.
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jan 1996 00:00:00 GMT');
if ((isset($_GET['token'])) && (isset($_GET['validator']))) {
@require_once('connect/connectionfile.php');
$token=htmlspecialchars($_GET['token'],ENT_QUOTES);
$token= mysql_real_escape_string($token);
$validator=htmlspecialchars($_GET['validator'],ENT_QUOTES);
$validator= mysql_real_escape_string($validator);
$last_id=htmlspecialchars($_GET['last_id'],ENT_QUOTES);
$last_id=mysql_real_escape_string($last_id);
//now validating the token
$sql="SELECT * FROM bla WHERE blabla='$token'";
$result=mysql_query($sql);
//if token exists
if(mysql_num_rows($result))
{
header('Content-type: application/json');
//valid token
$fakevalue = mysql_fetch_assoc($result);
$uid = $fakevalue['id'];
$results = array();
$query = "SELECT * FROM bla bla WHERE bla && bla bla && a.id_comments < '$last_id' ORDER BY a.id_comments DESC LIMIT 0, 2";
$rsult = mysql_query($query);
while($value = mysql_fetch_assoc($rsult, MYSQL_ASSOC))
$results[] = $value;
{
echo "myJsonMethod".'('.json_encode($results).')'; //ECHO RESULTS IN JSONP FORMAT
}
}
else
{
//Invalid token
header('Content-type: application/json');
echo "myJsonMethod({\"token\":".utf8_encode(json_encode('failed'))."})";
}
}
else {
header('Content-type: application/json');
echo "myJsonMethod({\"token\":".utf8_encode(json_encode('Invalid token check parameters'))."})";
}
?>
Cảm ơn. Lưu ý rằng bạn có thể bao gồm hàm onScrollEnd như một phần của các tùy chọn được chuyển vào hàm tạo, ví dụ: iScroll mới ('element', {onScrollEnd: function() {...}); – jackocnr
Tuyệt vời, đó là những gì tôi đang tìm kiếm. – Xinan
Điều này cũng có thể được sử dụng nếu bạn cần sử dụng, ví dụ: iScroll-probe's và bất kỳ tính năng nào khác của 'fragrance', như zoom, trên V5. Trong ví dụ này, bạn có thể chỉ cần sử dụng iScroll-zoom và sử dụng sự kiện này để cấu hình cuộn vô hạn của bạn. – StinkyCat