概要より多くの方法を理解し、比較できるようにするために、ドラッグを実装するために 3 つの異なる方法を使用します。
ドラッグアンドドロップの実装プロセスには、多くの実用的な知識が含まれます。そのため、私自身の知識の蓄積を強化し、皆さんにさらに多くの知識を学んでもらうために、いくつかの詳細を詳しく共有したいと思います。注意深く読めば、必ず何かを学べると信じています。 1. DOM要素をアニメーション化する方法多くの場合、要素の top、left、translate を変更して要素の位置を変更します。以下の例では、ボタンがクリックされるたびに、対応する要素が 5 ピクセル移動します。ここをクリックしてご覧ください。 クリックすると、要素をアニメーション化する小さな例が表示されます。
2. 現在のブラウザでサポートされている変換互換の書き込み方法を取得する方法Transform は CSS3 属性であり、これを使用する場合は互換性の問題に直面します。異なるブラウザの互換性のあるバージョンを記述する方法は、おおよそ次のとおりです。 ['transform'、'webkitTransform'、'MozTransform'、'msTransform'、'OTransform'] したがって、現在のブラウザ環境でどの変換属性がサポートされているかを判断する必要があります。方法は次のとおりです。 // 現在のブラウザでサポートされている変換互換の書き込みメソッドを取得する関数 getTransform() { var 変換 = ''、 divStyle = document.createElement('div').style, // 互換性のある書き込み方法が複数ある場合があり、ブラウザが認識するものはループを通じて見つけられます。 transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i++) { if (transformArr[i] が divStyle にある) { // 見つけたらすぐに戻り、関数を終了します。 return transform = transformArr[i]; } } // 見つからない場合は、空の文字列を返します。 return transform; } このメソッドは、ブラウザでサポートされている変換プロパティを取得するために使用されます。空の文字列が返された場合は、現在のブラウザが transform をサポートしていないことを意味します。このとき、要素の位置を変更するには、left と top の値を使用する必要があります。サポートされている場合は、transform の値を変更します。 3. 要素の初期位置を取得する方法まず、ターゲット要素の初期位置を取得する必要があるため、ここでは要素のスタイルを取得するために特別に使用される関数が必要です。 ただし、IE で要素スタイルを取得する方法は他のブラウザとは少し異なるため、互換性のある記述方法が必要です。 関数 getStyle(要素, プロパティ) { // つまり、要素のスタイルを取得するために currentStyle を使用し、他のブラウザは getComputedStyle を使用して取得します。 return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property]; } このメソッドを使用すると、ターゲット要素の初期位置を取得するメソッドの記述を開始できます。 関数 getTargetPos(要素) { var pos = {x: 0, y: 0}; var transform = getTransform(); if(変換) { var transformValue = getStyle(elem, transform); if(変換値 == 'なし') { elem.style[transform] = 'translate(0, 0)'; 位置を返します。 } それ以外 { var temp = transformValue.match(/-?\d+/g); 戻り値 pos = { x: parseInt(temp[4].trim())、 y: parseInt(temp[5].trim()) } } } それ以外 { if(getStyle(elem, 'position') == 'static') { elem.style.position = '相対'; 位置を返します。 } それ以外 { var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0); var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0); 戻り値 pos = { x: x, y: y } } } } ドラッグ処理中は、ターゲット要素が移動できるようにその新しい位置を常に設定する必要があるため、ターゲット要素の位置を設定するメソッドが必要です。 // 位置 = { x: 200, y: 100 } 関数setTargetPos(要素, pos) { var transform = getTransform(); if(変換) { elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px)'; } それ以外 { elem.style.left = pos.x + 'px'; elem.style.top = pos.y + 'px'; } 要素を返します。 } 5. どのようなイベントを使用する必要がありますか?PC のブラウザでは、mousedown、mousemove、mouseup の 3 つのイベントを組み合わせることでドラッグを実現できます。
これらのイベントを要素にバインドすると、イベント オブジェクトがパラメーターとしてコールバック関数に渡されます。イベント オブジェクトを通じて、現在のマウスの正確な位置を取得できます。マウスの位置情報こそが、ドラッグを実現するための鍵となります。
6. ドラッグの原理イベントがトリガーされると、イベント オブジェクトを通じてマウスの正確な位置を取得できます。これが抗力を実現するための鍵です。マウスが押されたとき (mousedown トリガー)、マウスの初期位置とターゲット要素の初期位置を記憶する必要があります。目標は、マウスが動くとターゲット要素も動くようにすることです。常識的に考えると、次の関係を導き出すことができます。
マウスの位置の差が dis で表される場合、ターゲット要素の位置は次のようになります。
イベント オブジェクトを通じて、マウスの現在の位置を正確に知ることができるため、マウスをドラッグすると (mousemove)、マウスの移動の差を継続的に計算して、ターゲット要素の現在の位置を見つけることができます。このプロセスによりドラッグが実現されます。 マウスを離して(マウスアップして)ドラッグを終了するときは、仕上げ作業を行う必要があります。詳細についてはコードを参照してください。 7. コーディングを支援するためにマインドマッピングをお勧めします。新しい友達から、論理的思考力が強くなくてもコードを書いたりフロントエンドの仕事をしたりできるかどうかよく聞かれます。私の答えは「はい」です。マインドマッピングの助けを借りれば、論理の欠点を簡単に補うことができるからです。また、頭の中でロジックを理解しようとするよりも明確で、エラーも起こりにくくなります。 上記の 6 番目のポイントで原則を紹介したので、実行するのはそれほど難しくありません。具体的な手順は、以下のマインド マップに明確に示されています。これらの手順に従ってコードを記述するだけです。試してみてください。簡単なはずです。 マインドマップを使用して、ドラッグプロセス全体で何をする必要があるかを明確に表現します。 8. コードの実装パート1.準備// ターゲット要素オブジェクトを取得します。 var oElem = document.getElementById('target'); // マウスの初期位置の x 座標と y 座標を保存するための 2 つの変数を宣言します。var startX = 0; var 開始Y = 0; // ターゲット要素の初期位置の x 座標と y 座標を保存するための 2 つの変数を宣言します。var sourceX = 0; var ソースY = 0; パート2、機能すでにコードを投稿しているので、繰り返すつもりはありません。 // 現在のブラウザでサポートされている変換互換の書き込みメソッドを取得する関数 getTransform() {} // 要素のプロパティを取得する function getStyle(elem, property) {} // 要素の初期位置を取得する function getTargetPos(elem) {} // 要素の初期位置を設定する function setTargetPos(elem, potions) {} パート3. 3つのイベントのコールバック関数を宣言するこれら 3 つの方法は、ドラッグ アンド ドロップを実現するための核心です。上記のマインド マップの手順に厳密に従って、コードを完成させます。 //マウスダウン時のコールバックにバインドされ、eventは受信イベントオブジェクトです。function start(event) { // マウスの初期位置を取得します。startX = event.pageX; イベントページY // 要素の初期位置を取得します。var pos = getTargetPos(oElem); ソースX = pos.x; ソースY = pos.y; // バインディング document.addEventListener('mousemove', move, false); document.addEventListener('mouseup', end, false); } 関数move(イベント) { // マウスの現在の位置を取得します。var currentX = event.pageX; var currentY = イベント.pageY; // 差を計算します var distanceX = currentX - startX; var 距離Y = 現在のY - 開始Y; // 要素の現在の位置を計算して設定する setTargetPos(oElem, { x: (sourceX + distanceX).toFixed(), y: (ソースY + 距離Y).toFixed() }) } 関数終了(イベント) { document.removeEventListener('mousemove', 移動); document.removeEventListener('mouseup', 終了); // 他のことを行う } はい、簡単なドラッグ アンド ドロップで問題なく実現できます。この例のデモをオンラインで表示するには、以下のリンクをクリックしてください。 ドラッグアンドドロップを実装するにはネイティブjsを使用する 9. ドラッグオブジェクトをカプセル化する上記で実装したドラッグをドラッグ オブジェクトにカプセル化してみましょう。私たちの目標は、ドラッグ インスタンスを宣言する限り、渡されたターゲット要素が自動的にドラッグできるようになることです。 実際の開発では、オブジェクトを別の js ファイルに配置することがよくあります。この js ファイルは別のモジュールとして使用され、さまざまなモジュールの方法で整理されて使用されます。もちろん、この例では 1 つのモジュールのみが必要なので、ここでは複雑なモジュールの相互作用はありません。 変数汚染を避けるために、関数の自己実行をシミュレートするブロックレベルのスコープ内にモジュールを配置する必要があります。 (関数() { ... })();
オブジェクトをカプセル化するときに、プロパティとメソッドをコンストラクターまたはプロトタイプに配置できること、そして自己実行関数を追加した後で、プロパティとメソッドがモジュールの内部スコープ内に入らないようにできることがわかっています。これはクロージャに関する知識です。 私たちが直面している課題は、属性とメソッドの場所を適切に処理する方法です。 もちろん、それぞれの物体の状況は異なり、一般化することはできません。最も適切な決定を下すためには、これら 3 つの位置の特徴を明確に把握する必要があります。
方法を判断するのは比較的簡単です。 新しいインスタンスが宣言されるたびにコンストラクター内のメソッドが常に繰り返し作成されるため、コンストラクター内でメソッドを宣言することは避けるようにします。 メソッドがコンストラクター内の変数を使用する必要がある場合、またはそれらをパブリックにしたい場合は、それらをプロトタイプに配置する必要があります。 メソッドをプライベートにして外部からアクセスできないようにする必要がある場合は、モジュール スコープに配置します。 属性をどこに配置するかを正しく判断することが難しい場合があり、どの属性をどの位置に配置する必要があるかを正確に定義することは困難です。これには、実際の開発での継続的な経験の要約が必要です。しかし、一般的には、最も適切な判断を下すには、これら 3 つの立場の特性を組み合わせる必要があります。 属性値がインスタンスのみによって所有される場合 (特定の人物インスタンスにのみ属することができる人物オブジェクトの名前など)、またはここでドラッグされたオブジェクト内の要素の初期位置が要素の現在の位置のみである場合、この属性はコンストラクターに配置するのが適切です。 属性が内部メソッドからのみアクセス可能な場合は、モジュール スコープに配置するのが適切です。
これらの考えに基づいて、自分でそれをカプセル化してみることができます。次に、私の考えと比較して、私たちの考えがどのように異なるかを確認します。以下の例のコメントで私の考えを述べます。 パッケージ化されたデモを見るにはクリックしてください js ソースコード (関数() { // これはプライベート プロパティであり、インスタンスによってアクセスする必要はありません var transform = getTransform(); 関数ドラッグ(セレクタ) { // コンストラクター内に配置されたプロパティは、各インスタンスに個別に属します。 this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector); this.startX = 0; this.startY = 0; this.sourceX = 0; this.sourceY = 0; これを初期化します。 } // プロトタイプ Drag.prototype = { コンストラクタ: ドラッグ、 初期化: 関数() { // 最初に行う必要があること this.setDrag(); }, // 若干変更されていますが、getName と同様に、現在の要素の属性を取得するためにのみ使用されます。 getStyle: 関数(プロパティ) { document.defaultView.getComputedStyle を返します? document.defaultView.getComputedStyle(this.elem, false)[プロパティ] : this.elem.currentStyle[プロパティ]; }, // 現在の要素の位置情報を取得するために使用します。前の getPosition: function() との違いに注意してください。 var pos = {x: 0, y: 0}; if(変換) { var transformValue = this.getStyle(transform); if(変換値 == 'なし') { this.elem.style[transform] = 'translate(0, 0)'; } それ以外 { var temp = transformValue.match(/-?\d+/g); 位置 = { x: parseInt(temp[4].trim())、 y: parseInt(temp[5].trim()) } } } それ以外 { if(this.getStyle('position') == 'static') { this.elem.style.position = '相対'; } それ以外 { 位置 = { x: parseInt(this.getStyle('left') ? this.getStyle('left') : 0), y: parseInt(this.getStyle('top') ? this.getStyle('top') : 0) } } } 位置を返します。 }, // 現在の要素の位置を設定するために使用します setPosition: function(pos) { if(変換) { this.elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px)'; } それ以外 { this.elem.style.left = pos.x + 'px'; this.elem.style.top = pos.y + 'px'; } }, // このメソッドはイベントをバインドするために使用されます setDrag: function() { var self = this; this.elem.addEventListener('mousedown', 開始, false); 関数開始(イベント) { イベントページを生成 イベントページYをself.startYに代入します。 var pos = self.getPosition(); 自己ソースX = pos.x; 自己のソースY = pos.y; document.addEventListener('mousemove', 移動, false); document.addEventListener('mouseup', end, false); } 関数move(イベント) { var currentX = イベント.pageX; var currentY = イベント.pageY; var 距離X = 現在のX - 自己開始X; var 距離Y = 現在のY - 自己開始Y; 自己.setPosition({ x: (self.sourceX + distanceX).toFixed(), y: (self.sourceY + distanceY).toFixed() }) } 関数終了(イベント) { document.removeEventListener('mousemove', 移動); document.removeEventListener('mouseup', 終了); // 他のことを行う } } } // プライベートメソッド。変換関数の互換性のある書き込みメソッドを取得するためにのみ使用されます。getTransform() { var 変換 = ''、 divStyle = document.createElement('div').style, transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i++) { if (transformArr[i] が divStyle にある) { 戻り値: transform = transformArr[i]; } } 変換を返します。 } // 外の世界に公開する方法 window.Drag = Drag; })(); // 使用法: 2 つのドラッグ インスタンスを宣言します。new Drag('target'); 新しいドラッグ('target2'); このようなドラッグ オブジェクトはカプセル化されます。 私が提示した考え方に基づいて、より多くのコンポーネントをカプセル化してみることをお勧めします。たとえば、ポップアップ ウィンドウをカプセル化したり、ループ カルーセルをカプセル化したりします。さらに練習すれば、オブジェクト指向は問題ではなくなります。この考え方は将来いつでも使えます。 上記は、JavaScript オブジェクト指向のカプセル化とドラッグ オブジェクトの実際の応用に関する詳細な説明です。JS オブジェクト指向でカプセル化とドラッグ オブジェクトを実装する方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Ubuntu 18.04 は mysql 5.7.23 をインストールします
>>: Linux における nohup と & の使い方と違いの詳細な説明
目次1. トランジションとアニメーションの違い2. Vueを使用して基本的なCSSトランジションとア...
私はApacheを使ったことがありません。仕事を始めてからはずっとnginxを使っていました(運用保...
ドラッグ機能は主に、ドラッグによる並べ替え、ポップアップ ボックスのドラッグと移動など、ユーザーがカ...
次の図に示すように: 仮想マシンと Docker を使用するとき、「なぜ Docker は VM よ...
この記事では、Linuxサーバー上でDockerを使用してNexusプライベートサーバーを構築する方...
目次序文始めるちょっとした考えコードの実装真似する実装トラックトリガーの実装観察の実装計算の実装序文...
1.1 バイナリインストールパッケージをダウンロードするhttps://dev.mysql.com/...
以前、UDP を使い始めるために簡単な UDP サーバーとクライアントの例を作成しましたが、実際に使...
HTML部分コードをコピーコードは次のとおりです。 <!DOCTYPE html> &l...
効果画像: 1. はじめに独自のアプレットでこのような機能を実装する必要がある1. 核となる考え方ス...
テスト環境: C:\>systeminfo | findstr /c:"OS 名&q...
JSON データを美しいインデント形式で表示するには、最も単純な JSON.stringify 関...
画像タグ <IMG> を挿入します。今日私たちが目にするカラフルなウェブページはすべて、...
ナビゲーションバーのサブメニューを再帰的に生成すると、メニューは正常に生成できるが、マウスをホバーす...
序文この記事では、Windows で Mysql をバックアップするための簡単な BAT スクリプト...