亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

學(xué)習(xí)移動(dòng)端組件 Picker一下

iOS122 / 3063人閱讀

摘要:原文前言一個(gè)移動(dòng)端的事件或者事件,具體看看怎么玩。初始化組件已經(jīng)有了基本的組件,現(xiàn)在我們開始進(jìn)行一個(gè)初始化。因?yàn)槲覀兊谝粋€(gè)元素需要向下移動(dòng)一列,所以第一列應(yīng)該是空的這個(gè)時(shí)候位置也是我們位移最大位置??磮D最后目前只是一個(gè)最基本的例子。

原文: https://www.luoyangfu.com/art...
前言

一個(gè)移動(dòng)端的touch 事件或者 mouse 事件,具體看看怎么玩。

先看看效果:

這里年月日都是使用創(chuàng)建好的Picker組件來實(shí)現(xiàn)的,在之前感謝博客園 @糊糊糊糊糊了, 原文地址.

原文中講了實(shí)現(xiàn)Picker核心思路,我也是受益頗多,然后根據(jù)思路以及Github源碼,終于寫了自己想要的Picker,于是就有了記錄,再次感謝.

多帶帶Picker HTML 結(jié)構(gòu)

開發(fā)這個(gè)Picker, 觀察Picker節(jié)點(diǎn)結(jié)構(gòu),Picker 是由定高隱藏元素的塊, 一個(gè)定高不隱藏元素的的塊,以及一個(gè)選擇列表組成這三個(gè)部分。我們得知了這個(gè)Picker組成后很容易就可以寫出來下面HTML的結(jié)構(gòu):

2016
2017
2018
2019
2020

這個(gè)就是最簡單的 picker 結(jié)構(gòu)了。

CSS 樣式

咱們給這塊結(jié)構(gòu)添加樣式,顯示如下, 在這里我們默認(rèn)元素的高度在css 中寫死為 50px.

我們這里就寫了關(guān)于 Picker 基礎(chǔ)樣式。

.picker {
  overflow: hidden;
  position: relative;
  z-index: 1;
}

.picker-wrapper {
  overflow: visible;
  height: calc(50px * 3);
}

.picker-item {
  height: 50px;
  line-height: 50px;
  text-align: center;
  color: #999;
}

.picker-item.active {
  color: #000;
}

.picker-center-highlight {
  height: 50px;
  position: absolute;
  width: 100%;
  top: 50%;
  margin-top: -25px;
  z-index: 2;
}

.picker-center-highlight::before, .picker-center-highlight::after {
  content: "";
  display: block;
  height: 2px;
  background-color: #000;
  width: 100%;
  transform: scaleY(0.5);
  position: absolute;
}

.picker-center-highlight::before {
  top: 0;
}

.picker-center-highlight::after {
  bottom: 0;
}

上面僅僅僅僅包含圖片樣式組成,后續(xù)會(huì)逐漸添加各種樣式。

初始化Picker組件

已經(jīng)有了基本的 Picker 組件,現(xiàn)在我們開始進(jìn)行一個(gè)初始化。讓第一個(gè)元素顯示在正確的位置。
這里有兩個(gè)基本問題需要先考慮一下:

元素的移動(dòng)范圍

元素的下標(biāo)和位置交換

元素的移動(dòng)范圍

我們元素移動(dòng)范圍用下標(biāo)來說的話,應(yīng)該是 1 到 length, 這里length 就是傳入Picker數(shù)據(jù)長度。

因?yàn)槲覀兊谝粋€(gè)元素需要向下移動(dòng)一列,所以第一列應(yīng)該是空的, 這個(gè)時(shí)候位置也是我們位移最大位置。當(dāng)不斷將Picker 向上位移什么時(shí)候?yàn)樽钚〉奈恢媚兀繎?yīng)該是有這樣計(jì)算 (length - Math.ceil(count / 2)) * 50. 這里我們說的是顯示3列情況, length 為數(shù)據(jù)長度, 50為單個(gè)Picker高度,上文已有。

下面直接看元素結(jié)算范圍:

const getMoveRange = function() {
  const max = Math.floor(visibleCount / 2) * itemHeight;
  const min = (itemLength - Math.ceil(visibleCount / 2)) * -itemHeight;
  return [min, max]
}

這里就解決了第一個(gè)元素的范圍問題。

這里使用兩個(gè)數(shù)學(xué)函數(shù):
Math.floor 取不大于該數(shù)的最大整數(shù)
Math.ceil 取不小于該數(shù)的最小整數(shù)
元素的下標(biāo)和位置交換

這里需要兩個(gè)函數(shù)分別來計(jì)算使用下標(biāo)獲取位置,使用位置來獲取下標(biāo)的。

