<!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;
}