ホームページ ウェブフロントエンド jsチュートリアル JavaScript で PC の Web ページにドラッグ アンド ドロップ効果を実装_JavaScript スキル

JavaScript で PC の Web ページにドラッグ アンド ドロップ効果を実装_JavaScript スキル

May 16, 2016 pm 03:10 PM
javascript pc 引っ張る

数年前、私は不動産ウェブサイトのデザインと開発に参加し、フロントエンドの仕事を担当しました。プロジェクトマネージャーの要求は比較的高いため、不動産の優れた機能を数多く参照しました。他の人の優れたデザインやアイデアを集めようと思って集まったとき、その時点でのデザイン案や機能の実装は何度も変更されただけで、今日達成された良い効果は翌日に延期される可能性があります。それについては話さないでください。今日説明するケースについて話しましょう。Soufun.com にアクセスしたことがあるのか​​どうかはわかりません。Soufun は支払うことができますか。広告料?)、プロダクト マネージャーが特に気に入っている機能が 1 つあります。それは次のとおりです:

これは現在の効果ですが、おそらくいくつかの変更が加えられています。元の効果は、中の絵を上下左右にドラッグすると、家に表示されている建物番号も絵とともに移動します。 time, js 能力が十分ではなく、プロジェクトマネージャーの要求を達成できませんでしたが、後にプロジェクトマネージャーがこのエフェクトを拒否し、別のエフェクトに置き換えました

プロジェクトマネージャーはこのような影響を望んでいませんでしたが、その時は私の心に深い傷を残し、今でも忘れることができません。

今日このブログを書く私の本来の目的は、この種の抗力効果を達成したいが、それを達成する方法がわからない学生に、離脱しないようにするためのアイデアを提供することを願っています。もちろん、ドラッグ アンド ドロップを実装する方法はたくさんありますが、ここでは 1 つの方法だけを JavaScript で紹介し、ゆっくりと原理を理解していきます。

さて、冗談は終わりです。本題に取り掛かりましょう。まず、ドラッグとは何かを理解する必要があります。しかし、それでも説明しておきたいと思います。

ドラッグ アンド ドロップは、マウスを使用してページ上でドラッグできます。正確に説明すると、マウスをコンテナに移動してからマウスを放さないように注意してください。実際の例では、テーブルの上に箱があり、その上に手を置いて移動します。手が止まると箱が止まります、取ってください、箱は動きません、ふふ、分かりました!

上記の内容はナンセンスであると思わないでください。そこから多くの情報を得ることができます。要約は次のとおりです:

ドラッグ = マウスダウン + マウス移動 + マウスアップ

これでドラッグ アンド ドロップのタスクが完了しました。これがドラッグ アンド ドロップの原理であることが分かりました。ドラッグ アンド ドロップの効果をシミュレートするために上記の 3 つのアクションを自然に実装できます。そうですね、これは JavaScript の構文に対応しています:

の 3 つのアクションを実装するだけです。

onmousedown、onmousemove、onmouseup

実装されるコードは次のようになります:

obj.onmousedown = function(ev){
   obj.onmousemove = function(ev){
 
   } ;
   obj.onmouseup = function(ev){
   
   };
   
}
ログイン後にコピー
なぜ次の 2 つのアクションを記述する必要があるのでしょうか? それでは、最初のステップの一般的なアイデアを説明します。次のステップは、オブジェクトをマウスで動かす方法を検討することです。アイデアはおそらく次のようになります:

まず、オブジェクトを移動するには左と上の値を操作する必要があるため、マウスの移動自体に距離を置く必要があります。マウスが移動したことを知っていますか? オブジェクトまでの距離を指定すると、オブジェクトはマウスと同じ距離を移動しますか?はは、ちょっとアイデアがあって、かわいい感じがします〜 ここで詳しく知りたい場合は、ボックス モデルを確認してください。多くのマスターも関連ブログを持っています。それを示すために次の写真を使用します。

説明: 青いボックスは画面の幅と高さ、太い黒いボックスはブラウザの表示領域の幅と高さ (ブラウザの縮小効果)、細い黒いボックスはマウスでドラッグされるオブジェクトです図に示すように、マウスの座標を取得します。event.clientX、event.clientY を使用して取得できます。

