Maison > interface Web > js tutoriel > Comment implémenter l'effet sélecteur dans vue

Comment implémenter l'effet sélecteur dans vue

亚连
Libérer: 2018-06-22 15:38:28
original
4670 Les gens l'ont consulté

Cet article présente principalement l'implémentation Vue de l'effet de sélection natif iOS et l'analyse des idées d'implémentation. Cet article vous présente de manière très détaillée et a une valeur de référence. Les amis dans le besoin peuvent s'y référer

J'étais. le premier à en implémenter un auparavant. Il existe un plug-in de sélection de temps similaire, mais son champ d'application est trop étroit. Je veux simplement publier cette implémentation récemment et réécrire un composant vue hautement réutilisable.

Supporte Android 4.0 ou supérieur, Safari 7 ou supérieur

Aperçu de l'effet

gitHub

Principalement la structure DOM de la partie de la molette de défilement

<template data-filtered="filtered">
 <p class="pd-select-item">
  <p class="pd-select-line"></p>
  <ul class="pd-select-list">
   <li class="pd-select-list-item">1</li>
  </ul>
  <ul class="pd-select-wheel">
   <li class="pd-select-wheel-item">1</li>
  </ul>
 </p>
</template>
props
props: {
   data: {
    type: Array,
    required: true
   },
   type: {
    type: String,
    default: &#39;cycle&#39;
   },
   value: {}
  }
Copier après la connexion

Définissez le style CSS pour la centrer verticalement

.pd-select-line, .pd-select-list, .pd-select-wheel {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}
.pd-select-list {
  overflow: hidden;
}
Copier après la connexion

Paramètres de style 3D de la molette de défilement

/* 滚轮盒子 */
.pd-select-wheel {
  transform-style: preserve-3d;
  height: 30px;
}
/* 滚轮单项 */
.pd-select-wheel-item {
  white-space: nowrap;
  text-overflow: ellipsis;
  backface-visibility: hidden;
  position: absolute;
  top: 0px;
  width: 100%;
  overflow: hidden;
}
Copier après la connexion

Faites principalement attention à 2 attributs : transform-style :preserve-3d ;backface-visibility :hided ;

