ドラッグ アンド ドロップ効果は、ドラッグ アンド ドロップとも呼ばれ、最も一般的な JS 特殊効果の 1 つです。
多くの詳細を無視すれば、実装は非常に簡単ですが、多くの場合、詳細が困難になります。
このプログラムのプロトタイプは、画像カットエフェクトを作成していたときに作成されました。当時、いくつかの同様のエフェクトを参照し、muxrwc と BlueDestiny から多くのことを学びました。
整理するたびに気分が良くなりますが、時々、私が学んだ知識と同じように、どこかに改善の余地があること、どこかに間違いがあること、特定のニーズを実現する必要があることに気づくことがあります。
単純なドラッグ アンド ドロップのみが必要な方もいるかもしれないことを考慮して、学習を容易にするために、ドラッグ アンド ドロップの SimpleDrag の簡略化されたバージョンがあります。
プログラム原理
ここでは、SimpleDrag を例として基本原理について説明します。
まず、初期化プログラムにはドラッグ アンド ドロップ オブジェクトが必要です:
this.Drag = $(drag);
また、ドラッグ アンド ドロップに対する相対的なマウスの座標を記録する 2 つのパラメータもあります。先頭にオブジェクトをドロップします:
this._x = this. _y = 0;
イベントを追加および削除するための 2 つのイベント オブジェクト関数もあります:
this._fM = BindAsEventListener(this, this.Move); ._fS = Bind(this, this.Stop);
ドラッグ アンド ドロップ オブジェクトの位置は絶対位置である必要があります:
そして、_fM ドラッグ プログラムと _fS stop ドラッグ プログラムをそれぞれバインドします。mousemove イベントと Mouseup イベントをドキュメントにバインドします:
addEventHandler(document, "mousemove", this._fM); 、"mouseup"、this._fS);
ドキュメントにバインドすると、ウィンドウ全体で発生したイベントがドキュメント内で有効であることが保証されます。
ドラッグアンドドロップオブジェクトに設定する必要がある左と上は、マウスの現在の座標値とドラッグ開始時のマウスの相対座標値の差によって取得できます:
this.Drag.style.left = oEvent.clientX - this._x + "px";
this.Drag.style.top = oEvent.clientY - this._y + "px";
最終的にマウスを放した後、Stop プログラムがトリガーされて、ドラッグアンドドロップ。
ここでの主な機能は、スタート プログラムでドキュメントに追加されたイベントを削除することです:
removeEventHandler(document, "mousemove", this._fM);
ドラッグアンドドロップロック
ロックには、水平ロック(LockX)、垂直ロック(LockY)、完全ロック(Lock)の3種類があります。
これは比較的簡単です。移動でロックされているかどうかを判断し、完全にロックされている場合は直接戻るだけです。 if(!this.LockX){ this.Drag.style.left = ...; }if(!this.LockY){ this.Drag.style.top = ... }
トリガー オブジェクトは、ドラッグ アンド ドロップ プログラムをトリガーするために使用されます。場合によっては、ドラッグ アンド ドロップ オブジェクト全体をトリガーに使用する必要はありません。この場合、トリガー オブジェクトが必要になります。
範囲制限を設定するには、まず Limit を true に設定する必要があります。範囲制限には固定範囲制限とコンテナ範囲制限の 2 種類があり、主に Move プログラムで設定します。
コンテナの範囲制限とは、ドラッグ&ドロップで上下左右の範囲を指定することです。
lower (mxBottom): 左限界;
right (mxRight): left+offsetWidth限界。
範囲が正しく設定されていない場合、上下または左右が同時に範囲を超える可能性があります。範囲パラメータを修正するための修復プログラムがプログラム内にあります。
修復プログラムはプログラムの初期化と開始プログラムで実行されます。修復プログラムの mxRight と mxBottom を修正します。 this.mxRight = Math.max(this.mxRight, this.mxLeft + this.Drag.offsetWidth); this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.Drag.offsetHeight); ここで、mxLeft+offsetWidth と mxTop+offsetHeight は、それぞれ mxRight と mxBottom の最小範囲値です。
範囲パラメータに従って移動パラメータを修正します:
iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft);
iTop = Math.max(Math.min(iTop) , mxBottom - this.Drag.offsetHeight), mxTop);
左上側には大きな値を、右下側には小さな値をとります。
容器范围限制
容器范围限制的意思就是把范围限制在一个容器_mxContainer内。
要注意的是拖放对象必须包含在_mxContainer中,因为程序中是使用相对定位来设置容器范围限制的(如果是在容器外就要用绝对定位,这样处理就比较麻烦了),还有就是容器空间要比拖放对象大,这个就不用说明了吧。
原理跟固定范围限制差不多,只是范围参数是根据容器的属性的设置的。
当设置了容器,会自动把position设为relative来相对定位:
!this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative");
注意relative要在获取offsetLeft和offsetTop即设置_x和_y之前设置,offset才能正确获取值。
由于是相对定位,对于容器范围来说范围参数上下左右的值分别是0、clientHeight、0、clientWidth。
clientWidth和clientHeight是容器可视部分的宽度和高度(详细参考这里)。
为了容器范围能兼容固定范围的参数,程序中会获取容器范围和固定范围中范围更小的值:
mxLeft = Math.max(mxLeft, 0);
mxTop = Math.max(mxTop, 0);
mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
注意如果在程序执行之前设置过拖放对象的left和top而容器没有设置relative,在自动设置relative时会发生移位现象,所以程序在初始化时就执行一次Repair程序防止这种情况。因为offsetLeft和offsetTop要在设置relative之前获取才能正确获取值,所以在Start程序中Repair要在设置_x和_y之前执行。
因为设置相对定位的关系,容器_mxContainer设置过后一般不要取消或修改,否则很容易造成移位异常。
鼠标捕获
我在一个拖放实例中看到,即使鼠标移动到浏览器外面,拖放程序依然能够执行,仔细查看后发现是用了setCapture。
鼠标捕获(setCapture)是这个程序的重点,作用是将鼠标事件捕获到当前文档的指定的对象。这个对象会为当前应用程序或整个系统接收所有鼠标事件。
使用很简单:
this._Handle.setCapture();
setCapture捕获以下鼠标事件:onmousedown、onmouseup、onmousemove、onclick、ondblclick、onmouseover和onmouseout。
程序中主要是要捕获onmousemove和onmouseup事件。
msdn的介绍中还说到setCapture有一个bool参数,用来设置在容器内的鼠标事件是否都被容器捕获。
容器就是指调用setCapture的对象,大概意思就是:
参数为true时(默认)容器会捕获容器内所有对象的鼠标事件,即容器内的对象不会触发鼠标事件(跟容器外的对象一样);
参数为false时容器不会捕获容器内对象的鼠标事件,即容器内的对象可以正常地触发事件和取消冒泡。
而对于容器外的鼠标事件无论参数是什么都会被捕获,
可以用下面这个简单的例子测试一下(ie):
<script>document.body.setCapture(); </script>
这里的参数是true,一开始body会捕获所有鼠标事件,即使鼠标经过div也不会触发onmousemove事件。
换成false的话,div就可以捕获鼠标事件,就能触发onmousemove事件了。
拖放结束后还要使用releaseCapture释放鼠标,这个可以放在Stop程序中:
this._Handle.releaseCapture();
setCapture是ie的鼠标捕获方法,对于ff也有对应的captureEvents和releaseEvents方法。
但这两个方法只能由window来调用,而且muxrwc说这两个方法在DOM2里已经废弃了,在ff里已经没用了。
不过ff里貌似会自动设置取消鼠标捕获,但具体的情形就不清楚了,找不到一个比较详细的介绍,谁有这方面的资料记得告诉我啊。
下面都是我的猜测,ff的鼠标捕获相当于能自动设置和释放的document.body.setCapture(false)。
因为我测试下面的程序,发现ie和ff效果是差不多的:
ie:
<script> <br/>document.body.onmousedown=function(){this.setCapture(false)} <br/>document.body.onmouseup=function(){this.releaseCapture()} <br/>document.onmousemove=function(){aa.innerHTML+=1} <br/></script>
ff:
<script> <br/>document.onmousemove=function(){aa.innerHTML+=1} <br/> <br/> <br/>まだ理解できていないことがたくさんあるので、後で勉強します。 <p>ff2 ではマウス キャプチャにバグがあることに注意してください。ドラッグ アンド ドロップ オブジェクトの中にテキスト コンテンツがなく、ブラウザの外にドラッグ アンド ドロップすると、キャプチャは失敗します。 <p> <font size='1px'> などの空のテキストをドラッグ アンド ドロップ オブジェクトに挿入します。これは解決できますが、このバグは ff3 で修正されました。 <br/>フォーカスが失われた<p> 通常の状況では、マウス キャプチャはイベントを正常にキャプチャできますが、ブラウザ ウィンドウのフォーカスが失われた場合、キャプチャは失敗します。 <p>フォーカス損失を引き起こす可能性のある操作には、ウィンドウの切り替え (alt+tab を含む)、アラート、ポップアップ、その他のポップアップ フォームが含まれることを一時的にテストしました。 <br/>フォーカスを失った場合、同時に Stop プログラムを実行してドラッグ アンド ドロップを終了する必要があります。ただし、フォーカスを失った場合は、mouseup イベントをキャプチャできません。つまり、_fS をトリガーできません。 <br/>幸いなことに、IE にはキャプチャが失敗したときにトリガーされる onlosecapture イベントがあり、この状況では次のように設定できます: <br/>addEventHandler(this._Handle, "losecapture", this._fS);<p> そしてそれを削除します。 Stop プログラム内: <p>removeEventHandler(this._Handle, "losecapture", this._fS);<p>ただし、ff には同様のメソッドがありませんが、muxrwc は、losecapture を置き換える window.onblur イベントを見つけて、それを設定できます。 Start プログラム内: <p>addEventHandler(window, "blur", this._fS);<p>Stop プログラム内での削除: <p>removeEventHandler(window, "blur", this._fS);<p>その ie には、 window.onblur イベントを使用する場合は、losecapture の代わりに window.onblur を使用してください。コードを節約できるのではないでしょうか。 <p>その後、いくつかのテストを行ったところ、基本的に、losecapture をトリガーするあらゆる状況が同時に window.onblur をトリガーし、機能するようであることがわかりました。 <br/> そこで、losecapture の代わりに window.onblur を使用するようにプログラムを修正しましたが、テスト後に問題が発生したため、alt+tab を使用して別のウィンドウに切り替えると、ドラッグは続行できますが、この時点でフォーカスが失われるはずであることがわかりました。時間。 <br/>そこで、テスト コードとプログラム コードを 1 つずつ削除したところ、DTD が使用されている場合、再びフォーカスを取得するまで window.onblur がトリガーされないことがわかりました。 <p>次のコードを使用してテストできます: <br/><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/ xhtml1-transitional.dtd"> <p><script>window.onblur=function(){alert(1)} </script>
Window.onblur は、他のプログラムに切り替えてから再び切り替えた後にのみトリガーされます。他にも奇妙な状況がいくつかありますが、いずれにしても、IE で window.onblur を使用するのは理想的ではありません。 デフォルトアクション 選択された状態でテキストコンテンツ、接続、画像をドラッグアンドドロップすると、システムのデフォルトアクションがトリガーされます。たとえば、IEで画像上でマウスをドラッグすると、禁止された操作状態になり、ドラッグが発生します。実行するプログラムの削除は失敗します。 ただし、IEでsetCaptureを設定すると、ユーザーインターフェースを介したマウスによるドラッグアンドドロップ操作やコンテンツの選択が禁止されます。
これは、setCapture の後、ドキュメントのコンテンツをドラッグ アンド ドロップして選択することができないことを意味します。たとえば、ondragstart はシステムのデフォルトのアクションを指します。
ただし、setCapture のパラメータが false の場合でも、コンテナ内のオブジェクトはイベントをトリガーできるため (詳細についてはマウス キャプチャの部分を参照)、setCapture のパラメータを true に設定するか、デフォルト値を維持する必要があります。
たとえば、ctrl+a を使用してコンテンツを選択します。
追記: onkeydown、onkeyup、onkeypress イベントはマウス キャプチャの影響を受けません。
そして、ff はマウスダウン時に元の選択されたコンテンツをクリアできますが、マウスをドラッグして Ctrl+A を押すと引き続きコンテンツが選択されます。
ただし、システムのデフォルトのアクションを破棄した後は、この選択はドラッグ アンド ドロップ操作には影響しません。これは主にエクスペリエンスを向上させるためです。
しかし、この方法では、ドラッグ アンド ドロップ オブジェクト自体が選択されないようにすることしかできません。その後、選択をクリアするより良い方法を見つけました。これは、ドラッグ アンド ドロップ オブジェクトの選択効果に影響を与えないだけでなく、ドキュメント全体もクリアします:
ドラッグ アンド ドロップ処理中にコンテンツが選択されないようにするには、互換性のある記述メソッドを以下に示します:
window.getSelection().removeAllRanges() : document .selection.empty();
margin
ドラッグ アンド ドロップ オブジェクトにマージンが設定されている場合、ドラッグ アンド ドロップ時に位置がずれるという別の状況もあります (SimpleDrag ドラッグ アンド ドロップでマージンを設定することでテストできます)。オブジェクトをドロップします)。
その理由は、Start プログラムが _x と _y を設定するときにオフセットを使用してそれらを取得し、この値にはマージンが含まれるため、left と top を設定する前にこのマージンを減算する必要があるためです。
ただし、Start プログラムでマージンを削除すると、Move プログラムで範囲制限を設定するときに計算エラーが発生します。
そのため、Start プログラムで値を取得するのが最善です:
this._marginLeft = parseInt(CurrentStyle) (this.Drag) .marginLeft) || 0;
this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0;
最終的なスタイルのセクションを参照してください。詳細については。
移動プログラムで値を設定します:
this.Drag.style.left = iLeft - this._marginLeft + "px";
this.Drag.style.top = iTop - this._marginTop + "px";
範囲を修正した後にマージンを設定する必要があることに注意してください。そうしないと、位置がずれてしまいます。
【背景が透明のバグ】
IE には背景が透明のバグがあります (バグかどうかはわかりません)。次のコードを使用してテストできます:
行版 //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
html>
背景のクリックによってトリガーされることがわかります。イベントはトリガーできませんが、境界線をクリックするとトリガーできます。
なぜですか?次に、次のコードを使用してテストします:
次の 2 つの div は、本文を超える (つまり、赤いボックスを超える) 場合はイベントをトリガーできないことがわかるはずです。
つまり、イベントをトリガーするポイントが体外にあり、背景が透明な場合、トリガーポイントは体外の何もない場所にあると誤解されるため、イベントはトリガーされません。 解決策は、イベントトリガーポイントをボディ内に維持するか、不透明な背景を設定することです。
この問題は、プログラムでドラッグアンドドロップオブジェクトの背景色を設定するだけで解決できますが、場合によっては透明にする必要がある場合(カット効果など)、どうすればよいですか?
最初に思いつくのは、背景色を追加して完全に透明に設定することですが、そうするとコンテナ内の境界線やオブジェクトまで完全に透明になってしまい、これでは良くありません。
with(this._Handle.appendChild(document.createElement("div")).style ){
width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)";
プログラムにこのバグが発生した場合は、プログラムのオプションのパラメータを設定してくださいTransparent を true に設定すると、そのようなレイヤーが自動的に挿入されます。
もっと良い方法があればアドバイスをお願いします。
今回はここまでですが、考慮されていないiframeやスクロールなどもありますので、必要に応じて検討していきます。

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

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

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境