計算の一般原理は以下の図を参照してください:

説明: 左は初期位置、右はターゲット位置、原点はマウスの位置、大きな黒いボックスはブラウザの表示幅、小さな黒いボックスはドラッグ オブジェクト、ステータスを参照してください。オブジェクトを目的の位置にドラッグし、マウスの最終的な位置を取得し、マウスとオブジェクトの差を減算して、オブジェクトの上部と左の値に代入します。マウスの位置の差を取得し、その差を最初の上と左の値に追加することもできます。2 番目の種類も可能です。自分で試してみてください。

 obj.onmousedown = function(ev){
  var ev = ev || event;
  var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop;
 
  document.onmousemove = function(ev){
    var ev = ev || event;
    obj.style.left = ev.clientX - disX + 'px';
    obj.style.top = ev.clientY - disY + 'px';
  };
  document.onmouseup = function(ev){
    var ev = ev || event;
    document.onmousemove = document.onmouseup = null;
  };
}
ログイン後にコピー

这里说明一下:onmousemove和onmouseup之所以用document对象而不用obj对象,是因为如果用obj对象,鼠标在obj内部还好,如果在obj外面的话,拖拽会很怪异,你也可以改成obj体会一下,最后我们在鼠标弹起的时候将事件都清空;

上面的基本拖拽就算完成了,但是细心的同学一定会问,如果页面上有文字的话,拖拽物体会将文字选中,这效果岂不是怪怪的,没错,这是因为拖拽的时候触发了浏览器的默认选择事件,所以,在拖拽的时候,我们要清除这个默认事件,那怎么清除呢?

下面给一个兼容性写法:

if(ev.stopPropagation){
   ev.stopPropagation();
}else{
  ev.cancelBubble = true; //兼容IE
}
//简写成
ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;
ログイン後にコピー

将上面的代码放在onmousedown下,鼠标按下就清除浏览器默认事件,文字就不会被选中了,好了,一个简单的拖拽效果就完成了,当然你现在是看不到效果,之所以不给demo链接是为了让你自己试着写一写,这样印象更深刻,

好了,那问题又来了,到这里就这样完了吗?。。。。。。按本人的风格,当然没有,干货还在后面!

如果我想实现这样一个效果,就是这一个大的容器里面(可以是box,也可以是document),怎么样能让我们的拖拽对象不跑出去呢,换句话说,拖到边缘就拖不动了,耶,是不是很多人想要实现的效果,哈哈,我们看看实现的原理是什么:

现实生活中,一个物体在一个盒子里跑不出去,是因为有堵墙,那我们只要能模拟出这堵墙,就可以把物体框起来,那这堵墙要怎么做呢?我们可以换个思路,当拖拽对象拖到边缘的时候,比如说拖到右边,我们将它的left固定住,是不是就不能再往右了,因为left值不能再加了,那么拖到底部,同理我们将top值固定住,就不能再往下拖了,理解吗?

最终的结果就是如下:

//左侧
if(obj.offsetLeft <=0){
  obj.style.left = 0;
};
//右侧
if(obj.offsetLeft >= pWidth - oWidth){
  obj.style.left = pWidth - oWidth + 'px'; 
};
//上面
if(obj.offsetTop <= 0){
  obj.style.top = 0; 
};
//下面
if(obj.offsetTop >= pHeight - oHeight){
  obj.style.top = pHeight - oHeight + 'px'; 
};
ログイン後にコピー

说明:pWidth,pHeight 表示父级元素的宽高(这里是表示相对于父级的宽高限制),oWidth,oHeigt表示拖拽元素的宽高

最后,我将整个拖拽代码整理了一下:

