<!DOCTYPE html>
<html>
<head>
<title>test pull</title>
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<style type="text/css">
body {
margin: 50px;
}
.content{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow-y: scroll;
}
.content div.item{
background: #f1f1f1;
padding: 4px;
margin-bottom: 5px
}
.loader{
display: none;
float: right;
margin-top: -30px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div data-role="page" id="page">
<div data-role="header" data-tap-toggle="false" data-position="fixed">
<h3>Header</h3>
<div class="loader"><i class="glyphicon"></i></div>
</div>
<div data-role="content" class="content"></div>
</div>
</body>
</html>
var pullFresh = function(selector, options)
{
'use strict';
if( $(selector).find('._wrapper').length === 0)
{
$(selector).css({
'position' : 'relative',
'overflow-y' : 'scroll',
'-webkit-overflow-scrolling' : 'touch'
});
$(selector).wrapInner('<div class="_wrapper" />');
}
var container = $(selector).find('._wrapper'),
drag = false,
start_pos,
callbacks = {},
perform_callback = function(callback)
{
var args = Array.prototype.slice.call(arguments);
if(callbacks[callback])
callbacks[callback].apply(null, args.slice(1));
},
pull_animation = function(target, offset, delay)
{
var transform_prefixes = {
'transform' : '',
'WebkitTransform' : '-webkit-',
'MozTransform' : '-moz-',
'OTransform' : '-o-',
'msTransform' : '-ms-'
},
transform_prefix = false;
for(var computed in transform_prefixes)
{
var prefix = transform_prefixes[computed],
div = document.createElement('div');
if( div.style[computed] !== undefined )
{
transform_prefix = prefix;
}
}
if(!transform_prefix)
{
$(target).stop().animate({
top : offset
}, delay);
}
else
{
var css = {};
css[[transform_prefix, 'transform'].join('')] = 'translate3d(0px, %dpx, 0px)'.replace('%d', offset);
css[[transform_prefix, 'transition'].join('')] = 'top %dms ease'.replace('%d', delay);
$(container).css(css);
}
},
pull_pos = function()
{
return parseInt($(container).css('top'), 10);
},
reset_pos = function()
{
drag = false;
pull_animation(container, 0, 300);
},
set_default_opts = function(options)
{
var default_opts = {
threshold : 100,
offsetTop : 0
};
for(var opt in default_opts)
{
if( !options[opt] )
options[opt] = default_opts[opt];
}
return options;
};
options = set_default_opts(options || {});
this.on = function(type, callback)
{
if( $.inArray(type, ['refresh', 'pull', 'start-pull', 'end-pull', 'init']) === -1)
return false;
callbacks[type] = callback;
return this;
}
if( isNaN(pull_pos) )
{
$(container).css({
'top': 0,
'position' : 'relative'
});
}
// fix chrome pull refresh
if( /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) )
{
$( window ).on ('touchmove scroll', function(event)
{
if($(window).scrollTop() <= 0)
$(window).scrollTop(1);
});
}
$(container).on('vmousedown', function(event)
{
event.preventDefault();
drag = true;
start_pos = event.pageY;
perform_callback('start');
});
$(container).on('vmouseup vmouseleave', function(event)
{
drag = false;
reset_pos();
perform_callback('end-pull');
});
$(container).on('vmousemove', function(event)
{
event.preventDefault();
var pull_offset = (event.pageY - start_pos),
pull_percentage;
if( !drag )
return;
if( ($(window).scrollTop() - $('.content').offset().top) > options.offsetTop )
return;
if( pull_offset >= options.threshold || pull_offset < 0)
{
reset_pos();
perform_callback('end-pull');
if(pull_offset >= options.threshold)
perform_callback('refresh');
return;
}
//$(container).css('top', pull_offset);
pull_animation(container, pull_offset, 300);
perform_callback('pull', pull_offset, (pull_offset * 100) / options.threshold);
});
return this;
};
function __init()
{
$.ajax({
url: 'http://jsonplaceholder.typicode.com/posts',
method: 'GET',
dataType: 'json'
}).then(function(data) {
$(data).each(function(item, i){
if( !i.body )
return;
$(".content").append($('<div class="item" />').html(i.body));
});
new pullFresh('.content', {
threshold : 200
})
.on('refresh', function()
{
$('.loader .glyphicon')
.removeClass('glyphicon-arrow-down')
.addClass('glyphicon-refresh');
setTimeout(function(){
$('.loader').hide();
}, 1000);
})
.on('pull', function(pos, percentage)
{
$('.loader .glyphicon')
.addClass('glyphicon-arrow-down')
.removeClass('glyphicon-refresh');
$('.loader').show();
})
.on('end-pull', function()
{
});
});
}
$(document).ready(__init);
body {
margin: 50px;
}
.content{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow-y: scroll;
}
.content .item{
background: #f1f1f1;
padding: 4px;
margin-bottom: 5px
}
.loader{
display: none;
float: right;
margin-top: -30px;
}