Maison > Article > interface Web > Barres de défilement virtuelles sur 2.x dans vue.js
Cet article présente principalement l'exemple de code de barre de défilement virtuelle basé sur vue.js 2.x. Maintenant, je le partage avec vous et le donne comme référence.
Avant-propos
Je me souviens avoir parcouru par hasard un projet cms open source et avoir découvert que le menu de gauche de ce projet dépassait la largeur des fenêtres. J'étais curieux de savoir pourquoi. il n'y a pas de barre de défilement ? Ensuite, j'ai regardé de plus près et j'ai trouvé un petit p sur le côté gauche. Ensuite, j'ai essayé de le faire glisser et j'ai découvert que c'était la même que la barre de défilement native ! En regardant son code source, j'ai découvert que cette barre de défilement s'appelle slimScroll. Ensuite, je suis allé sur son référentiel github et je l'ai regardé. Après avoir étudié le code source, j'ai senti que je pouvais aussi faire la même barre de défilement ! Réalisé grâce à vue !
Conception
D'accord, nous commençons maintenant les étapes de conception de la barre de défilement :
Concevoir la barre de défilement dom
La première chose à penser est la suivante : si vous souhaitez faire défiler le contenu que vous devez faire défiler, la première chose est que son domaine parent doit avoir une longueur et une largeur fixes, c'est-à-dire que la partie excédentaire doit être masquée, c'est-à-dire, ajoutez un style : overflow : caché, Par conséquent, nous ajoutons un wrapper au contenu à faire défiler afin que sa longueur et sa largeur soient égales au dom parent, puis il y a un style appelé : overflow : caché, et le L'élément enveloppé s'appelle scrollPanel
Deuxièmement : nous le savons, nous voulons le rendre aussi puissant que la barre de défilement native ! Il est nécessaire de concevoir des barres de défilement horizontales et des barres de défilement verticales. La barre de défilement et scrollPanel appartiennent à la relation entre les nœuds frères, car l'existence de la barre de défilement ne peut pas provoquer d'erreur de mise en page de style d'origine et prend en charge le haut et la gauche pour contrôler sa position. , donc la barre de défilement La position doit être absolue. Eh bien, nous appelons la barre de défilement horizontale : hBar, et la barre de défilement verticale : vBar
Enfin : nous avons conçu scrollPanel, vBar, hBar, et nous avons besoin d'un parent. p pour les envelopper, puis ajoutez un style : position : relative
Pratique
Structure des composants de conception
Premier de au total, nos plug-ins sont constitués de 4 composants, dont 3 sont des composants enfants et 1 est un composant parent, à savoir : vueScroll (composant parent), scrollPanel (sous-composant qui encapsule le contenu qui doit défiler), vBar (barre de défilement verticale) , hBar (barre de défilement horizontale)
Deuxièmement, concevons les fonctions dont chaque composant est responsable. Les composants ici sont divisés en composants de couche de contrôle et composants d'affichage (les étudiants familiers avec React devraient le savoir). Les composants de couche d'affichage ne complètent que la fonction d'affichage : vBar, hBar, scrollPanel. Les composants de couche de contrôle sont quelque peu similaires au CPU et peuvent contrôler. sous-composants. Différents états, tels que la largeur, la hauteur, la couleur, la transparence, la position, etc. Le composant de la couche de contrôle est : vueScroll.
Mise en œuvre spécifique
hBar/vBar
hBar/vBar Ces deux barres sont respectivement une barre de défilement horizontale et une barre de défilement verticale, les fonctions implémentées sont à peu près les mêmes, donc les anciennes sont mentionnées ensemble ici, nous prenons vBar comme exemple.
props reçoit les propriétés transmises par le composant parent, à savoir :
{ height: vm.state.height + 'px', //滚动条的高度 width: vm.ops.width, // 滚动条的宽度 position: 'absolute', background: vm.ops.background, // 滚动条背景色 top: vm.state.top + 'px', // 滚动条的高度 transition: 'opacity .5s', // 消失/显示 所用的时间 cursor: 'pointer', // opacity: vm.state.opacity, // 透明度 userSelect: 'none' }
2 événements, principalement pour afficher la barre de défilement lorsque la souris bouge.
... render(_c){ return _c( // ... { mouseenter: function(e) { vm.$emit('showVBar'); // 触发父组件事件,显示滚动条 } } // ... ) }
Parmi eux, state représente l'état, qui peut être modifié au moment de l'exécution, et ops est le paramètre de configuration, qui est transmis par l'utilisateur.
scrollPanel
est un composant qui encapsule le contenu défilant. Le style doit être défini sur : overflow : masqué.
1. Style
var style = vm.scrollContentStyle; style.overflow = 'hidden'; // ... { style: style } // ...
2. Composant de contrôle d'événement
// ... render(_c) { // ... on: { mouseenter: function() { vm.$emit('showBar'); }, mouseleave: function() { vm.$emit('hideBar'); } } // ... } // ...
vuescroll
. Contrôlez l'état affiché par les sous-composants, ajoutez divers événements d'écoute, etc.
1. Obtenez l'élément dom du sous-composant pour obtenir des informations en temps réel sur le dom.
// ... initEl() { this.scrollPanel.el = this.$refs['vueScrollPanel'] && this.$refs['vueScrollPanel'].$el; this.vScrollBar.el = this.$refs['vScrollBar'] && this.$refs['vScrollBar'].$el; this.hScrollBar.el = this.$refs['hScrollBar'] && this.$refs['hScrollBar'].$el; } // ...
2. Afficher les barres de défilement
Afficher les barres de défilement, y compris l'affichage des barres de défilement horizontales et l'affichage des barres de défilement verticales :
// ... var temp; var deltaY = { deltaY: this.vScrollBar.ops.deltaY // 获取用户配置的deltaY }; if(!this.isMouseLeavePanel || this.vScrollBar.ops.keepShow){ if ((this.vScrollBar.state.height = temp = this.getVBarHeight(deltaY))) { // 判断条件 // 重新设置滚动条的状态 this.vScrollBar.state.top = this.resizeVBarTop(temp); this.vScrollBar.state.height = temp.height; this.vScrollBar.state.opacity = this.vScrollBar.ops.opacity; } } // ...3. Obtenez la hauteur de la barre de défilement La hauteur de l'élément dom n'étant pas fixe, vous devez obtenir la hauteur réelle du dom en temps réel. de la barre de défilement est la suivante :
var height = Math.max( scrollPanelHeight / (scrollPanelScrollHeight / scrollPanelHeight), this.vScrollBar.minBarHeight );C'est-à-dire : la hauteur de la barre de défilement : la hauteur du scrollPanel == la hauteur du scrollPanel : la hauteur de l'élément dom 4. resizeVBarTop, afin d'éviter les erreurs, et la hauteur de la barre de défilement à partir de l'élément parent peut être trouvée.
resizeVBarTop({height, scrollPanelHeight, scrollPanelScrollHeight, deltaY}) { // cacl the last height first var lastHeight = scrollPanelScrollHeight - scrollPanelHeight - this.scrollPanel.el.scrollTop; if(lastHeight < this.accuracy) { lastHeight = 0; } var time = Math.abs(Math.ceil(lastHeight / deltaY)); var top = scrollPanelHeight - (height + (time * this.vScrollBar.innerDeltaY)); return top; }5. Surveiller les événements de défilement de la roue.
// ... on: { wheel: vm.wheel } // ... wheel(e) { var vm = this; vm.showVBar(); vm.scrollVBar(e.deltaY > 0 ? 1 : -1, 1); e.stopPropagation(); } // ...6. Surveillez les événements de glissement de la barre de défilement
listenVBarDrag: function() { var vm = this; var y; var _y; function move(e) { _y = e.pageY; var _delta = _y - y; vm.scrollVBar(_delta > 0 ? 1 : -1, Math.abs(_delta / vm.vScrollBar.innerDeltaY)); y = _y; } function t(e) { var deltaY = { deltaY: vm.vScrollBar.ops.deltaY }; if(!vm.getVBarHeight(deltaY)) { return; } vm.mousedown = true; y = e.pageY; // 记录初始的Y的位置 vm.showVBar(); document.addEventListener('mousemove', move); document.addEventListener('mouseup', function(e) { vm.mousedown = false; vm.hideVBar(); document.removeEventListener('mousemove', move); }); } this.listeners.push({ dom: vm.vScrollBar.el, event: t, type: "mousedown" }); vm.vScrollBar.el.addEventListener('mousedown', t); // 把事件放到数组里面,等销毁之前移除掉注册的时间。 }7. Adaptez-vous aux terminaux mobiles et écoutez les événements tactiles. Le principe est similaire à celui des événements de traînée, sauf qu'il existe un jugement supplémentaire pour déterminer si la direction actuelle est x ou y.
listenPanelTouch: function() { var vm = this; var pannel = this.scrollPanel.el; var x, y; var _x, _y; function move(e) { if(e.touches.length) { var touch = e.touches[0]; _x = touch.pageX; _y = touch.pageY; var _delta = void 0; var _deltaX = _x - x; var _deltaY = _y - y; if(Math.abs(_deltaX) > Math.abs(_deltaY)) { _delta = _deltaX; vm.scrollHBar(_delta > 0 ? -1 : 1, Math.abs(_delta / vm.hScrollBar.innerDeltaX)); } else if(Math.abs(_deltaX) < Math.abs(_deltaY)){ _delta = _deltaY; vm.scrollVBar(_delta > 0 ? -1 : 1, Math.abs(_delta / vm.vScrollBar.innerDeltaY)); } x = _x; y = _y; } } function t(e) { var deltaY = { deltaY: vm.vScrollBar.ops.deltaY }; var deltaX = { deltaX: vm.hScrollBar.ops.deltaX }; if(!vm.getHBarWidth(deltaX) && !vm.getVBarHeight(deltaY)) { return; } if(e.touches.length) { e.stopPropagation(); var touch = e.touches[0]; vm.mousedown = true; x = touch.pageX; y = touch.pageY; vm.showBar(); pannel.addEventListener('touchmove', move); pannel.addEventListener('touchend', function(e) { vm.mousedown = false; vm.hideBar(); pannel.removeEventListener('touchmove', move); }); } } pannel.addEventListener('touchstart', t); this.listeners.push({ dom: pannel, event: t, type: "touchstart" }); }8. Faire défiler le contenu Le principe du défilement du contenu n'est rien de plus que de changer le scrollTop/scrollLeft du scrollPanel pour contrôler le contenu pour se déplacer vers le haut, le bas, la gauche et la droite .
scrollVBar: function(pos, time) { // >0 scroll to down <0 scroll to up var top = this.vScrollBar.state.top; var scrollPanelHeight = getComputed(this.scrollPanel.el, 'height').replace('px', ""); var scrollPanelScrollHeight = this.scrollPanel.el.scrollHeight; var scrollPanelScrollTop = this.scrollPanel.el.scrollTop; var height = this.vScrollBar.state.height; var innerdeltaY = this.vScrollBar.innerDeltaY; var deltaY = this.vScrollBar.ops.deltaY; if (!((pos < 0 && top <= 0) || (scrollPanelHeight <= top + height && pos > 0) || (Math.abs(scrollPanelScrollHeight - scrollPanelHeight) < this.accuracy))) { var Top = top + pos * innerdeltaY * time; var ScrollTop = scrollPanelScrollTop + pos * deltaY * time; if (pos < 0) { // scroll ip this.vScrollBar.state.top = Math.max(0, Top); this.scrollPanel.el.scrollTop = Math.max(0, ScrollTop); } else if (pos > 0) { // scroll down this.vScrollBar.state.top = Math.min(scrollPanelHeight - height, Top); this.scrollPanel.el.scrollTop = Math.min(scrollPanelScrollHeight - scrollPanelHeight, ScrollTop); } } // 这些是传递给父组件的监听滚动的函数的。 var content = {}; var bar = {}; var process = ""; content.residual = (scrollPanelScrollHeight - scrollPanelScrollTop - scrollPanelHeight); content.scrolled = scrollPanelScrollTop; bar.scrolled = this.vScrollBar.state.top; bar.residual = (scrollPanelHeight - this.vScrollBar.state.top - this.vScrollBar.state.height); bar.height = this.vScrollBar.state.height; process = bar.scrolled/(scrollPanelHeight - bar.height); bar.name = "vBar"; content.name = "content"; this.$emit('vscroll', bar, content, process); },9. Détruisez les événements enregistrés. Nous venons tout juste de mettre les événements enregistrés dans le tableau des auditeurs, et nous pouvons les détruire dans le hook beforedestroy.
// remove the registryed event. this.listeners.forEach(function(item) { item.dom.removeEventListener(item.event, item.type); });Capture d'écran de l'opérationLa capture d'écran de l'opération côté PC est la suivante : Après avoir enregistré l'événement d'écoute, il est comme indiqué ci-dessous : Exécutez la capture d'écran sur votre téléphone :
On peut voir que l'effet de performance est cohérent avec la barre de défilement native.
Conclusion et réflexion
Ce qui précède est essentiellement le design de la barre de défilement que j'ai conçue. Tout d'abord, je suis très reconnaissant aux Nuggets de m'avoir offert un tel. plateforme de partage, et ensuite je voudrais remercier slimScroll L'auteur m'a donné une telle idée. Après avoir terminé ce plug-in, j'en sais plus sur les éléments scrollWidth, scrollHeigh, scrollTop et scrollLeft du DOM
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 :
3 modes de base des paramètres de routage de vue (tutoriel détaillé)
Astuces associées en JavaScript
Implémenter l'importation dynamique de fichiers dans webpack
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!