H5—全局拖拽属性draggable
draggable全局拖拽属性—规定元素是否可拖动
属性值 | 描述 |
---|---|
true | 规定元素的可拖动的 |
false | 规定元素不可拖动 |
auto | 使用浏览器的默认行为 |
注意:链接和图像默认是可拖动的,不需要 draggable 属性
浏览器兼容:
注意:
①IE 9+, Firefox, Opera, Chrome, and Safari 支持 draggable 属性
②IE8 以及更早的版本,不支持 draggable 属性
H5—拖拽API
新概念:拖拽drag、释放drop
场景解析:拖拽指的是鼠标点击源对象(拖动源)后一直移动不松手,在不断移动过程中即为拖拽。一但松手就释放了,一般会在进入到目标对象(放置目标)后进行释放。
源对象与目标对象
- 源对象drag:
指的是鼠标点击后拖拽的一个事物对象,这里可以是一张图片、一个DIV区域、一段文本、一个文件等等。 - 目标对象drop:
指的是拖动源对象后移动到一块区域对象,源对象可以进入这个区域,可以在这个区域上方悬停(未松手),可以释松手释放将源对象放置此处(已松手),也可以悬停后离开该区域。
源对象API
API | 作用 |
---|---|
ondragstart | 应用于拖拽元素,源对象开始被拖动 |
ondrag | 应用于拖拽元素,源对象被拖动过程中 |
ondragend | 应用于拖拽元素,源对象被拖动结束 |
ondragleave | 应用于拖拽元素,拖拽过程中,当鼠标离开拖拽元素范围时调用 |
回顾两个坐标属性:
属性值 | 作用 |
---|---|
offsetX | 鼠标指针距离当前绑定元素左侧的距离 |
offsetY | 鼠标指针距离当前绑定元素顶部的距离 |
pageX | 鼠标指针距离文档左侧边缘的距离,不随滚动条变化而变化 |
pageY | 鼠标指针距离文档顶部边缘的距离,不随滚动条变化而变化 |
案例:实现一个可以随着鼠标拖动而移动的图片
<img class="img_area" src="img/demo.png">
*{
margin: 0;
padding: 0;
}
img{
display: block;
width: 200px;
position: absolute;
}
var img_area = document.querySelector("img.img_area");
// 记录初始偏移量
var offsetX,offsetY;
// console.log(img_area);
img_area.ondragstart = function (event) {
console.log("事件源开始被拖动");
// 记录刚拖动时,鼠标在源对象上的偏移量
offsetX = event.offsetX;
offsetY = event.offsetY;
// console.log(offsetX);
}
img_area.ondrag = function (event) {
console.log("事件源拖动ing...");
// 记录拖动时,鼠标指针距离文档左侧及顶部的距离
var x = event.pageX;
var y = event.pageY;
console.log("距离左侧:" + x + ";距离顶部:" + y);
// 针对最后一刻x,y都为0的情景,不作处理
if (x==0 && y==0){
return false;
}
// 动态计算位置:
x -= offsetX;
y -= offsetY;
console.log("左:" + x + ";顶:" + y);
// 计算结果赋值
img_area.style.left = x+"px";
img_area.style.top = y+"px";
}
img_area.ondragend = function (event) {
console.log("事件源拖动结束");
}
// img_area.ondragleave = function () {
// ondragleave 应用于拖拽元素,拖拽过程中,当鼠标离开拖拽元素范围时调用
// console.log("鼠标离开拖拽元素范围");
// }
目标对象API
属性 | 作用 |
---|---|
ondragenter | 应用于目标元素,拖拽源对象进入目标对象时触发 |
ondragover | 应用于目标元素,拖拽源对象在目标对象上移动时触发 |
ondrop | 应用于目标元素,被拖拽的元素在目标元素上,松开鼠标时触发 |
ondragleave | 应用于目标元素,源对象拖动着离开了目标对象,即当鼠标离开目标元素时调用(一般 有了 drop就没有dragleave 事件) |
ondragover有一个浏览器默认行为,那就是当ondragover触发时,ondrop会失效,所以如果想让ondrop即源对象放置生效,必须要阻止默认事件,方法如下:
drop_area.ondragover = function (event) {
event.preventDefault();
}
注意:
默认情况下,浏览器阻止任何东西向HTML元素放置拖拽的发生。
要使一个元素称为可放置区域,需要阻止浏览器的默认行为,也就是要监听dragenter 和 dragover 事件使用Event.preventDefault()。
dataTransfer数据传递对象:
dataTransfer.dropEffect拖拽效果,在PC web端主要表现在鼠标手形上。不同的dropEffect值,鼠标的手形效果是不一样的。
语法:event.dataTransfer.dropEffect = "copy";
属性值 | 作用 |
---|---|
move | 移动 |
copy | 复制 |
link | 链接 |
none | 禁止 |
案例:垃圾删除回收案例
html部分:
<h2>垃圾回收删除效果</h2>
<div class="img_area">
<img data-index="1" src="img/demo.png"/>
<img data-index="2" src="img/demo2.png"/>
<img data-index="3" src="img/demo3.png"/>
</div>
<div class="drop_area"></div>
css部分:
*{
margin: 0;
padding: 0;
}
h2{
text-align: center;
}
/*图片列表*/
.img_area{
width: 600px;
height: 200px;
border: 1px solid gray;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-around;
margin: 20px;
float: left;
}
.img_area img{
width: 180px;
height: 170px;
}
/*垃圾箱*/
.drop_area{
width: 200px;
height: 200px;
/*border: 1px solid;*/
background-image: url(../img/drop.png);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
float: left;
margin: 20px 200px;
opacity: 0.4;
}
js部分:
//源对象进入目标对象后,改变目标对象透明度
var drop_area = document.querySelector(".drop_area");
drop_area.ondragenter = function(){
// ondragenter 应用于目标元素,拖拽源对象进入目标对象时触发
console.log("源对象进入目标对象");
drop_area.style.opacity = "0.7";
}
//鼠标拖拽源对象离开目标对象后,恢复目标对象透明度
drop_area.ondragleave = function(){
// ondragleave 应用于目标元素,源对象拖动着离开了目标对象,即当鼠标离开目标元素时调用(一般 有了 drop就没有dragleave 事件)
console.log("鼠标拖拽源对象离开目标对象");
drop_area.style.opacity = "0.4";
}
//为源对象添加事件监听--为源对象中保存数据,记录拖动了哪一个源对象
var img_area_img = document.querySelectorAll(".img_area>img");
//console.log(img_area_img)
for(var i=0;i<img_area_img.length;i++){
var item = img_area_img[i];
console.log(item)
// 开始拖动源对象
item.ondragstart = function(event){
// ondragstart 应用于拖拽元素,源对象开始被拖动
// 源对象中保存数据--该img元素的data-index;
event.dataTransfer.setData("imgIndex",this.dataset.index);
console.log(this.dataset.index);
}
}
//源对象在悬停在目标对象上时,阻止默认行为,使得drop可以触发
drop_area.ondragover = function(event){
// ondragover 应用于目标元素,拖拽源对象在目标对象上移动时触发
event.preventDefault();
}
//源对象松手释放在了目标对象中
drop_area.ondrop = function(event){
// ondrop 应用于目标元素,被拖拽的元素在目标元素上,松开鼠标时触发
console.log("松开拖动");
drop_area.style.opacity = "0.4";
// 目标对象中读取数据
// event.dataTransfer 在源对象和目标对象的事件间传递数据
var imgIndex = event.dataTransfer.getData("imgIndex");
console.log(imgIndex);
// 获取源对象
var img_item = document.querySelector("img[data-index ='"+imgIndex+"']");
console.log(img_item);
// 咨询框
var confirm_area = confirm("确定删除?");
if(confirm_area){
// 删除DOM
img_item.parentNode.removeChild(img_item);
}else{
return false;
}
}
拓展:如何在网页中显示客户端(电脑)的一张图片
应用场景:
在某网站上,上传图片做头像、上传相片…
drag和drop面试题
因为是文件读取显示操作,所以涉及到文件操作,H5新增文件操作对象
对象 | 说明 |
---|---|
file | 代表一个文件对象 |
filelist | 代表一个文件列表对象;类数组 |
fileReader | 用于从文件中读取数据 |
FileWriter | 用于向文件中写出数据 |
相关函数,一共分为5步:
- 找到拖放的文件
- 创建文件读取器
- 读取文件内容
- 读取完成
- 使用读取到的数据,图像对象属性赋值
面试案例:将本地图片拖动放置到浏览器中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片拖拽浏览</title>
<style>
*{
margin: 0;
padding: 0;
}
h3{
line-height: 100px;
text-align: center;
}
#container{
width: 600px;
height: 300px;
border: 1px solid gray;
margin: 10px auto;
}
#container img{
max-width: 100%;
max-height: 100%;
}
</style>
</head>
<body>
<h3>拖放API--请拖动图片到下方方框区域</h3>
<div id="container"></div>
<script>
// 监听document的drop事件--取消其默认行为:在新窗口打开图片
var container = document.querySelector("#container");
document.ondragover = function (event) {
// 使得drop事件可以触发
event.preventDefault();
}
// 阻止在新窗口中打开图片,否则仍然会执行下载操作
document.ondrop = function (event) {
event.preventDefault();
}
// 监听div#container的drop事件,设法读取到释放的图片数据,显示出来
container.ondrop = function (event) {
event.preventDefault();
}
// 目标对象中,释放源对象
container.ondrop = function (event) {
var parper = event.dataTransfer.files[0];/*1、找到拖放的文件*/
var file = new FileReader()/*2、创建文件读取器*/
file.readAsDataURL(parper);/*3、读取文件内容*//*4.读取完成*/
console.log(parper);
console.log(file);
file.onload = function () {
console.log("读取文件完成");
console.log(file.result);
var img = new Image();/*建立图像对象*/
img.src = file.result/*5、使用读取到的数据,图像对象属性赋值*/
/*通过innerHTML删除子元素*/
if (container.children.length > 0){
container.innerHTML = "";
}
container.appendChild(img);
}
}
</script>
</body>
</html>