通過下標(biāo)獲取元素位置時(shí)候有一點(diǎn)需要注意的是,我們元素位置是需要根據(jù)當(dāng)前顯示的個(gè)數(shù)進(jìn)行偏移的,也就說,在計(jì)算之前,需要減去偏移量。偏移量剛好等于 Math.floor(count / 2)。

const getTranslByIndex = function(index) {
  const offset = Math.floor(visibleCount / 2)
  
  if(index >= 0) {
    return (index - offset) * -itemHeight
  }
}

通過位移獲取元素位置就簡單很多了。

const getIndexByTransl = function(transl) {
  transl = Math.round(transl / itemHeight) * itemHeight;
  const index = - (transl - Math.floor(visibleCount / 2) * itemHeight) / itemHeight;
  
  return index;
}

計(jì)算用了三行代碼, 第一行主要是轉(zhuǎn)化當(dāng)前位置靠近哪一個(gè)元素,得到具體translate,第二行 計(jì)算具體的 index, 這里計(jì)算語句前面使用 -減號(hào), 主要因?yàn)?translate 減去顯示個(gè)數(shù)的1/2后,總是負(fù)值,這里需要將負(fù)值轉(zhuǎn)正,也可以使用 Math.abs 來替代。

上面我們就解決了兩個(gè)問題。

初始化組件

首先需要組件初始化為上圖的樣子,這個(gè)時(shí)候,我們開始監(jiān)聽事件,這了我們主要監(jiān)聽 touchstart, touchmove, touchend 事件。

const translateEl = function(transl) {
  el.style.transform = `translateY(${transl}px)`;
};

const setSelectedEl = function(index) {
  Array.prototype.forEach.call(pickerItems, (item, idx) => {
    item.classList.remove("active");
  });
  pickerItems[index].classList.add("active");
};

function initEvent() {
  el.addEventListener("touchstart", function(e) {
    console.log("touchstart", e);
  });
  el.addEventListener("touchmove", function(e) {
    console.log("touchmove", e);
  });
  el.addEventListener("touchend", function(e) {
    console.log("touchenv", e);
  });
}

window.onload = function onload() {
  translateY = getTranslByIndex(0);
  setSelectedEl(0);
  translateEl();
  initEvent();
};

上面的 pickerItems 就是選中的picker 元素集合.

這里就對(duì)元素進(jìn)行了touchstart,touchmove, touchend 監(jiān)聽。下面我進(jìn)一步對(duì)事件做處理,讓picker動(dòng)起來。
為了讓picker 在移動(dòng)過程中有過度效果,增加如下css

.picker-wrapper {
    overflow: visible;
    height: calc(50px * 3);
    transition: all 0.3s ease-in-out; /* 這里就對(duì) 元素做了過渡動(dòng)畫處理*/
}

開始對(duì)事件進(jìn)行處理

el.addEventListener("touchstart", function(e) {
    startAt = Date.now();
    startTop = e.touches[0].pageY;
    // 開始滾動(dòng)的位置
    startTranslateY = translateY;
  });
  el.addEventListener("touchmove", function(e) {
    const deltaY = e.touches[0].pageY - startTop;
    translateY = startTranslateY + deltaY;
    velocityTranslate = translateY - prevTranslateY || translateY;

    prevTranslateY = translateY;
    translateEl();
  });
  el.addEventListener("touchend", function(e) {
    let momentumTranslate = 0;
    // 小于 300 就開始彈性滾動(dòng)
    if (Date.now() - startAt < 300) {
      momentumTranslate = translateY + velocityTranslate * momentumRatio;
    }

    let translate = Math.round(translateY / itemHeight) * itemHeight;

    if (momentumTranslate) {
      translate = Math.round(momentumTranslate / itemHeight) * itemHeight;
    }

    const range = getMoveRange();
    translateY = Math.max(Math.min(translate, range[1]), range[0]);
    translateEl();
    const index = getIndexByTransl(translateY);
    setSelectedEl(index);
  });

  // 每個(gè)item 點(diǎn)擊生效
  Array.prototype.forEach.call(pickerItems, function(item, index) {
    item.addEventListener("click", function(e) {
      setSelectedEl(index);
      translateY = getTranslByIndex(index);
      translateEl();
    });
  });

這里就對(duì)觸摸事件做了處理,也對(duì)單個(gè)元素的點(diǎn)擊做了監(jiān)聽。

const el = document.querySelector("#wrapper");
const itemHeight = 50;
const visibleCount = 3;
const itemLength = 5;
const pickerItems = document.querySelectorAll(".picker-item");
let startAt = Date.now();
let startTop = 0;
let translateY = 0;
let startTranslateY = 0;
let prevTranslateY = 0;
// 動(dòng)力參數(shù)
let momentumRatio = 7;
// 速度速度位移
let velocityTranslate = 0;