/*
      参数说明:
      元素绝对定位,父级相对定位,如果父级为window,则可以不用
      传一个参数,表示父级为window,物体相对于window范围拖动
      传2个参数,则父级为第二个参数,物体相对于父级范围拖动
      参数为id值
    */
    function drag(obj,parentNode){
      var obj = document.getElementById(obj);
      if(arguments.length == 1){
        var parentNode = window.self; 
        var pWidth = parentNode.innerWidth,pHeight = parentNode.innerHeight;  
      }else{
        var parentNode = document.getElementById(parentNode);
        var pWidth = parentNode.offsetWidth,pHeight = parentNode.offsetHeight;
      }
      obj.onmousedown = function(ev){
        var ev = ev || event;
        var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop;
        var oWidth = obj.offsetWidth,oHeight = obj.offsetHeight;
         
        //阻止冒泡时间
        ev.stopPropagation &#63; ev.stopPropagation() : ev.cancelBubble = true;
       
         
        document.onmousemove = function(ev){
          var ev = ev || event;
          obj.style.left = ev.clientX - disX + 'px';
          obj.style.top = ev.clientY - disY + 'px';
           
          //左侧
          if(obj.offsetLeft <=0){
            obj.style.left = 0;
          };
          //右侧
          if(obj.offsetLeft >= pWidth - oWidth){
            obj.style.left = pWidth - oWidth + 'px'; 
          };
          //上面
          if(obj.offsetTop <= 0){
            obj.style.top = 0; 
          };
          //下面
          if(obj.offsetTop >= pHeight - oHeight){
            obj.style.top = pHeight - oHeight + 'px'; 
          };
        };
        document.onmouseup = function(ev){
          var ev = ev || event;
          document.onmousemove = document.onmouseup = null;
        };
      }
         
    }
ログイン後にコピー

说明:我这里处理的效果是,如果传一个参数,表示相对的对象是window对象,如果传2个参数,第一个是拖拽对象,第二个为相对父级

开篇就说了,搜房网的那个图片拖拽效果是我的一个心结,我写了一个类似的效果,供大家参考,因为自己没有买服务器,所以效果我就不展示了,直接把代码贴出来,供大家参考:

css:

<style>
.box{
  width:600px;
  height:400px;
  margin:50px auto;
  position:relative;
  overflow:hidden;
}
#box{
  width:1000px;
  height:800px;
  position:absolute;
  left:50%;
  top:50%;
  margin:-400px 0 0 -500px;
}
#pic{ width:800px; height:600px; background:url(images/pic1.jpg) no-repeat; position:absolute; left:100px; top:100px; }
#pic:hover{
  cursor:move;
}
</style>
ログイン後にコピー

html:

<div class="box">
    <div id="box">
      <div id="pic"></div>
    </div>
  </div>
ログイン後にコピー

javascript:

window.onload = function(){
     
    drag("pic","box");
    function drag(obj,parentNode){
      var obj = document.getElementById(obj);
      if(arguments.length == 1){
        var parentNode = window.self; 
        var pWidth = parentNode.innerWidth,pHeight = parentNode.innerHeight;  
      }else{
        var parentNode = document.getElementById(parentNode);
        var pWidth = parentNode.offsetWidth,pHeight = parentNode.offsetHeight;
      }
      obj.onmousedown = function(ev){
        var ev = ev || event;
        var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop;
        var oWidth = obj.offsetWidth,oHeight = obj.offsetHeight;
         
        //阻止冒泡时间
        ev.stopPropagation &#63; ev.stopPropagation() : ev.cancelBubble = true;
       
         
        document.onmousemove = function(ev){
          var ev = ev || event;
          obj.style.left = ev.clientX - disX + 'px';
          obj.style.top = ev.clientY - disY + 'px';
           
          //左侧
          if(obj.offsetLeft <=0){
            obj.style.left = 0;
          };
          //右侧
          if(obj.offsetLeft >= pWidth - oWidth){
            obj.style.left = pWidth - oWidth + 'px'; 
          };
          //上面
          if(obj.offsetTop <= 0){
            obj.style.top = 0; 
          };
          //下面
          if(obj.offsetTop >= pHeight - oHeight){
            obj.style.top = pHeight - oHeight + 'px'; 
          };
        };
        document.onmouseup = function(ev){
          var ev = ev || event;
          document.onmousemove = document.onmouseup = null;
        };
      }
         
    }
     
     
  }
ログイン後にコピー

效果完全是用的那个封装代码块,引用起来也挺方便,有人会问了,你这用的id获取DOM元素,一个页面只能用一次啊,如果页面多次使用呢,有道理,解决方案之一,那就命名不同的id呗,又不犯法,方案二,获取id的地方改成获取class,但是要注意的是,getElementsByClassName是获取的class集合,需要改写一下,这里我就不写了,有兴趣的同学自行改写一下,好了,到这里真的结束了!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Windows PCでアクセスポイントが一時的にいっぱいになるエラーを修正する方法 Windows PCでアクセスポイントが一時的にいっぱいになるエラーを修正する方法 Mar 16, 2024 pm 03:19 PM

