Rumah  >  Artikel  >  hujung hadapan web  >  JavaScript melaksanakan kesan seret dan lepas dalam kemahiran javascript halaman web PC

JavaScript melaksanakan kesan seret dan lepas dalam kemahiran javascript halaman web PC

WBOY
WBOYasal
2016-05-16 15:10:551478semak imbas

Beberapa tahun yang lalu, saya telah mengambil bahagian dalam reka bentuk dan pembangunan projek laman web hartanah laman web dan ingin mengumpul reka bentuk dan idea orang lain yang sangat baik Apabila kami berkumpul, draf reka bentuk dan pelaksanaan fungsi pada masa itu hanya diubah lagi dan sekali lagi itu, mari kita tidak bercakap mengenainya. Mari kita bercakap tentang kes yang akan kita jelaskan hari ini. beberapa yuran pengiklanan?), terdapat satu fungsi yang paling disukai oleh pengurus produk, iaitu yang berikut Ini:

Ini adalah kesan semasa, mungkin beberapa perubahan Kesan asal ialah gambar di dalam boleh diseret ke atas, ke bawah, ke kiri, dan ke kanan, dan kemudian nombor bangunan yang dipaparkan di rumah juga bergerak dengan gambar time, js Keupayaan tidak cukup baik, dan keperluan pengurus projek tidak tercapai, tetapi kemudian pengurus projek menolak kesan ini dan menggantikannya dengan kesan lain

Walaupun pengurus projek tidak mahu kesan ini, ia meninggalkan simpulan di hati saya pada masa itu, dan saya tidak dapat melupakannya sehingga hari ini.

Baiklah, ini niat asal saya menulis blog ini pada hari ini saya harap ia dapat memberi idea kepada pelajar yang ingin mencapai kesan seretan seperti ini, tetapi tidak tahu bagaimana untuk mencapainya, supaya tidak meninggalkannya. apa-apa penyesalan untuk remaja mereka Sudah tentu, terdapat banyak cara untuk melaksanakan seret dan lepas Di sini saya hanya akan memperkenalkan satu kaedah dalam JavaScript, dan perlahan-lahan memahami prinsipnya.

Baiklah, jenaka sudah berakhir, mari kita mula-mula memahami apa itu seretan, dan saya tahu itu, tetapi saya masih mahu menerangkannya:

Seret dan lepas adalah bekas Anda boleh menggunakan tetikus untuk menyeretnya di halaman, penerangan yang tepat sepatutnya, gerakkan tetikus ke bekas, kemudian tekan tetikus, berhati-hati untuk tidak melepaskannya. dan kemudian seret Tetikus dan bekas boleh mengikut tetikus Apabila anda melepaskan tetikus, bekas itu akan berhenti di situ kotak itu apabila tangan saya berhenti, kotak itu berhenti, kotak itu tidak bergerak, saya faham!

Jangan anggap perkara di atas adalah karut, banyak maklumat yang boleh kita perolehi, ringkasannya adalah seperti berikut:

Seret = tetikus ke bawah + pergerakan tetikus + tetikus ke atas

Ini menyelesaikan tugas seret dan lepas Nah, ternyata ini adalah prinsip seret dan lepas Jika anda ingin melaksanakan seret dan lepas, anda boleh melaksanakan tiga tindakan di atas untuk mensimulasikan kesan seret dan lepas. . Nah, ia sepadan dengan sintaks dalam JavaScript Hanya perlu melaksanakan 3 tindakan ini:

onmousedown, onmouseup, onmouseup

Kod yang dilaksanakan hendaklah:

obj.onmousedown = function(ev){
   obj.onmousemove = function(ev){
 
   } ;
   obj.onmouseup = function(ev){
   
   };
   
}

Mengapa dua tindakan seterusnya perlu ditulis di dalamnya. Ideanya mungkin seperti ini:

Pertama sekali, objek perlu diposisikan, kerana kita perlu memanipulasi nilai kiri dan atasnya untuk membuatnya bergerak tahu bahawa tetikus telah bergerak Sejauh mana jaraknya? Haha, saya ada idea sikit, dan rasa comel~ Masalahnya sekarang adalah bagaimana untuk mendapatkan jarak tetikus Jika anda perlu tahu lebih lanjut, sila semak model kotak saya tidak akan masuk ke sini. Banyak tuan juga mempunyai blog yang berkaitan. Saya menggunakan satu gambar untuk menunjukkannya:

Penjelasan: Kotak biru ialah lebar dan ketinggian skrin, kotak hitam tebal ialah lebar dan ketinggian kawasan yang boleh dilihat pelayar (kesan pengurangan pelayar), kotak hitam nipis adalah objek yang akan diseret oleh tetikus , seperti yang ditunjukkan dalam rajah, dapatkan koordinat tetikus , anda boleh menggunakan event.clientX, event.clientY untuk mendapatkannya, oh;

Prinsip umum pengiraan boleh merujuk kepada rajah di bawah:

Penjelasan: Kiri adalah kedudukan awal, kanan ialah kedudukan sasaran, asal adalah kedudukan tetikus, kotak hitam besar adalah lebar pelayar yang boleh dilihat, kotak hitam kecil adalah objek seret, lihat status daripada objek seret ke kedudukan sasaran, dan dapatkan tetikus Kedudukan akhir tetikus, kemudian tolak perbezaan antara tetikus dan objek, dan kemudian tetapkan pada nilai atas dan kiri objek Anda juga boleh mendapatkan perbezaan kedudukan tetikus, dan kemudian menambah perbezaan pada nilai atas dan kiri awal Kami menggunakan yang pertama Jenis kedua juga boleh, cuba sendiri:

 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集合,需要改写一下,这里我就不写了,有兴趣的同学自行改写一下,好了,到这里真的结束了!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn