javascript实现最简单的拖拽效果

缘琪梦      2022-02-13     457

关键词:

一、一些无关痛痒的唠叨

拖拽还是挺不错的一个页面效果,我个人认为,其生命力在于可以让用户自己做一些操作,所谓自定义。例如:
①浏览器标签顺序的拖拽切换
现在基本上所有的选项卡式的浏览器都有顺序拖拽切换的功能,如下图:
chrome浏览器选项卡切换 张鑫旭-鑫空间-鑫生活

类似的效果我们可以在QQ精要新闻弹出框中看到,见下图:
QQ弹出窗选项顺序切换 张鑫旭-鑫空间-鑫生活

②把内容放在自己喜欢的位置上
这个在桌面软件上见到的最多,比如视频播放器,Adobe系列软件(CS3+)等。
photoshop中的拖拽 张鑫旭-鑫空间-鑫生活

在web页面上,我们也会见到拖拽效果,但是,一般不会太复杂。例如iGoogle(点击这里访问)://zxx:域名已经不是点cn结尾,而是点com点hk
igoogle页面的拖拽 张鑫旭-鑫空间-鑫生活

或是我最近经常使用的新浪微博,其弹出层是可以拖拽的,与人人,或是QQ邮箱的弹出层不同,好处在于,在我输入一些信息的时候,常需要查看页面上的一些内容,有了拖拽功能,我就可以把弹出框移到一边,以便可以看到挡在下面的信息,这也是拖拽最核心最基础的功能。(下图是新浪微博注册页面点击登录按钮后的弹出层)
新浪微博注册页面登录弹出层 张鑫旭-鑫空间-鑫生活

二、JavaScript实现原理简述

在AS3中,使用startDrag()就能实现拖拽,但是js中,却没有此方法,但是也是可以实现的,说穿了,挺简单的。实现拖拽方法不少,我呢,js功力尚浅,只知道一种实现原理。如下:
①鼠标按下+鼠标移动 → 拖拽
②鼠标松开 → 无拖拽
③鼠标偏移 → 拖拽距离

用JavaScript事件方法表示就是:
① onmousedown + onmousemove → startDrag()
② onmouseup → stopDrag()
③ ……

关键点就是让鼠标的偏移值赋给拖拽对象。举个例子吧:
比如说凤姐要拉你回家做老公,你是死活不愿意的,结果拉不动你,这就像我们无法拖拽一个普通的页面元素一样。
可以凤姐是前后500年未有的“美人”,功力深厚,她用一股无形的内力将你拴住,内力收多少距离,你抵抗不住,只能被拉回多少距离。结果外人看来,你好像是主动跟着凤姐走的。这就像拖拽一样,鼠标偏移的多少,让被拖拽的元素跟着移动多少,那么,就好像元素是跟着鼠标走的。

好吧,具体细节就不讲了,怕讲多了会起沙尘暴(混乱),那我就罪人了。

三、效果展示、代码及使用

前面两小段,我承认,有凑篇幅的嫌疑,不过这部分不像山西疫苗那样,是没有水分的。

我已经把拖拽的效果封装在一个方法里面了,在本文实例中,此方法独立在一个js文件中,也可以当做一个小插件使用。

此拖拽效果js大小压缩后不足1K,只要几十行代码就可以搞定了,我不喜欢在文章里放长长的代码。

您可以狠狠地点击这里:zxx.drag.1.0.js 或压缩版zxx.drag.1.0-min.js (可“右键 – [目标|链接]另存为”下载)

// by zhangxinxu welcome to visit my personal website http://www.zhangxinxu.com/
// zxx.drag v1.0 2010-03-23 元素的拖拽实现

var params = {
    left: 0,
    top: 0,
    currentX: 0,
    currentY: 0,
    flag: false
};
//获取相关CSS属性
var getCss = function(o,key){
    return o.currentStyle? o.currentStyle[key] : document.defaultView.getComputedStyle(o,false)[key];     
};

//拖拽的实现
var startDrag = function(bar, target, callback){
    if(getCss(target, "left") !== "auto"){
        params.left = getCss(target, "left");
    }
    if(getCss(target, "top") !== "auto"){
        params.top = getCss(target, "top");
    }
    //o是移动对象
    bar.onmousedown = function(event){
        params.flag = true;
        if(!event){
            event = window.event;
            //防止IE文字选中
            bar.onselectstart = function(){
                return false;
            }  
        }
        var e = event;
        params.currentX = e.clientX;
        params.currentY = e.clientY;
    };
    document.onmouseup = function(){
        params.flag = false;    
        if(getCss(target, "left") !== "auto"){
            params.left = getCss(target, "left");
        }
        if(getCss(target, "top") !== "auto"){
            params.top = getCss(target, "top");
        }
    };
    document.onmousemove = function(event){
        var e = event ? event: window.event;
        if(params.flag){
            var nowX = e.clientX, nowY = e.clientY;
            var disX = nowX - params.currentX, disY = nowY - params.currentY;
            target.style.left = parseInt(params.left) + disX + "px";
            target.style.top = parseInt(params.top) + disY + "px";
            if (event.preventDefault) {
                event.preventDefault();
            }
            return false;
        }
        
        if (typeof callback == "function") {
            callback(parseInt(params.left) + disX, parseInt(params.top) + disY);
        }
    }    
};

 

