/** * @下拉刷新 * 善有部分不完善之处,后续稍稍进行扩展 */ (function () { var isValid = false, // 是否生效 isTouching = false, // 触摸中标识 isEfec = false, // 触摸是否生效 isDestory = false, // 是否销毁 startX, startY, disY = 0, // 起始触摸X、y坐标, 移动Y坐标 loadingH = 0, // laodingEl高度 options = { $el: $('body'), // 默认容器 $loadingEl: null, // 刷新提示容器 autoHide: true, // 自动隐藏 url: undefined, // 请求数据地址 sendData: null, // 获取下拉刷新发送数据,动态传入,使用function返回数据 // 触发拖动像素距离(触发灵敏度), // 浏览器中下拉默认事件一旦触发后,就不能再通过冒泡阻止此事件。 // chrome浏览器中大概是15PX左右的下拉后触发默认刷新,微信中大概是6像素左右。 // 如需在微信中使用,建议设置为6像素 startPX: 6, callbacks: { pullStart: null, // 拖动开始 start: null, // 开始请求数据 success: null, // 数据请求成功 error: null, // 下拉流程结束 end: null, // 下拉流程结束 } }; var getPos = function (event) { var pos = { x: event.pageX || event.clientX, y: event.pageY || event.clientY } return pos; } /** * 重置 * @param Boolean isAnim 是否需要过度动画 */ var reset = function (isAnim) { isValid = false, // 是否生效 isEfec = false, // 触摸是否生效 startX, startY, disY = 0; options.$loadingEl.animate({'margin-top': -loadingH}, (!isAnim || isAnim === false ? 0 : 800), function () { isTouching = false; runCb('end'); }); } /** *下拉刷新 */ var touchStart = function (evt) { var scrollTop = parseInt(options.$el.scrollTop()); if (scrollTop > 0) return; if (isDestory) return; // if (isTouching) return; isTouching = true; isEfec = true; //evt.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = evt.touches[0], //获取第一个触点 x = parseInt(touch.pageX), //页面触点X坐标 y = parseInt(touch.pageY); //页面触点Y坐标 //记录触点初始位置 startX = x; startY = y; } /** * 触摸移动过程 */ var touchMove = function (evt) { if (isDestory) return; if (!isTouching) return; if (!isEfec) return; var $loadingEl = options.$loadingEl, touch = evt.touches[0], //获取第一个触点 x = parseInt(touch.pageX), //页面触点X坐标 y = parseInt(touch.pageY), //页面触点Y坐标 t = y - startY; // 触摸距离 // 距离必须大于灵敏距离触摸才生效 if (!isValid && t > options.startPX) { isValid = true; runCb('pullStart'); } if (!isValid) return; if (evt.preventDefault) evt.preventDefault(); // 向上拖动 if (t < 0) { $loadingEl.css('margin-top', -loadingH); } // 拖动高度未超过刷新显示容器高度 if (t > 0 && t <= loadingH) { $loadingEl.css('margin-top', -(loadingH - t)); $loadingEl.height(loadingH); } // 拖动高度超过刷新显示容器高度 else if (t > loadingH) { $loadingEl.css('margin-top', 0); $loadingEl.height(t); } disY = t; } /** * 执行回调函数 */ var runCb = function (name, data) { if (options.callbacks[name]) options.callbacks[name].call(null, data); } /** * 触摸结束,请求数据 */ var touchEnd = function (evt) { if (isDestory) return; if (!isValid) return; // 当前已生效 if (!isTouching) return; if (evt.preventDefault) evt.preventDefault(); isValid = false; isEfec = false; disY = 0; var $loadingEl = options.$loadingEl, touch = evt.touches[0] || evt.changedTouches[0], //获取第一个触点 x = parseInt(touch.pageX), //页面触点X坐标 y = parseInt(touch.pageY), //页面触点Y坐标 t = y - startY; // 拖动高度未超过刷新显示容器高度 if (t <= loadingH) { $loadingEl.css('margin-top', -(loadingH - t)); $loadingEl.height(loadingH); $loadingEl.animate({'margin-top': -loadingH}, 200, function () { isTouching = false; }); } // 拖动高度超过刷新显示容器高度 else if (t > loadingH) { if (options.cb) options.cb(); $loadingEl.animate({'height': loadingH}, 200, function () { }); } var sendData = $.isFunction(options.sendData) ? options.sendData() : options.sendData; if (options.url) { runCb('start'); $.post(options.url, sendData, function (response, textStatus, xhr) { runCb('success', response); if (options.autoHide) reset(); }).error(function () { runCb('error'); if (options.autoHide) reset(); }); } else { if (options.callbacks) reset(); } } /** * 设置是否销毁 */ var setDestroy = function (destroy) { isDestory = destroy || false; } /** * 初始化 * 定义loading容器高度 * 绑定处理事件 */ var initlize = function () { loadingH = options.$loadingEl.height(); $el = options.$el; $el[0].addEventListener('touchstart', touchStart, false); $el[0].addEventListener('touchmove', touchMove, false); $el[0].addEventListener('touchend', touchEnd, false); } var pullDown = function () { initlize(); return { reset: reset, setDestroy: setDestroy } } $.pPullRefresh = function (settings) { $.extend(true, options, (settings || {})); options.$el = options.$el || $('body'); return pullDown(settings); } $.fn.pPullRefresh = function (settings) { settings.$el = $(this); return $.pPullRefresh(settings); } })();