Windows 11/10 PC で Wi-Fi ルーターまたはモバイル ホットスポットに接続するときに「アクセス ポイントが一時的にいっぱいです」というエラーが発生した場合、これは通常、ネットワークの過負荷または接続されているデバイスの多さが原因です。この問題を解決してインターネットに正常に接続するには、次の方法を試してください。 1. 他のデバイスが切断されるまでしばらく待ってから、再度接続を試みます。 2. Wi-Fi ルーターまたはモバイル ホットスポットを再起動して、ネットワーク キャッシュをクリアし、IP アドレスを再割り当てします。 3. PC の Wi-Fi アダプター ドライバーが最新であることを確認し、デバイス マネージャーで更新を確認します。 4. さまざまな時間に接続してみてください。ピーク時間を避けると、接続の機会が増える可能性があります。 5. AccessP の追加を検討する

Windows PC が BIOS で起動し続ける [修正] Windows PC が BIOS で起動し続ける [修正] Mar 11, 2024 am 09:40 AM

Windows PC が頻繁に BIOS インターフェイスに入る場合、使用が困難になる可能性があります。コンピューターの電源を入れるたびに BIOS 画面が表示され、再起動しても問題が解決しません。この問題に直面している場合は、この記事で説明する解決策が役に立ちます。コンピューターが BIOS で起動し続けるのはなぜですか? BIOS モードでコンピューターが頻繁に再起動する場合は、不適切なブート シーケンス設定、SATA ケーブルの損傷、接続の緩み、BIOS 構成エラー、ハード ドライブの障害など、さまざまな理由が考えられます。 Windows PC が BIOS で起動し続ける問題を修正する Windows PC が BIOS で起動し続ける場合は、以下の修正プログラムを使用してください。起動順序を確認し、再接続します。

Windows PC で Samsung Flow を使用する方法 Windows PC で Samsung Flow を使用する方法 Feb 19, 2024 pm 07:54 PM

SamsungFlow は、Galaxy 電話を Windows PC に簡単に接続できる便利で実用的なツールです。 SamsungFlow を使用すると、デバイス間でコンテンツを共有したり、通知を同期したり、スマートフォンをミラーリングしたりすることができます。この記事では、Windows パソコンで SamsungFlow を使用する方法を紹介します。 Windows PC でスマートフォン ストリーミングを使用する方法 SamsungFlow を使用して Windows PC と Galaxy Phone を接続するには、Galaxy スマートフォンとタブレットが Android 7.0 以降を実行し、Windows PC が Windows 10 以降を実行していることを確認する必要があります。

すべての OneDrive ファイルを一度に PC にダウンロードする方法 すべての OneDrive ファイルを一度に PC にダウンロードする方法 Feb 19, 2024 pm 06:51 PM

この記事では、すべての OneDrive ファイルを PC に一度にダウンロードする方法を説明します。 OneDrive は、ユーザーがいつでもどこでもファイルにアクセスできるようにする強力なクラウド ストレージ プラットフォームです。場合によっては、ユーザーはファイルをローカルにバックアップしたり、オフラインでアクセスしたりする必要があるかもしれません。これを簡単に行う方法については、読み続けてください。すべての OneDrive ファイルを一度に PC にダウンロードするにはどうすればよいですか?すべての OneDrive ファイルを Windows PC に一度にダウンロードするには、次の手順に従います。 Onedrive を起動し、[マイ ファイル] に移動します。 OneDrive にアップロードされたすべてのファイルはここで利用できるようになります。 CTRL+A を押してすべてのファイルを選択するか、チェックボックスをオンにしてすべての項目の選択を切り替えます。上部にあるダウンロードオプションをクリックし、

低コスト Chrome ホストの冒険: ブラック Apple をインストールすることはできませんが、認定された PC と見なすことができます 低コスト Chrome ホストの冒険: ブラック Apple をインストールすることはできませんが、認定された PC と見なすことができます Jul 11, 2024 pm 04:38 PM

