この記事では主に vue.js 2.x に基づく仮想スクロール バーのサンプル コードを紹介します。
前書き
以前、偶然オープンソースの cms プロジェクトを閲覧していて、プロジェクトの左側のメニューがウィンドウの幅を超えていることに気づきました。なぜスクロール バーがないのか疑問に思いました。そこでよく見てみると、その左側に小さな p があったので、それをドラッグしてみると、ネイティブのスクロール バーと同じであることがわかりました。ソースコードを見ると、このスクロールバーはslimScrollという名前であることがわかり、githubリポジトリにアクセスしてソースコードを調べたところ、同じスクロールバーを作成することができると感じました。 vueで実現!
デザイン
それでは、スクロール バーのデザイン手順を始めましょう:
スクロール バーの dom をデザインします
最初に考えるべきことは次のとおりです: コンテンツを作成したい場合は、スクロールする必要があります。スクロール、最初のことはそれです。親 dom は固定の長さと幅を持つ必要があります。つまり、余分な部分は非表示にする必要があります。つまり、スタイルが追加されます。したがって、コンテンツにラッパーを追加します。長さと幅が親 dom と等しくなるようにスクロールされると、スタイルが 1 つ呼び出されます: overflow: hidden、ラップされた要素はscrollPanel と呼ばれます
2 番目: と同じくらい強力である必要があることがわかっています。ネイティブスクロールバー!スクロール バーと垂直スクロール バーは、兄弟ノード間の関係に属しているため、スクロール バーの存在により元のスタイルのレイアウトが崩れることはなく、その位置を制御するために上と左をサポートするように設計する必要があります。なので、スクロール バーの位置は絶対値でなければなりません。水平スクロール バーを hBar、垂直スクロール バーを vBar と呼びましょう
最後に、scrollPanel、vBar、hBar を設計しました。これらをラップするには親 p が必要です。そして Style:position:relative を追加します
練習
デザインコンポーネント構造
まず第一に、私たちのプラグインには合計 4 つのコンポーネントがあり、そのうち 3 つは子コンポーネント、1 つは親コンポーネントです。すなわち: vueScroll (親コンポーネント)、scrollPanel (スクロールする必要があるコンテンツをラップするサブコンポーネント)、vBar (垂直スクロール バー)、hBar (水平スクロール バー)
次に、各コンポーネントが担当する関数を設計しましょう。ここでのコンポーネントは、コントロール層コンポーネントとディスプレイ コンポーネントに分かれています (反応に慣れている学生はこれを知っているはずです)。ディスプレイ層コンポーネントは、vBar、hBar、scrollPanel などの表示機能を完了するだけです。コントロール層コンポーネントは CPU に似ており、制御できます。幅、高さ、色、透明度、位置などのさまざまな状態のサブコンポーネント。コントロール層コンポーネントは vueScroll です。
具体的な実装
hBar/vBar
hBar/vBar これら 2 つはそれぞれ水平スクロール バーと垂直スクロール バーであり、実装する機能はほぼ同じであるため、ここでは vBar としてまとめて説明します。例。
props は、親コンポーネントによって渡されたプロパティ、具体的には、マウスの移動時に主にスクロール バーを表示する
{ 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 イベントを受け取ります。
... render(_c){ return _c( // ... { mouseenter: function(e) { vm.$emit('showVBar'); // 触发父组件事件,显示滚动条 } } // ... ) }
このうち、state は実行時に変更できる状態を表し、ops はユーザーによって渡される構成パラメーターです。
scrollPanel
は、スクロールコンテンツをラップするコンポーネントです: overflow: hidden に設定する必要があります。
1. スタイル
var style = vm.scrollContentStyle; style.overflow = 'hidden'; // ... { style: style } // ...
2. イベント
// ... render(_c) { // ... on: { mouseenter: function() { vm.$emit('showBar'); }, mouseleave: function() { vm.$emit('hideBar'); } } // ... } // ...
vescroll
コントロールコンポーネント。サブコンポーネントによって表示されるステータスを制御したり、さまざまなリスニング イベントを追加したりできます。
1. サブコンポーネントの dom 要素を取得して、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. スクロール バーを表示します。水平スクロール バーの表示と垂直スクロール バーの表示を含みます。
// ... 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.スクロールバー
dom要素のため高さは固定されていないため、リアルタイムでdomの実際の高さを取得する必要があります。 スクロールバーの高さの計算式は次のとおりです:
var height = Math.max( scrollPanelHeight / (scrollPanelScrollHeight / scrollPanelHeight), this.vScrollBar.minBarHeight );
つまり:スクロール バーの高さ: スクロール パネルの高さ == スクロール パネルの高さ: dom 要素の高さ
4. エラーを防ぐために、親からスクロール バーの高さを見つけることができるように、resizeVBarTop を実行します。要素。
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. ホイール スクロール イベントを監視します。
// ... on: { wheel: vm.wheel } // ... wheel(e) { var vm = this; vm.showVBar(); vm.scrollVBar(e.deltaY > 0 ? 1 : -1, 1); e.stopPropagation(); } // ...
6. スクロール バーのドラッグ イベントを監視します
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. モバイル端末に適応し、タッチ イベントをリッスンします。原理はドラッグ イベントの原理と似ていますが、現在の方向が x であるか 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. コンテンツをスクロールする
コンテンツをスクロールする原理は、scrollPanel のscrollTop/scrollLeftを変更して、コンテンツが上下左右に移動するように制御することに他なりません。
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. 登録されたイベントを破棄します。
今、登録されたイベントをリスナー配列に入れました。そして、それらを beforedestroy フックで破棄できます。
// remove the registryed event. this.listeners.forEach(function(item) { item.dom.removeEventListener(item.event, item.type); });
実行中のスクリーンショット
PC側の実行中のスクリーンショットは以下の通りです:
リスニングイベントの登録後は以下のようになります:
携帯電話での実行中のスクリーンショット:
パフォーマンス効果がネイティブ スクロール バーと一致していることがわかります。
結論と感想
上記は基本的に私がデザインしたスクロールバーのデザインです。 まず第一に、私にこのような共有プラットフォームを提供してくれたナゲッツに感謝し、それから作者に感謝したいと思います。このようなアイデアを与えてくれたslimScroll。このプラグインを完成させた後、DOM 要素のscrollWidth、scrollHeigh、scrollTop、scrollLeft について詳しく知ることができました。これが将来皆さんに役立つことを願っています。
関連記事:
vue ルートパラメータの受け渡しの 3 つの基本モード (詳細なチュートリアル) JavaScript の関連トリック webpack でファイルを動的にインポートする実装以上がvue.js の仮想スクロール バー約 2.xの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

WebStorm Mac版
便利なJavaScript開発ツール

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

ホットトピック









