国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

JS+CSS實現(xiàn)下拉刷新/上拉加載插件

2024-05-06 16:36:16
字體:
供稿:網(wǎng)友

閑來無事,寫了一個當下比較常見的下拉刷新/上拉加載的jquery插件,代碼記錄在這里,有興趣將代碼寫成插件與npm包可以留言。

體驗地址:http://owenliang.github.io/pullToRefresh/

項目地址:https://github.com/owenliang/pullToRefresh

實現(xiàn)注意:

利用transition做動畫時,優(yōu)先使用transform:translate取代top,后者動畫流暢度存在問題。

各移動瀏覽器對手勢觸摸的處理不同(簡單羅列如下),但是下面的應(yīng)對方案又會導(dǎo)致部分瀏覽器的overflow:scroll失效,總之難以兼容:

微信瀏覽器下拉自帶回彈動畫:可以禁止document的touchmove事件默認處理行為。

谷歌瀏覽器下拉自帶刷新功能:利用屬性touch-action: none可以禁掉。

針對上述問題,我的建議是滾動一律用iscroll5插件模擬實現(xiàn)(非overflow:scroll),然后利用上面的方法禁掉瀏覽器的默認touchmove行為。

transition如果有多個屬性,那么transitionend回調(diào)會為每個屬性回調(diào)一次,因此遇到其中任意一個回調(diào)就應(yīng)該把css和transitionend回調(diào)都刪除掉。

瀏覽器在執(zhí)行JS代碼時沒有機會重繪UI,因此在使用transition的時候一定要注意把修改動畫終止CSS的代碼通過setTimeout延遲一會執(zhí)行。

貼代碼上首頁,歡迎留言交流,需一位有興趣有時間的朋友合作,主要做2件事:

1)插件改為NPM包。

2)基于pullToRefresh庫,開發(fā)類似"今日頭條"的左右滑動UI。

pullToRefresh.js:

