版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39141044/article/details/82942718
拖拽的应用在平时的开发中很常见,如拖拽生成调查问卷,通过拖拽就能生成模板网站的系统,拖拽上传,OA系统中拖拽生成上报的流程图。
一、传统拖拽
1. 基本写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>传统拖拽</title>
<style>
.dialog{
position: absolute;
top: 50px;
left: 100px;
width: 200px;
}
.dialog .title{
background-color: #D7dEF0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
cursor: move;
}
.dialog .content{
background-color: #f0f0f0;
height: 200px;
}
</style>
</head>
<body>
<div class="dialog" id="dialog">
<div class="title">title</div>
<div class="content"></div>
</div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script>
var dialog = $('#dialog');
var titleEle = $('#dialog .title');
var lastPoint = {};
var isMouseDown = false;
titleEle.mousedown(function(e){
isMouseDown = true;
lastPoint.x = e.pageX;
lastPoint.y = e.pageY;
}).mousemove(function(e){
if(isMouseDown){
var currentLocationX = dialog.offset().left + (e.pageX - lastPoint.x);
var currentLocationY = dialog.offset().top + (e.pageY - lastPoint.y);
dialog.offset({top: currentLocationY,left: currentLocationX});
lastPoint.x = e.pageX;
lastPoint.y = e.pageY;
}
}).mouseup(function(e){
isMouseDown = false;
lastPoint = {};
}).mouseout(function(){
isMouseDown = false;
lastPoint = {};
});
</script>
</body>
</html>
2. 传统拖拽的改进
以上的基本写法有一个问题,当鼠标移动太快的时候,拖拽的元素会跟不上鼠标,鼠标脱离拖拽区域。
对此做出一点改进:
- 使用事件委托,将鼠标事件绑定在
document文档
上 - 对于鼠标移动事件不判断是否是指定子元素触发的。
<script>
var dialog = $('#dialog');
var titleEle = $('#dialog .title');
var lastPoint = {};
var isMouseDown = false;
//使用事件委托
$(document).on('mousedown','div.title',function(e){ //
isMouseDown = true;
lastPoint.x = e.pageX;
lastPoint.y = e.pageY;
}).on('mousemove',function(e){ //这里可以是使元素跟上鼠标的速度,而不至于脱离
if(isMouseDown){
var currentLocationX = dialog.offset().left + (e.pageX - lastPoint.x);
var currentLocationY = dialog.offset().top + (e.pageY - lastPoint.y);
dialog.offset({top: currentLocationY,left: currentLocationX});
lastPoint.x = e.pageX;
lastPoint.y = e.pageY;
}
}).on('mouseup',function(){
isMouseDown = false;
lastPoint = {};
});
</script>
大概就是这么个意思。
3.jquery事件对象中定位相关的属性
$(document).on('mousedown','div.title',function(e){
isMouseDown = true;
lastPoint.x = e.pageX;
lastPoint.y = e.pageY;
}).
绑定的事件中的参数e就是事件对象。
- clientX Y:参照页面左上角,不算滚动的距离
- pageX Y:参照页面左上角,从滚动条滚到最上面的的点加上滚动的距离然后再到点击的这个点距离
- offsetX Y:参照父元素左上角
- screenX Y:参照屏幕(显示器)的左上角
二、HTML5实现拖拽和拖拽上传
HTML5实现拖拽的三点:
- HTML5标签添加draggable=true
- HTML5标签添加拖拽事件(dragstart、dragover、drop)
- 通过事件对象下的event.dataTransfer对象(setData、getData、files)
- jquery下的dataTransfer需要通过
event.originalEvent.dataTransfer
使用 event.originalEvent.dataTransfer.files
或者event.dataTransfer.files
可以获取鼠标拖拽系统文件的信息
1.简单的拖拽实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>H5鼠标拖拽</title>
<style>
.container{
width: 200px;
height: 200px;
background-color: yellow;
}
.drag{
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="container" class="container" ondrop="drop(event)" ondragover="dragover(event)"></div>
<div id="drag" class="drag" draggable="true" ondragstart="dragstart(event)"></div>
<script>
function dragstart(e){
e.dataTransfer.setData("Text",e.target.id);
}
function drop(e){
e.preventDefault();
var data = e.dataTransfer.getData("Text");
e.target.appendChild(document.getElementById(data));
}
function dragover(e){
e.preventDefault();
}
</script>
</body>
</html>
2.拖拽问卷简单实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>问卷拖拽生成</title>
<style>
*{margin: 0;padding: 0;}
.left{
margin-top: 30px;
width: 50%;
float: left;
}
.left .container{
width:100%;
min-height: 500px;
box-sizing: border-box;
padding:0 10px 0 20px;
}
.left .containerDrop{
background-color: #F5F5F5;
}
.left .problem-list__item{
outline: 0;
}
.right{
margin-top: 30px;
padding:0 10px 0 20px;
width: 50%;
float: right;
box-sizing: border-box;
border-left: 5px solid red;
}
.problem-list__item{
height: 50px;
line-height: 50px;
margin-top: 20px;
outline: 3px dashed gray;
cursor: move;
}
.problem-list__item:last-child{
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="left">
<div class="container" id="container">
<h1>调查问卷</h1>
</div>
</div>
<div class="right">
<div class="problem-list" id="problem-list">
<div class="problem-list__item" draggable="true">
<label for="">姓名:</label>
<input type="text" name="name" placeholder="请输入用户名" />
</div>
<div class="problem-list__item" draggable="true">
<label for="">手机号:</label>
<input type="text" name="name" placeholder="请输入用户名" />
</div>
<div class="problem-list__item" draggable="true">
<label for="">性别:</label>
<input type="radio" name="sex" value="0"/>男
<input type="radio" name="sex" value="1"/>女
</div>
<div class="problem-list__item" draggable="true">
<label for="">爱好:</label>
<input type="checkbox" name="hobby" value="0"/>游泳
<input type="checkbox" name="hobby" value="1"/>健身
<input type="checkbox" name="hobby" value="2"/>篮球
<input type="checkbox" name="hobby" value="3"/>纹身
<input type="checkbox" name="hobby" value="4"/>烫头
</div>
<div class="problem-list__item" draggable="true">
<label for="">email:</label>
<input type="email" name="email" placeholder="请输入邮箱" />
</div>
</div>
</div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script type="text/javascript">
$(function(){
var proListEle = $('#problem-list');
var dropContainer = $('#container');
var dragTarget;
proListEle.on('dragstart','.problem-list__item',function(e){
dragTarget = e.target;
});
dropContainer.on('dragover',function(e){
e.preventDefault();
}).on('drop',function(e){
e.preventDefault();
$(this).append($(dragTarget).clone());
$(this).removeClass('containerDrop');
}).on('dragenter',function(e){
e.preventDefault();
$(this).addClass('containerDrop');
});
});
</script>
</body>
</html>
3.拖拽拼图
每个目标既是拖拽对象,也是投放对象。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>使用拖拽更改支付宝的默认付款方式</title>
<style type="text/css">
*{margin: 0;padding: 0;}
#card{
position: relative;
width: 600px;
height: 600px;
top: 50px;
left: 50px;
}
li{
width: 200px;
line-height: 200px;
height: 200px;
text-align: center;
font-size: 30px;
list-style: none;
box-sizing: border-box;
border: 3px dashed gray;
float: left;
}
ul.bg{
background-color: #eee;
}
</style>
</head>
<body>
<h3>使用拖拽更改支付宝的默认付款方式</h3>
<ul id="card">
<li>中上</li>
<li>中下</li>
<li>中左</li>
<li>左上</li>
<li>左下</li>
<li>右上</li>
<li>右下</li>
<li>中</li>
<li>中右</li>
</ul>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script>
$(function(){
var ulEle = $('#card');
var targetEle;
ulEle.children().each(function(index,element){
$(element).attr('draggable',true);
})
.end().on('dragstart','li',function(e){
targetEle = e.target;
}).on('drop',function(e){
e.preventDefault();
if(targetEle!=this){
var temp = targetEle.innerHTML;
targetEle.innerHTML = e.target.innerHTML;
e.target.innerHTML = temp;
}
ulEle.removeClass('bg');
}).on('dragover',function(e){
e.preventDefault();
}).on('dragenter',function(e){
e.preventDefault();
ulEle.addClass('bg');
});
});
</script>
</body>
</html>
3.拖拽上传(简单实现)
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.container{
width: 400px;
height: 300px;
margin: 200px auto;
border: 3px dashed #D9D9D9;
overflow: auto;
}
.containerDrag{
border: 3px dashed #000;
}
.tips{
height: 290px;
width: 100%;
text-align: center;
line-height: 290px;
}
.none{
display: none;
}
.files .file__item{
width: 100%;
height: 40px;
position: relative;
border-bottom: 1px solid #D9D9D9;
}
.files .file__item .file__info{
line-height: 40px;
font-size: 20px;
padding-left: 10px;
position: absolute;
z-index: 2;
}
.files .file__item .file__info .file__state{
display: inline-block;
width: 32px;
height: 32px;
vertical-align: middle;
}
.files .file__item .file__info .file__state--loading{
background: url('../public/img/loading.png') no-repeat;
animation-name: loading;
animation-duration: 3s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.files .file__item .file__info .file__state--right{
background: url('../public/img/right.png') no-repeat;
}
.files .file__item .file__info .file__state--wrong{
background: url('../public/img/wrong.png') no-repeat;
}
@keyframes loading{
from{transform: rotate(0deg);}
to{transform: rotate(360deg);}
}
.files .file__item .file__progress{
position: absolute;
top: 0;
height: 100%;
width: 0%;
background-color: #b0e24b;
}
</style>
</head>
<body>
<div id="container" class="container">
<div id="tips" class="tips">拖动文件至此区域,即可上传</div>
<ul id="files" class="files">
</ul>
</div>
<div id="template" style="display: none;">
<li class="file__item">
<span class="file__info">
<span class="file__state"></span>
<span class="file__name"></span>
</span>
<div class="file__progress"></div>
</li>
</div>
<div id="wrong"></div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script>
(function($) {
var containerEle = $('#container');
containerEle.on('dragenter',function(e){
if(!$('#tips').hasClass('none')){
$('#tips').text('松开鼠标,即可上传');
}
$(this).addClass('containerDrag');
}).on('dragleave',function(e){
if(!$('#tips').hasClass('none')){
$('#tips').text('拖动文件至此区域,即可上传');
}
$(this).removeClass('containerDrag');
}).on('dragover',function(e){
e.preventDefault();
}).on('drop',function(e){
e.preventDefault();
if(!$('#tips').hasClass('none')){
$('#tips').addClass('none');
$('#files').removeClass('none');
}
var files = e.originalEvent.dataTransfer.files; //取得拖拽文件的信息
for(var i=0; i<files.length;i++){
var liEle = $('#template li').clone();
var stateEle = liEle.find('.file__state');
var nameEle = liEle.find('.file__name');
var progressEle = liEle.find('.file__progress');
nameEle.text(files[i].name);
$('#files').append(liEle);
upload(files[i],stateEle,progressEle);
}
});
//上传
var upload = function(file, state, progress){
var formData = new FormData();
formData.append('file',file);
var xhr = new XMLHttpRequest();
xhr.open("POST","http://localhost/.../upload2.php",true);
xhr.upload.onprogress = function(e){
var percent = (e.loaded / e.total) *100;
progress.css('width',percent+'%');
state.addClass('file__state--loading');
}
xhr.onload = function(){
if(xhr.status == 200){
progress.css('width',0);
state.removeClass('file__state--loading').addClass('file__state--right');
}else{
state.removeClass('file__state--loading').addClass('file__state--wrong');
}
$('#wrong').append(xhr.responseText);
}
xhr.send(formData);
}
//测试上传动态效果
// var simuUpload = function(state, progress){
// var proWidth = 0;
// state.addClass('file__state--loading');
// var timer = setInterval(function(){
// proWidth = proWidth + Math.floor(Math.random()*4);
// if(proWidth < 100){
// progress.css('width',proWidth+'%');
// }else{
// clearInterval(timer);
// progress.css('width',0);
// state.removeClass('file__state--loading').addClass('file__state--right');
// }
// },100);
// }
})(jQuery);
</script>
</body>
</html>
后端代码
<?php
if( isset($_FILES['file']) ){
if($_FILES['file']['error'] > 0){ //文件上传出问题
echo 'error';
}else{
if(is_uploaded_file($_FILES['file']['tmp_name'])){
move_uploaded_file($_FILES['file']['tmp_name'], dirname ( __FILE__ )."/upload/".$_FILES['file']['name']);
echo 'success';
}else{
echo 'error';
}
}
}else{
echo 'error';
}
4.一些好用的拖拽插件
- jquery.pep.js http://pep.briangonzalez.org/
- dragdealer.js(处理滑块,自定义滚动条等) http://skidding.github.io/dragdealer/