【js学习笔记-096】----拖放事件
来源:互联网 发布:活性炭多久晒一次 知乎 编辑:程序博客网 时间:2024/05/16 14:30
【js学习笔记----拖放事件】
前面的篇幅中我们已经介绍过响应鼠标拖动。使用像那样的技术允许在网页上拖起“放置”元素,但真正的“拖放”是另一回事。拖放是在“拖放源”和“拖放目标”之间传输数据的用户界面,它可以存在相同的应用之间,也可以是不同应用之间。拖放是复杂的人机交互,用于实现拖放的API总是很复杂:
- 它必须和底层的OS结合,使它们能够在不相关的应用间工作。
- 它们必须适用于“移动”、“复制”和“链接”数据传输操作,允许拖放和拖放目标通过设置限制限制允许的操作,然后让用户选择(通常使用键盘辅助键)许可设置
- 它们必须为拖放源提供一种方式指定待拖动的图标和图像
- 它们必须为拖放源和拖放目标的DnD交互过程提供基于事件的通知
Microsoft IE早期版本就引入了DnD API。它并不是精心设计且精良的归档API,但其他浏览器都尝试复制它,且html5标准化了类似IE DnD API的东西,并增加了使API更易于使用的新特性。
draggable属性:任何html文档元素具有draggable属性的文档元素都是拖放源。当用户开始用鼠标在拖放源上拖动时,浏览器并没有选择元素内容,相对,它在这个元素上触发dragstart事件。这个事件的处理程序就调用dataTransfer.setData()指定当前可用的的拖放源数据(和数据类型)。(当新的html5 api实现时,可以用dataTransfer.items.add()代替。)这个事件的处理程序也可以设置dataTransfer.effectAllowed来指定支持“移动”、“复制”和“链接“传输操作中的几种,同时它可以调用dataTransfer.setDragImage()或dataTransfer.addElement()(在那些支持这些方法的浏览器中)指定图片或文档元素用做拖动时的视觉表现。在拖动过程中,浏览器在拖放源上触发拖动事件。如果想更新拖动图片或修改提供的数据,可以监听这些事件,但一般不需要注册”拖动“事件处理程序。
当放置数据发生时会触发dragstart 事件。如果拖放源支持” 移动“操作,它就会检查dataTransfer.dropEffect去看看是否实际执行了移动操作。如果执行了,数据就被传输到其他地方,你应该人拖放源中删除它。
例:一个自定义拖放源
<script src=”whenReady.js></script>
<script>
whenReady(function(){
var clock =document.getElementById(“clock”); //时钟元素
var icon =new Image(); //用于拖动的图片
icon.src =“clock-icon.png”; //图片url
//每分种显示一次时间
functiondisplayTime(){
varnow = new Date(); //获取当前时间
var hrs = now.getHours(),mins =now.getMinutes();
if(mins<10)mins=”0”+mins;
clock.innerHTML = hrs+”:”+mins; //显示当前时间
setTimeout(displayTime,60000); //一分钟后将再次运行
}
displayTime();
//使时钟能够拖动
//我们也能通过html属性实现这个目的:<span draggable=”true”>…
clock.draggable = true;
clock.ondragstart = function(event){
var event = event || window.event; //用于兼容IE
var dt = event.dataTransfer;
//告诉浏览器正在拖动的是什么
//把Date()构造函数用做一个返回时间戳字符器函数
Dt.setData(“Text”,Date()+”\n”);
//在支持的浏览器中,告诉它拖动图标来表现时间戳
//没有这行代码,浏览器也可以使用时钟文本图像作为拖动的值
If(dt.setDragImage)dt.setDragImage(icon,0,0);
};
});
</script>
<style>
#clock{
font:bold24pt sans;background:#ddf;padding:10px;border:solid black 2px;
border-radius:10px;
}
</style>
<h1>从时钟中播出时间戳</h1>
<span id=”clock”></span><!—时间显示在这里-->
<textareacols=60 rows=20></textarea> <!—把时间戳放置在这里-->
拖放目标比拖放源更棘手。任何文档元素都可以是拖放目标。这不需要拖放源一样设置html属性。只需要简单地定义合适的事件监听程序。(在html5DnD API,将可以在拖放目标上定义dropzone属性来取代定义后面介绍的一部分事件处理程序)
dragenter事件
dragover事件
dragleave事件
drop事件 事件处理程序使用dataTransfer.getData()获取传输的数据并做一些适当的处理。另外,如果用记在拖放目标放置一个或多个文件,dataTransfer.files属性是一个类数组的File对象。使用新的html 5 API ,drop事件处理程序将能遍历dataTransfer.items[]的元素去检查文件和非文件数据。
例:演示如何使<ul>元素成为拖放目标,同时如何使它们中的<li>元素成为拖放源。它查找class属性包含 “dnd”的<ul>元素,在它找到的此类列表上注册DnD事件处理程序。这些事件处理程序使列表本身成为拖放目标,在这个列表上放置的任何文本会变成新的列表项并插入到列表尾部。这些事件处理程序也监听列表项的拖动,使得每个列表项的文本可用于传输。拖放源事件处理程序允许“复制”和“移动”操作,并在移动操作下放置对象时会删除原有列表项。
例:作为拖放目标和拖放源的列表
/*
DnD API相当复杂,且浏览也不完全兼容
这个例子基本正确,但每个浏览器会有一点不同,每个似乎都有自身独有的bug
这些代码不会尝试浏览器特有的解决方案
*/
whenReady(function(){
//查找所有的<ul class=’dnd’>元素,并对其调用dnd()函数
var lists =document.getElementsByTagName(“ul”);
var regexp = /\bdnd\b/;
for(var i=0;i<lists.length;i++) if(regexp.text(list[i].className))dnd(lists[i]);
//为列表元素添加拖放事件处理程序
function dnd(list){
var original_class = list.className; //保存原始css类
var entered = 0;
//当拖放对象首次进入列表时调用这个处理程序
//它会检查拖放对象包含的数据格式它是否能处理
//如果能,它返回false来表示有兴趣放置
//这种情况下,它会高亮拖放目标,让用户知道兴趣
list.ondragenter = function(e){
e= e || window.event ;//标准或IE事件
varfrom = e.relatedTarget;
//dragenter和dragleave事件冒泡,它使得像<ul>元素有<li>子元素的情况下
//何时高亮显示或取消高亮显示元素变得棘手,在定义relatedTarget的浏览器
//中,我们能跟踪它,否则,我们需要通过统计进入和离开次数 如果从列表外进入
//或第一次进入,那么需要做一些处理
entered++;
if((from &&!ischild(from,list)) || entered==1){
var dt = e.dataTransfer; //所有dnd信息都在dataTransfer对象
//dt.types对象列出可用的拖放数据的类型或格式
//html5 定义这个对象有contains()方法
//在一些浏览器中,它是一个有indexOf()方法的数组
//在IE8及以前的版本中,它根本不存在
var types = dt.types;
//如果没有任何类型的数据或可用数据是纯文本格式
//那么高亮显示列表让用户知道我们正在监听拖放
//同时返回false让浏览器知晓
if(!types || //ie
(types.contains&& types.contains(“text/plain”)) || //html5
(types.indexOf && types. indexOf (“text/plain”)!=-1) //Webkit
){
list.className = original_class+” droppable”;
return false;
}
//如果我们无法识别数据类型,我们不希望拖放
return ;
}
return false ;//如果不是第一次进入,我们继续操持兴趣
}
//当鼠标指针悬停在列表上时,会调用这个处理程序
//我们必须定义这个处理程序并返回false,否则这个拖放操作将取消
list.ondragover = function(e){return false;};
list.ondragleave = function(e){
e= e || window.event;
var to = e.relatedTarget;
entered--;
if( to &&!ischild(to,list) || entered<=0){
list.className = original_class;
entered = 0;
}
return false;
};
list.ondrop = function(e){
e= e || window.event;
var dt = e.dataTransfer;
var text = dt.getData(“Text”);
if(text){
var item = document.createElement(“li”);
item.draggable = true;
item.appendChild(document.createTextNode(text));
list.appendChild(item);
list.className = original_class;
entered = 0;
return false;
}
};
//使原始所有列表项可拖动
var items = list.getElementsByTagName(“li”);
for(var I =0;i<items.length;i++) items[i].draggable= true;
list.ondragstart = function(e){
e=e|| window.event;
var target =e.target || e.srcElement;
if(target.tagName==”LI”)return false;
var dt = e.dataTransfer;
dt.setData(“Text”,target.innerText || target.textContent);
dt.effectAllowed=”copyMove”;
};
list.ondragend = function(e){
e= e|| window.event;
var target =e.target || e.srcElement;
if(e.dataTransfer.dropEffect===”move”)
target.parentNode.removeChild(“target”);
}
function ischild(a,b){
for(; a;a=a.parentNode) if(a===b) return true;
return false;
}
}
});
- 【js学习笔记-096】----拖放事件
- #学习笔记#(10)元素拖放事件-html
- JS控件拖放,触发事件
- 【HTML5学习笔记】拖放
- Qt学习笔记-----拖放
- JS学习笔记-事件绑定
- HTML5 的拖放学习笔记
- HTML5学习笔记之拖放
- HTML5 学习笔记11-拖放
- 【js基础】js事件对象学习笔记
- 拖放事件
- 拖放事件
- 拖放事件
- 【js学习笔记-090】---事件处理
- 【js学习笔记-093】------文档加载事件
- 【js学习笔记-094】---------鼠标事件
- 【js学习笔记-095】----鼠标滚轮事件
- 【js学习笔记-097】-------文本事件
- 初试jQuery EasyUI
- 两层 if 防止同步问题
- c++ cin输入格式
- DataGridView之为每行前面添加序号
- 2014ACM集训13级PK赛3-Taxi Fare
- 【js学习笔记-096】----拖放事件
- JSON教程之简介
- 源程序Bwriter.java(从键盘输入一系列字符串,写入到某磁盘文件中)
- Cable Modem工作原理
- C++默认流的输出有效位是6位。
- Android的系统服务
- C++ 输出迭代器
- pig的官方安装
- Why iperf dual traffic in 100Mbps envrionment is much less than 100M?