そういえば、海外ジャンクシリーズはすでに何冊も出ていますが、それ以前は携帯電話や組み立て済みのPCがほとんどで、前者はプレイアビリティとしては平均的で、後者は不確実性が満載でした。たとえば、前回インストールに 300 ドルを費やしたコンピューターは、現在、ドライバーがノンストップで削除される状態になっています。しかし、「ボロ拾い」とはそういうもので、リスクとメリットが共存するのが常です。たとえば、今回ASUS ChromeBoxを「拾った」のですが、当初はこれをMacmini(偽物)にしようと思っていましたが、途中で予想外の問題が多く発生し、意図した目的を達成できませんでした。結局、次善の策に落ち着いて、それに Windows をフラッシュすることを選択する必要がありました。リンゴを黒くする試みは最後の段階まで落ちましたが、その過程全体はとても楽しかったです。そしてとして

300元を費やして組み立てたコンピューターは、地元の大型モデルで正常に動作しました 300元を費やして組み立てたコンピューターは、地元の大型モデルで正常に動作しました Apr 12, 2024 am 08:07 AM

2023 年が AI 元年とみなされるなら、2024 年は大規模な AI モデルの普及にとって重要な年になる可能性があります。過去 1 年間で、多数の大規模な AI モデルと多数の AI アプリケーションが登場し、Meta や Google などのメーカーも、「AI 人工知能」と同様の独自のオンライン/ローカル大規模モデルを一般に公開し始めています。 「それは手の届かないところにある。」という概念が突然人々に浮かびました。現在、人々は生活の中で人工知能に触れる機会が増えており、注意深く見てみると、アクセスできるさまざまな AI アプリケーションのほぼすべてが「クラウド」上に展開されていることがわかります。大きなモデルをローカルで実行できるデバイスを構築したい場合、ハードウェアは 5,000 元以上の新品の AIPC になります。

中華風ハードコア武侠アクションゲーム『Yi Wen Lu: Reinationnation』本日よりオンライントライアル開始 中華風ハードコア武侠アクションゲーム『Yi Wen Lu: Reinationnation』本日よりオンライントライアル開始 Feb 06, 2024 pm 06:00 PM

中国風ハードコア武侠アクションゲーム『イー・ウェン・ルー:サムサラ』が本日よりオンライントライアルプレイを開始。これは、中国の伝統的な文化要素を取り入れたマルチプラットフォームのハードコア武術アクション スタンドアロン ゲームであり、プレイヤーは武術キャラクターとして世界の災難を防ぎ、安定と平和を取り戻すことになります。関係者らは、プレイヤーは絶妙な芸術シーンと鮮やかなストーリーを通じて武道文化の価値を説明し、武道文化の含意と精神を探求して表現し、同時に素晴らしい旅を体験できると主張している。開発者によると、チームの当初の設計意図は、プレイヤーが武術の優雅さをよりよく体験できるようにすることであり、チームは中国武術のさまざまな流派とテクニックのほとんどを研究し、ゲーム内でそれらをリアルに表現しました。プレイヤーは、太極拳、剣術、剣技などのさまざまなスキルや動きを使って学習したり、敵と遭遇したりできます。

国産FPSの新たな王者! 「オペレーション・デルタ」の戦場は予想を超える 国産FPSの新たな王者! 「オペレーション・デルタ」の戦場は予想を超える Mar 07, 2024 am 09:37 AM

「オペレーション デルタ」は本日(3月7日)より大規模PCテスト「コードネーム:ZERO」を開始する。先週末、上海で本作のオフラインフラッシュモブ体験イベントが開催され、幸運にも17173さんも参加することができました。前回のテストからわずか 4 か月以上しか離れていないため、この短期間で「オペレーション デルタ」がどのような新たなハイライトやサプライズをもたらすのか、興味が湧きます。 4か月以上前、私はオフライン試食会と最初のベータ版で「オペレーション デルタ」を体験しました。当時、ゲームは「危険なアクション」モードのみを開きました。しかし、デルタ作戦は当時としてはすでに印象的なものでした。大手メーカーがモバイルゲーム市場に群がる中、国際基準に匹敵するFPS

See all articles