Le premier est Disposition 3D, rendant l'interface 3D, la seconde consiste à masquer automatiquement l'arrière de la molette de défilement (la partie rouge dans l'image ci-dessus, le nœud DOM au dos sera automatiquement masqué)

Comment implémenter la molette de défilement 3D

La phrase principale de la transformation css de la boîte : rotate3d(1, 0, 0, x deg);

l'élément utilise principalement cette transformation css : rotate3d(1, 0, 0, xdeg) translation3d(0px, 0px, [x]px) ;


Les 2 images ci-dessus montrent Translate3d(0px, 0px, [x]px); ceci L'effet de la phrase [x] est le rayon du cercle

Comme vous pouvez le voir sur l'image ci-dessus, il suffit de faire pivoter chaque dom lui-même, puis d'utiliser translate3d(0px, 0px, [x]px); Développez chaque dom

pour former un anneau α. angle de rotation de chaque dom. Parce que seulement 0 à 180° est utilisé ici, une boîte est utilisée Installer ces dom

Calculer la hauteur et l'angle des rangées

<🎜. >

Calculez la longueur du troisième côté si les deux côtés et l'angle sont connus~=34px

http://tool.520101.com/calculator/sanjiaoxingjiaodu/

Implémentation de la molette de défilement infinie

/* 滚轮展示大小限定 */
spin: {start: 0, end: 9, branch: 9}
 
/* 获取spin 数据 */
 getSpinData (index) {
  index = index % this.listData.length
  return this.listData[index >= 0 ? index : index + this.listData.length]
 }
 /* 模运算 获取数组有的索引 这样就构成 圆环了 */
Copier après la connexion

touchend effectue un traitement spécial

Définissez le type setCSS dans touchend pour arrondir les données de défilement, donc que lorsqu'il s'arrêtera, il fera

une rotation précise d'une image à la fois

// other code ....
/* 计算touchEnd移动的整数距离 */
    let endMove = margin
    let endDeg = Math.round(updateDeg / deg) * deg
    if (type === &#39;end&#39;) {
     this.setListTransform(endMove, margin)
     this.setWheelDeg(endDeg)
    } else {
     this.setListTransform(updateMove, margin)
     this.setWheelDeg(updateDeg)
    }
 // other code ....
惯性缓动
// other code ....
setWheelDeg (updateDeg, type, time = 1000) {
    if (type === &#39;end&#39;) {
     this.$refs.wheel.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)`
     this.$refs.wheel.style.webkitTransform = `rotate3d(1, 0, 0, ${updateDeg}deg)`
    } else {
     this.$refs.wheel.style.webkitTransition = &#39;&#39;
     this.$refs.wheel.style.webkitTransform = `rotate3d(1, 0, 0, ${updateDeg}deg)`
    }
   }
setListTransform (translateY = 0, marginTop = 0, type, time = 1000) {
    if (type === &#39;end&#39;) {
     this.$refs.list.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)`
     this.$refs.list.style.webkitTransform = `translateY(${translateY - this.spin.branch * 34}px)`
     this.$refs.list.style.marginTop = `${-marginTop}px`
     this.$refs.list.setAttribute(&#39;scroll&#39;, translateY)
     console.log(&#39;end&#39;)
    } else {
     this.$refs.list.style.webkitTransition = &#39;&#39;
     this.$refs.list.style.webkitTransform = `translateY(${translateY - this.spin.branch * 34}px)`
     this.$refs.list.style.marginTop = `${-marginTop}px`
     this.$refs.list.setAttribute(&#39;scroll&#39;, translateY)
    }
}
// other code ....
Copier après la connexion

Obtenir la valeur actuellement sélectionnée

/* 在设置完css后获取值 */
setStyle (move, type, time) {
  // ...other code
  /* 设置$emit 延迟 */
  setTimeout(() => this.getPickValue(endMove), 1000)
 // ...other code
}
/* 获取选中值 */
   getPickValue (move) {
    let index = Math.abs(move / 34)
    let pickValue = this.getSpinData(index)
    this.$emit(&#39;input&#39;, pickValue)
   }
Copier après la connexion

Paramètres d'initialisation

mounted () {
   /* 事件绑定 */
   this.$el.addEventListener(&#39;touchstart&#39;, this.itemTouchStart)
   this.$el.addEventListener(&#39;touchmove&#39;, this.itemTouchMove)
   this.$el.addEventListener(&#39;touchend&#39;, this.itemTouchEnd)
   /* 初始化状态 */
   let index = this.listData.indexOf(this.value)
   if (index === -1) {
    console.warn(&#39;当前初始值不存在,请检查后listData范围!!&#39;)
    this.setListTransform()
    this.getPickValue(0)
   } else {
    let move = index * 34
    /* 因为往上滑动所以是负 */
    this.setStyle(-move)
    this.setListTransform(-move, -move)
   }
Copier après la connexion

Lorsqu'il est affiché sous la forme d'une molette de défilement non infinie

Nous pouvons facilement juger ici, c'est-à-dire que la distance de défilement ne peut pas dépasser la longueur du tableau du nombre d'origine * 34 et ne peut pas être inférieure à 0 (la direction impliquée dans le code réel)

/* 根据滚轮类型 line or cycle 判断 updateMove最大距离 */
    if (this.type === &#39;line&#39;) {
     if (updateMove > 0) {
      updateMove = 0
     }
     if (updateMove < -(this.listData.length - 1) * singleHeight) {
      updateMove = -(this.listData.length - 1) * singleHeight
     }
    }
 /* 根据type 控制滚轮显示效果 */
   setHidden (index) {
    if (this.type === &#39;line&#39;) {
     return index < 0 || index > this.listData.length - 1
    } else {
     return false
    }
   },
Copier après la connexion

La structure dom a également ajout des réponses correspondantes

<p class="pd-select-item">
  <p class="pd-select-line"></p>
  <p class="pd-select-list">
   <ul class="pd-select-ul" ref="list">
    <li class="pd-select-list-item" v-for="el,index in renderData " :class="{&#39;hidden&#39;:setHidden(el.index)}" :key="index">{{el.value}}</li>
   </ul>
  </p>
  <ul class="pd-select-wheel" ref="wheel">
   <li class="pd-select-wheel-item" :class="{&#39;hidden&#39;:setHidden(el.index)}" :style="setWheelItemDeg(el.index)" :index="el.index" v-for="el,index in renderData " :key="index">{{el.value}}</li>
  </ul>
 </p>
Copier après la connexion
Ce qui précède est ce que j'ai compilé pour tout le monde. J'espère que cela sera utile à tout le monde à l'avenir.

Articles associés :

Optimisation du module JavaScript

Comment extraire des bibliothèques tierces à l'aide de webpack

Comment déterminer le type de client en utilisant JS

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal