今日は最後のドラッグ プロトタイプの問題をいくつか解決します。以下の問題点は何でしょうか?
全員が問題を確認できるように、前号の Javascript コードを添付します。
<script type="text/javascript"> window.onload = function() { var oDiv = document.getElementById("div1"); var disX = 0; var disY = 0; oDiv.onmousedown = function(ev) { var oEvent = ev || event; disX = oEvent.clientX - oDiv.offsetLeft; disY = oEvent.clientY - oDiv.offsetTop; oDiv.onmousemove = function(ev) { var oEvent = ev || event; oDiv.style.left = oEvent.clientX - disX+'px'; oDiv.style.top = oEvent.clientY - disY+'px'; }; oDiv.onmouseup = function() { oDiv.onmousemove = null; oDiv.onmouseup = null; }; }; }; </script>
1. 現在のドラッグ中にマウスを速く動かすと、 マウスが div から外れ、この時点では div がマウスに追従しないことがわかります。
では、なぜこの問題が発生するのでしょうか?
その理由は実際には非常に簡単で、mousemove イベントを div に追加しているため、マウスが div から離れると、その時点では Mousemove はトリガーされなくなります。
解決策: イベントはドキュメントに読み込まれます。マウスは何があってもページ内にあるため、何があってもマウス移動がトリガーされ、問題なく素早く移動できます。
次に、それに応じてコードを変更します。
<script type="text/javascript"> window.onload = function() { var oDiv = document.getElementById("div1"); var disX = 0; var disY = 0; oDiv.onmousedown = function(ev) { var oEvent = ev || event; disX = oEvent.clientX - oDiv.offsetLeft; disY = oEvent.clientY - oDiv.offsetTop; // 事件加载document 上 document.onmousemove = function(ev) { var oEvent = ev || event; oDiv.style.left = oEvent.clientX - disX+'px'; oDiv.style.top = oEvent.clientY - disY+'px'; }; oDiv.onmouseup = function() { document.onmousemove = null; oDiv.onmouseup = null; }; }; }; </script>
そうすれば、この問題は解決できます。
2. すぐにドラッグする問題は解決しましたが、この位置にマウスを移動すると、問題があるかどうかを確認してください。
マウスが div 上にないことがはっきりとわかります。この時点でマウスを持ち上げると、戻った後もマウスが移動することがわかります。
これはまたバグです!
実際、この問題は上記の問題と同じです。解決策は非常に簡単です。マウスアップをドキュメントに追加してみましょう。
document.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; };
3. ブラウザの互換性の問題を見てみましょう
実際、Firefox の下位バージョンではこのような問題があります
。初めてドラッグすると、正しく表示されます。一度ドラッグして、押したまま移動すると、その後ろにこの影があることがわかります。どうしたの?
今度は問題がなくなったことがわかるでしょう。
つまり、Firefox のバグは空の div にのみ発生します。
解決策:
これは実際には非常に簡単で、onmousedown でブラウザのデフォルト イベントが false を返さないようにするだけです。 なぜ onmousedown に追加するのでしょうか?ドラッグがどのイベントから始まるかは、マウスが押されたときのonmousedownから始まりますよね。したがって、onmousedown でロードする必要があります。
実際、Firefox のバグをブロックするために return false を追加しただけです。
いくら引きずっても問題ありません。
コードを添付します:
<script type="text/javascript"> window.onload = function() { var oDiv = document.getElementById("div1"); var disX = 0; var disY = 0; oDiv.onmousedown = function(ev) { var oEvent = ev || event; disX = oEvent.clientX - oDiv.offsetLeft; disY = oEvent.clientY - oDiv.offsetTop; // 事件加载document 上 document.onmousemove = function(ev) { var oEvent = ev || event; oDiv.style.left = oEvent.clientX - disX+'px'; oDiv.style.top = oEvent.clientY - disY+'px'; }; document.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; }; return false; }; }; </script>
たとえば、ユーザーがこの div をブラウザの外にドラッグする可能性がありますが、それを解決するにはどうすればよいでしょうか?
それでは判定を加えてみましょう。 これは非常に簡単で、左から外に出ると
の場合、それは直接 0 に等しく、左から抜け出すことができなくなります。それから、上記も同様です。
では、右側から出られなくなるのを防ぐにはどうすればよいでしょうか? ? 絵を描くだけで一目瞭然です。 実際、ページの表示幅から div の幅を引くだけで計算できます。
これがいわゆる最大値であり、移動距離がこの最大値を超えているかどうかを判断してください。それでは以下同様です。
完全なコードを添付します:
<script type="text/javascript"> // 拖拽空div 低版本的火狐有bug window.onload = function() { var oDiv = document.getElementById("div1");var disX = 0; var disY = 0; oDiv.onmousedown = function(ev) { var oEvent = ev || event; disX = oEvent.clientX - oDiv.offsetLeft; disY = oEvent.clientY - oDiv.offsetTop; document.onmousemove = function(ev) { var oEvent = ev || event; // 存储div当前的位置 var oDivLeft = oEvent.clientX - disX; var oDivTop = oEvent.clientY - disY; // 从左边拖出去了 if (oDivLeft < 0) { oDivLeft = 0; } else if (oDivLeft > document.documentElement.clientWidth - oDiv.offsetWidth) { oDivLeft = document.documentElement.clientWidth - oDiv.offsetWidth; } if (oDivTop < 0) { oDivTop = 0; } else if (oDivTop > document.documentElement.clientHeight - oDiv.offsetHeight) { oDivTop = document.documentElement.clientHeight - oDiv.offsetHeight; } oDiv.style.left = oDivLeft + 'px'; oDiv.style.top = oDivTop + 'px'; }; document.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; }; return false; // 阻止默认事件,解决火狐的bug }; }; </script>