// by zhangxinxu welcome to visit my personal website http://www.zhangxinxu.com/
// zxx.drag v1.0 2010-03-23
var params={left:0,top:0,currentX:0,currentY:0,flag:false};var getCss=function(b,a){return b.currentStyle?b.currentStyle[a]:document.defaultView.getComputedStyle(b,false)[a]};var startDrag=function(a,b,c){if(getCss(b,"left")!=="auto"){params.left=getCss(b,"left")}if(getCss(b,"top")!=="auto"){params.top=getCss(b,"top")}a.onmousedown=function(d){params.flag=true;if(!d){d=window.event;a.onselectstart=function(){return false}}var f=d;params.currentX=f.clientX;params.currentY=f.clientY};document.onmouseup=function(){params.flag=false;if(getCss(b,"left")!=="auto"){params.left=getCss(b,"left")}if(getCss(b,"top")!=="auto"){params.top=getCss(b,"top")}};document.onmousemove=function(i){var j=i?i:window.event;if(params.flag){var f=j.clientX,d=j.clientY;var h=f-params.currentX,g=d-params.currentY;b.style.left=parseInt(params.left)+h+"px";b.style.top=parseInt(params.top)+g+"px";if(i.preventDefault){i.preventDefault()}return false}if(typeof c=="function"){c(parseInt(params.left)+h,parseInt(params.top)+g)}}};

 

使用如下:
首先调用js文件,如下:

<script src="http://www.zhangxinxu.com/study/js/zxx.drag.1.0.js" type="text/javascript"></script>

然后使用startDrag()方法绑定拖拽效果,startDrag()方法有两个参数,第一个是点击的对象(即点击那里可以实现拖拽,例如弹出层的标题栏),第二个是拖拽的对象(例如一个弹出层)。也就是startDrag(触发拖拽对象,被拖拽对象)。我做了个简单的图示意下,如下:
拖拽使用示意 张鑫旭-鑫空间-鑫生活

具体使用如下示例代码:
HTML/CSS

<style type="text/css">
#box{position:absolute; left:100px; top:100px; padding:5px; background:#f0f3f9; font-size:12px; -moz-box-shadow:2px 2px 4px #666666; -webkit-box-shadow:2px 2px 4px #666666;}
#main{border:1px solid #a0b3d6; background:white;}
#bar{line-height:24px; background:#beceeb; border-bottom:1px solid #a0b3d6; padding-left:5px; cursor:move;}
#content{width:420px; height:250px; padding:10px 5px;}
</style>

<div id="box">
    <div id="main">
        <div id="bar">拖拽</div>
        <div id="content">
            内容……
        </div>
    </div>
</div>

 

 

JS部分

<script src="http://www.zhangxinxu.com/study/js/zxx.drag.1.0.js" type="text/javascript"></script>
<script type="text/javascript">
    var oBox = document.getElementById("box");
    var oBar = document.getElementById("bar");
    startDrag(oBar, oBox);
</script>

 

上面js部分,加粗代码使关键,是不是使用很简单啊。

您可以狠狠地点击这里:拖拽效果demo

拖拽效果截图:
拖拽效果截图 张鑫旭-鑫空间-鑫生活

说明:被拖拽的最想如果不是绝对定位或是相对定位(position:absolute/relative),那么是不会看到效果的。

四、扫尾工作

实现最简单的拖拽效果,方便跟我一样js功力尚浅的人学习,也方便日后的使用:直接调用js链接,一句startDrag(objA, objB);就可以实现效果了。还是那句话,如果您发现文章中有表述不准确或是有相关问题需要交流可以通过评论或是去这里进行提问交流。
原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]

 

javascript小实例,pc网页里的拖拽(转)

这是现在的效果,可能改了一些,原来的效果是,里面的这张图是可以上下左右拖动的,然后房子上面的显示的楼栋号,也跟着图片一起移动,当时js能力还不行,未能实现项目经理的要求,不过后来项目经理又把这个效果推掉... 查看详情

jquery监听事件on写法以及简单的拖拽效果

引子——关于jquery的某些写法我先不对监听事件做解释,我们先来看下jquery的一些写法吧!我们最常用的是jquery的css()方法,相信大家都会用!假如用css设置一个属性,我们写法如下:$("#haorooms").css("width","100px");假如多个... 查看详情

4,简单的拖拽效果