/** * 為指定的容器添加滾動條,支持下拉刷新與上拉加載功能 * @param container 需要滾動的容器,要求設(shè)置css: position!=static,height= * @param option 配置項,詳見下方defaultOption說明 * @return 返回對象用于操控此區(qū)域,當前暴露了iscroll的refresh函數(shù),當你在插件之外向滾動區(qū)域增加/刪除內(nèi)容后應(yīng)該主動調(diào)用一次 * @description * * 2017-03-29 * 1)支持上拉加載 * 2017-03-30 * 1)改為jquery靜態(tài)函數(shù)插件 * 2)支持關(guān)閉下拉刷新或上拉加載 */$.installPullToRefresh =function (container, option) {  // 起始觸摸位置  var touchStartY = 0;  // 起始圖標位置  var pullStartY = 0;  // 當前的觸摸事件  var touchEvent = null;  // 當前的刷新事件  var refreshEvent = null;  // 當前圖標位置  var curY = -55;  // 當前的加載事件  var loadEvent = null;  // 默認參數(shù)  var defaultOption = {    // 刷新相關(guān)    noRefresh: false, // 關(guān)閉下拉刷新特性    pauseBound: 40, // 觸發(fā)刷新的位置(也是圖標loading暫停的位置)    lowerBound: 80, // 最大下拉到多少px    loadImg: "load.png", // loading圖片    pullImg: "pull.png", // 下拉圖片    onRefresh: function (refreshDone) { // 刷新數(shù)據(jù)回調(diào)      setTimeout(function() { // 默認不做任何事        refreshDone();      }, 0);    },    // 加載相關(guān)    noLoad: false, // 關(guān)閉上拉加載特性    bottomHeight: 1, // 距離滾動條底部多少px發(fā)起刷新    onLoad: function (loadDone) {      setTimeout(function() {        loadDone();      }, 0);    },  };  var finalOption = $.extend(true, defaultOption, option);  // 創(chuàng)建iscroll5滾動區(qū)域  var iscroll = new IScroll(container, {    bounce: false,  });  // 關(guān)閉上拉加載特性  if (!finalOption.noLoad) {    // 監(jiān)聽滾動結(jié)束事件,用于上拉加載    iscroll.on('scrollEnd', function () {      // 有滾動條的情況下,才允許上拉加載      if (iscroll.maxScrollY < 0) { // maxScrollY<0表明出現(xiàn)了滾動條        var bottomDistance = (iscroll.maxScrollY - iscroll.y) * -1;        // 距離底部足夠近,觸發(fā)加載        if (bottomDistance <= finalOption.bottomHeight) {          // 當前沒有刷新和加載事件正在執(zhí)行          if (!loadEvent && !refreshEvent) {            loadEvent = {}; // 生成新的加載事件            finalOption.onLoad(function (error, msg) {              loadEvent = null; // 清理當前的加載事件              // 延遲重繪滾動條              setTimeout(function () {                iscroll.refresh();              }, 0);            });          }        }      }    });  }  // 關(guān)閉下拉刷新特性  if (!finalOption.noRefresh) {    // 緊鄰滾動區(qū)域,容納刷新圖標    var pullContainer = $('<div class="pullContainer"></div>')    // 創(chuàng)建小圖標    var pullToRefresh = $('<div class="pullToRefresh"><img src="' + finalOption.pullImg + '"></div>');    // 保留小圖標的快捷方式    var pullImg = pullToRefresh.find("img");    // 小圖標加入到容器    pullContainer.append(pullToRefresh);    // 小圖標容器添加到滾動區(qū)域之前    $(container).before(pullContainer);    // 預(yù)加載loadImg    $('<img src="' + finalOption.loadImg + '">');    // 設(shè)置transform的函數(shù)    function cssTransform(node, content) {      node.css({        '-webkit-transform' : content,        '-moz-transform'  : content,        '-ms-transform'   : content,        '-o-transform'   : content,        'transform'     : content,      });    }    // 調(diào)整小圖標位置,角度,透明度    function goTowards(translateY, rotate, opcaticy) {      // 更新當前小圖標的位置,獲取css(transform)比較麻煩,所以每次變更時自己保存      curY = translateY;      // 旋轉(zhuǎn)圖標(根據(jù)抵達lowerBound的比例旋轉(zhuǎn),最大轉(zhuǎn)1圈)      if (rotate === undefined) {        rotate = (curY / finalOption.lowerBound) * 360;      }      // 透明度根據(jù)抵達pauseBound的比例計算      if (opcaticy === undefined) {        opcaticy = (curY / finalOption.pauseBound) * 1;        if (opcaticy > 1) {          opcaticy = 1;        }      }      // 改變位置和旋轉(zhuǎn)角度      cssTransform(pullToRefresh, "translateY(" + translateY + "px) translateZ(0)" + "rotateZ(" + rotate + "deg)");      // 改變透明度      pullToRefresh.css("opacity", opcaticy);    }    // 開啟回彈動畫    function tryStartBackTranTop() {      // 啟動回彈動畫      pullToRefresh.addClass("backTranTop");      // 判斷是否觸發(fā)刷新      if (curY >= finalOption.pauseBound) {        goTowards(finalOption.pauseBound);        // 回彈動畫結(jié)束發(fā)起刷新        pullToRefresh.on('transitionend webkitTransitionEnd oTransitionEnd', function (event) {          // 由于transitionend會對每個屬性回調(diào)一次,所以只處理其中一個          if (event.originalEvent.propertyName == "transform") {            // 暫停動畫            pullToRefresh.removeClass("backTranTop");            pullToRefresh.unbind();            // 透明度重置為1            goTowards(finalOption.pauseBound, undefined, 1);            // 切換圖片為loading圖            pullImg.attr("src", finalOption.loadImg);            // 因為anamition會覆蓋transform的原因,使用top臨時定位元素            pullToRefresh.addClass("loadingAnimation");            pullToRefresh.css("top", finalOption.pauseBound + "px");            // 回調(diào)刷新數(shù)據(jù),最終應(yīng)將refreshEvent傳回校驗            finalOption.onRefresh(function (error, msg) {              // 用戶回調(diào)時DOM通常已經(jīng)更新, 需要通知iscroll調(diào)整(官方建議延遲執(zhí)行,涉及到瀏覽器重繪問題)              setTimeout(function () {                iscroll.refresh();              }, 0);              // 重置角度,切換為pull圖              goTowards(finalOption.pauseBound);              // 取消animation,重置top              pullToRefresh.removeClass("loadingAnimation");              pullToRefresh.css("top", "");              // 延遲過渡動畫100毫秒,給瀏覽器重繪的機會              setTimeout(function () {                // 切換為pull圖                pullImg.attr("src", finalOption.pullImg);                // 恢復(fù)動畫                pullToRefresh.addClass("backTranTop");                // 刷新完成                refreshEvent = null;                // 彈回頂部                goTowards(-55);              }, 100);            });          }        });      } else {        goTowards(-55); // 彈回頂部        refreshEvent = null; // 未達成刷新觸發(fā)條件      }    }    // 父容器注冊下拉事件    $(container).on("touchstart", function (event) {      // 新的觸摸事件      touchEvent = {};      // 有一個刷新事件正在進行      if (refreshEvent) {        return;      }      // 只有滾動軸位置接近頂部, 才可以生成新的刷新事件      if (iscroll.y < -1 * finalOption.lowerBound) {        return;      }      // 一個新的刷新事件      refreshEvent = touchEvent;      touchStartY = event.originalEvent.changedTouches[0].clientY;      pullStartY = curY;      // 如果存在,則關(guān)閉回彈動畫與相關(guān)監(jiān)聽      pullToRefresh.removeClass("backTranTop");      pullToRefresh.unbind();      // 切換為pull圖      pullImg.attr("src", finalOption.pullImg);    }).on("touchmove", function (event) {      // 在刷新未完成前觸摸,將被忽略      if (touchEvent != refreshEvent) {        return;      }      var touchCurY = event.originalEvent.changedTouches[0].clientY;      var touchDistance = touchCurY - touchStartY; // 本次移動的距離      var curPullY = pullStartY + touchDistance; // 計算圖標應(yīng)該移動到的位置      // 向下不能拉出范圍      if (curPullY > finalOption.lowerBound) {        curPullY = finalOption.lowerBound;      }      // 向上不能拉出范圍      if (curPullY <= -55) {        curPullY = -55;      }      // 更新圖標的位置      goTowards(curPullY);    }).on("touchend", function (event) {      // 在刷新未完成前觸摸,將被忽略      if (touchEvent != refreshEvent) {        return;      }      // 嘗試啟動回彈動畫      tryStartBackTranTop();    });  }  // 初始化iscroll  setTimeout(function() {    iscroll.refresh();  }, 0);  // 返回操作此區(qū)域的工具對象  return {    // 用戶如果在下拉刷新之外修改了滾動區(qū)域的內(nèi)容,需要主動調(diào)用refresh    refresh: function() {      // 延遲以便配合瀏覽器重繪      setTimeout(function() {        iscroll.refresh();      }, 0);    },    // 觸發(fā)下拉刷新    triggerPull: function() {      // 正在刷新或者禁止刷新      if (refreshEvent || finalOption.noRefresh) {        return false;      }      // 暫??赡苷谶M行的最終階段回彈動畫      pullToRefresh.removeClass("backTranTop");      // 小圖標移動到lowerbound位置      goTowards(finalOption.lowerBound);      // 創(chuàng)建新的刷新事件,占坑可以阻止在setTimeout之前的觸摸引起刷新      refreshEvent = {};      // 延遲到瀏覽器重繪      setTimeout(function() {        tryStartBackTranTop();      }, 100);    },  };};Contact GitHub API Training Shop Blog About© 2017 GitHub, Inc. Terms Privacy Security Status Help

pullToRefresh.css:

.pullToRefresh {  position:absolute;  left:0;  right:0;  margin:auto;  width: 50px;  height: 50px;  z-index: 10;  opacity: 1;  transform:translateY(-55px) translateZ(0) rotateZ(0deg);  -ms-transform:translateY(-55px) translateZ(0) rotateZ(0deg);   /* IE 9 */  -moz-transform:translateY(-55px) translateZ(0) rotateZ(0deg);   /* Firefox */  -webkit-transform:translateY(-55px) translateZ(0) rotateZ(0deg); /* Safari 和 Chrome */  -o-transform:translateY(-55px) translateZ(0) rotateZ(0deg);   /* Opera */}.backTranTop{  transition: transform 0.8s ease, opacity 0.8s ease;  -moz-transition: transform 0.8s ease, opacity 0.8s ease; /* Firefox 4 */  -webkit-transition: transform 0.8s ease, opacity 0.8s ease; /* Safari 和 Chrome */  -o-transition: transform 0.8s ease, opacity 0.8s ease; /* Opera */}.pullContainer {  position:relative;}.pullToRefresh img {  display:block;  width: 40px;  height: 40px;  /* 讓img居中在.pullToRefresh中 */  position: absolute;  top: 0;  bottom: 0;  left:0;  right:0;  margin:auto;}/* loading旋轉(zhuǎn)動畫 */.loadingAnimation{  animation: loadingFrame 1s infinite;  -moz-animation: loadingFrame 1s infinite;  /* Firefox */  -webkit-animation: loadingFrame 1s infinite;  /* Safari 和 Chrome */  -o-animation: loadingFrame 1s infinite;  /* Opera */}@keyframes loadingFrame{  from {    transform: rotateZ(360deg);  }  to {    transform: rotateZ(0deg);  }}@-moz-keyframes loadingFrame /* Firefox */{  from {    transform: rotateZ(360deg);  }  to {    transform: rotateZ(0deg);  }}@-webkit-keyframes loadingFrame /* Safari 和 Chrome */{  from {    transform: rotateZ(360deg);  }  to {    transform: rotateZ(0deg);  }}@-o-keyframes loadingFrame /* Opera */{  from {    transform: rotateZ(360deg);  }  to {    transform: rotateZ(0deg);  }}

以上所述是小編給大家介紹的JS+CSS實現(xiàn)下拉刷新/上拉加載插件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對VeVb武林網(wǎng)網(wǎng)站的支持!


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 仁化县| 玛多县| 北海市| 麻阳| 湟源县| 林西县| 乌兰察布市| 扶余县| 洛宁县| 西畴县| 马边| 房产| 米林县| 濉溪县| 司法| 泉州市| 葵青区| 门头沟区| 九江县| 嘉禾县| 光泽县| 兰考县| 平凉市| 水富县| 双江| 基隆市| 巴青县| 依兰县| 望都县| 那曲县| 兴仁县| 乡宁县| 怀集县| 卓尼县| 滦平县| 张家口市| 宁乡县| 德阳市| 岐山县| 永川市| 泾川县|