這里再開頭申明了一些內(nèi)容,主要說明一下 momentumRatiovelocityTranslate 這兩個(gè),前者是動(dòng)力系數(shù)用于短時(shí)間修改位移后慣性移動(dòng),后者是速度位移用于在用戶移動(dòng)過程中移動(dòng)的量。

現(xiàn)在就完成了一個(gè)基本的Picker??磮D:

最后

目前只是一個(gè)最基本的例子。如果說需要選擇兩側(cè)有一個(gè)縮放呢。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105269.html

相關(guān)文章

  • 記 vue 移動(dòng)開發(fā) 中的經(jīng)驗(yàn)(2)

    摘要:官網(wǎng)還不斷的訪問不了。在此推薦一個(gè)移動(dòng)端庫按需引入二次封裝組件列表的下拉刷新和上拉加載更多是移動(dòng)端必須的組件。不用寫死高度了,并且兼容對(duì)外提供了更加簡明易用的刷新,回到頂部,獲得和設(shè)置滾動(dòng)條位置的方法統(tǒng)一的提示,免去重復(fù)代碼。 按需引入mint-ui 本項(xiàng)目用了 mint-ui 作為基礎(chǔ)ui框架,在使用中遇到不少問題。官網(wǎng)doc 還不斷的訪問不了。不過還是很感謝 mint-ui 團(tuán)隊(duì)。...

    Flands 評(píng)論0 收藏0
  • 地區(qū)picker 各選擇器,優(yōu)劣分析

    摘要:移動(dòng)端選擇器有很多,各大組件都有自己的,比如,,,等等。這次的地區(qū)選擇,需要地區(qū)的省份市經(jīng)緯度,還要設(shè)置第一次點(diǎn)開的時(shí)候是特定城市。引入樣式和文件地區(qū)選擇級(jí)聯(lián)地區(qū)選擇設(shè)定默認(rèn)選項(xiàng)省份城市代碼很簡單,不懂的百度一下。移動(dòng)端選擇器picker有很多,各大ui組件都有自己的picker,比如light7,HUI,MUI,jqueryUI等等。但是,我發(fā)現(xiàn)他們都有各種各樣的問題。這次的地區(qū)選擇,需要...

    番茄西紅柿 評(píng)論0 收藏0
  • 基于 vue 的 picker 組件 vue-awesome-picker

    摘要:本組件停止維護(hù)組件庫請(qǐng)移步小程序組件庫請(qǐng)移步有贊前端大量坑位,內(nèi)推私信基于的移動(dòng)端組件支持單列多列和聯(lián)級(jí)數(shù)據(jù)內(nèi)置時(shí)間日期數(shù)據(jù)滾輪效果顏色可配置已啟用試試離線訪問吧點(diǎn)擊查看詳細(xì)使用方法參照源碼參數(shù)描述可選類型默認(rèn)詳細(xì)描述 ?? DEPRECATED 本組件停止維護(hù) ?? Vue 組件庫請(qǐng)移步 Vant ?? 小程序組件庫請(qǐng)移步 Vant Weapp ?? 有贊前端大量坑位,內(nèi)推私信 v...

    Lsnsh 評(píng)論0 收藏0
  • UI組件庫從1到N開發(fā)心得-組件

    摘要:正文距離第一篇組件庫文章發(fā)布已經(jīng)過去個(gè)月了,在此期間利用零零散散的時(shí)間持續(xù)更新組件庫,目前移動(dòng)端組件庫已經(jīng)更新大類基礎(chǔ)表單彈出層種組件供使用。鏈接組件庫從到開發(fā)心得主頁更改版版方案祝工作順利鄧文斌年月日正文 距離第一篇UI組件庫文章發(fā)布已經(jīng)過去3個(gè)月了,在此期間利用零零散散的時(shí)間持續(xù)更新owl-ui組件庫,目前owl-ui移動(dòng)端組件庫已經(jīng)更新3大類(基礎(chǔ)、表單、彈出層)9種組件(Button...

    hzc 評(píng)論0 收藏0
  • 基于zepto的移動(dòng)輕量級(jí)日期插件

    摘要:本文簡單介紹近來寫的一款基于的移動(dòng)端輕量級(jí)日期插件。再來看看兼容性對(duì)于移動(dòng)開發(fā)足矣最后就是在綁定事件的兼容性問題,不同廠商對(duì)于這個(gè)事件的定義并不一致,比如里面監(jiān)聽的是事件,但是在安卓里面監(jiān)聽事件完全沒反應(yīng),經(jīng)過一番,發(fā)現(xiàn)安卓需要監(jiān)聽事件。 前言 做過移動(dòng)Web開發(fā)的同學(xué)都知道,移動(dòng)端日期選擇是很常見的需求。在PC端,我們有很豐富的選擇,比較出名的就有Mobiscroll和jQuery ...

    ranwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<