classMainextendsegret.DisplayObjectContainer{/***入口文件,最先执行的构造方法*这会实例化一个和手机屏幕一样大的舞台*/publicconstructor(){super();this.once(egret.Event.ADDED_TO_STAGE,this.begin,this);}/***入口文件加载成功后执行的方法*也是逻辑的开始,... 查看详情

js实现鼠标的拖拽效果

拖拽效果在我们上网的过程中是很常见的,大家都应该在电脑上面登陆过qq吧,当这个qq的登陆框弹出来的时候,我们是可以进行拖动的。这就是一个拖拽效果这是我在慕课网上面看到的,我直接拿过来了,地址http://www.imooc.com/le... 查看详情

用javascript实现拖拽带来的种种问题

第一篇,先水一下,用javascript实现简单的拖拽。主要还是想通过demo的形式总结一下各种event对象属性。首先先看一下,这个demo最终实现的效果:主要涉及的属性有:MouseEvent.clientX、MouseEvent.clientY、HTMLElement.offsetLeft、HTMLElement.off... 查看详情

实现元素简单的拖拽

1.通过元素的offsetLeft,offsettop实现元素的拖拽1<!DOCTYPEhtml>2<html>34<head>5<metacharset="UTF-8">6<title></title>7<styletype="text/css">8.box{9width:100px;10height:100px 查看详情

screentoviewportpoint,worldtoviewportpoint,viewporttoworldpoint的运用,实现一个简单的对三维中物体的拖拽移动效果

  众所周知,我们手机或者手机屏幕上的坐标是一个二维平面的的坐标值,而且这个坐标是一像素为单位的,也就是说这个是会根据你用的设备的不同,你手机或者电脑上的坐标的长宽最大值也就不同。  之前不太了解标题... 查看详情

jquery拖拽(最浅显易懂的分析)

如何实现一个可以拖拽的div?其实很简单,我们捋清思路,很快便能实现。首先div的拖拽,如果把div当作一件物品,我们拖拽的时候是因为手抓住了这件物品,因此我们走到哪里,东西就到了哪里。但是鼠标是没有办法抓住div的... 查看详情

通过js实现简单的拖拽功能并且可以在特定元素上禁止拖拽

...处理这些细节,经过翻阅jqueryui的源码才找到答案。拖拽实现关于拖拽功能不再啰嗦,直接贴代码/***[draggable拖拽方法]*@param{[type]}modal[移动元素]*@param 查看详情

canvasn拖拽效果

...nvasid="can"width="400"height="400"></canvas><scripttype="text/javascript">varca 查看详情

three.js如何实现在x,y,z轴上的拖拽

...ateElement('script');    script.type='text/javascript';    script.src='https://raw.github.com/zz85/ThreeLabs/master/DragControls.js';    document.body.appendChild(script);    script.onload=functio... 查看详情

ui组件之浮出层的拖拽

...题,不过最后也解决了,这里也总结一下。首先,我们要实现的效果是浮出层在鼠标点击之后随着鼠标移动,松开之后停止移动,并且边框不得超出边界。网上很多教程已经说得很清楚了,这里就再啰嗦两句,这个过程总共分 查看详情

简单实现svg的拖拽和缩放

...,来控制svg(正方形)刚好在父元素内,radio是缩放比例实现方式是<fontcolor=\'red\'>重绘</font>,所以元素太多会造成卡顿。一、拖拽我们来分析拖拽的过程,鼠标按下---->鼠标移动------>松开鼠标。对应的事件分别是mo... 查看详情

jq实现登陆页面的拖拽功能

<!DOCTYPEhtml><html> <head> <metacharset="UTF-8"> <scriptsrc="js/jquery-1.9.1.min.js"type="text/javascript"charset="utf-8"></script> <title></title> 查看详情

electron开发:electron应用中的拖拽操作

...这种行为称为拖拽操作。本节将会通过两个案例介绍如何实现Electron应用的拖拽操作。本节将通过一个简单的案例演示如何实现图像文件的拖放操作,本例的主要功能是将一个图像文件拖拽的程序的某个区域,然后在窗口上按等... 查看详情

玩玩flutter的拖拽——实现一款万能遥控器(代码片段)

...然想到两年前写过的一篇博客:玩玩Android的拖拽——实现一款万能遥控器,就想着用Flutter来复刻一下。顺便练习一下Flutter里的拖拽Widget。先给大家看看最终的实现效果以及与Android版的对比(个人觉得还原度很高ÿ... 查看详情

qt::qwidget无默认标题栏边框的拖拽修改大小方式(代码片段)

...。这时候在QWidget中需要加上flag:Qt::FramelessWindowHint(实现方式很容易百度就不再赘述)。但是这样带来的问题就是系统自带的标题栏边框提供的拖拽移动和拖拽修改窗口大小的功能被废弃掉。这样就需要自己实现一个方案来提... 查看详情

arcgisjs学习笔记2实现仿百度的拖拽画圆

...产品外,其他的真的不敢恭维。在上一篇笔记里,我已经实现了自定义的地图测量模块。在百度地图里面(其他地图)都有一个周边搜索的功能,拖拽画一个圆,然后以圆半径进行搜索(也就是缓冲区╮(╯_╰)╭)。 这次的... 查看详情