8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
元素的拖放(Drag and Drop)在Web页面上也是一个常见的特性,即抓取一个对象拖动并将其放到另一个位置;HTML5将其标准化:任何页面元素都可以被拖动。
HTML5拖放的浏览器支持情况如下:APIChromeIEFirefoxSafariOperaDrag and Drop4.09.03.56.012.0
draggable 属性
draggable 属性是HTML5新增的一个属性,指定一个元素是否可以被拖动,所有HTML元素都可以设置该属性;draggable 属性可以设置的值如下所示:true:元素可以拖动
false:元素不可以拖动
auto:使用浏览器默认行为默认情况下,图片和链接两种元素是可以拖动的
下面两个段落中的第二个将 draggable 属性设置为true后,可以看到该段落可以拖动了,鼠标移到上面后指针也不再变化,只是好像不能再选择文字了。
不可拖动的段落
可以拖动的段落
拖放相关事件
在元素的拖放过程会触发一系列事件,我们正是使用这些事件来响应拖放操作的;这些事件可以分为两类:拖动元素(拖放源)事件和放置元素(拖放目标)事件。
被拖动元素上触发的事件dragstart:用户开始拖动一个元素时触发
drag:元素正在被拖动时触发
dragend:用户结束元素拖动时触发
触发dragstart事件后,其他元素的鼠标事件诸如 mousemove、mouseover、mouseout 等事件均不会被触发了。注意,拖动元素时,drag事件每350毫秒触发一次
放置元素上触发的事件dragenter:当被拖动元素进入目标元素时触发
dragover:被拖动元素在目标元素上移动时触发
dragleave:被拖动元素离开目标元素时触发
drop:被拖动元素放在目标元素时触发(在目标元素上松开鼠标)
dragover事件是被拖拽元素在目标元素上移动一段时间后才触发,因此该事件并不会与dragenter事件一起被触发。
从上面的解释可以了解到,一个拖放过程应该是这样的:dragstart –> dragenter –> dragover –> drop –> dragend
DataTransfer 对象
DataTransfer 对象用于配置拖拽行为效果,并且在拖拽过程的各事件间传递数据,传递的数据类型被限定为字符串和文件类型;DataTransfer 对象作为一个属性存储在拖拽事件对象(DragEvent)中,DragEvent继承自MouseEvent,其实就比MouseEvent多了一个 DataTransfer 对象属性。
DataTransfer的属性
effectAllowed
effectAllowed 属性用于设置被拖拽元素可执行的操作。
该属性可以设置的值如下:可用值说明copy限定dropEffect的属性值为copy,否则会鼠标指针为禁止样式
link限定dropEffect的属性值为link,否则会鼠标指针为禁止样式
move限定dropEffect的属性值为move,否则会鼠标指针为禁止样式
copyLink限定dropEffect的属性值为copy和link,否则会鼠标指针为禁止样式
copyMove限定dropEffect的属性值为copy和move,否则会鼠标指针为禁止样式
linkMove限定dropEffect的属性值为link和move,否则会鼠标指针为禁止样式
all允许dropEffect的属性值为任意值
none鼠标指针一直为禁止样式,不管dropEffect的属性值是什么
uninitialized没有限定dropEffect属性的值,效果和 all 一样仅能在 dragstart 事件中设置该属性,其他事件中设置均无效。
dropEffect
dropEffect 属性用于设置目标元素将执行的操作,若属性值属于 effectAllowed 范围内,则鼠标指针将显示对应的指针样式,否则则显示禁止的指针样式。
该属性的取值及意义如下:可用值说明copy被拖拽元素将被复制到目标元素内,若属于 effectAllowed 范围内时,则鼠标指针显示复制的样式,否则则显示禁止的指针样式。
link被拖拽元素将以超链接的形式打开资源,若属于 effectAllowed 范围内时,则鼠标指针显示超链接的样式,否则则显示禁止的指针样式。
move被拖拽元素将被移动到目标元素内,若属于 effectAllowed 范围内时,则鼠标指针显示移动的样式,否则则显示禁止的指针样式。
none被拖拽元素不能在目标元素上作任何操作,一直显示禁止的指针样式。除了文本框外其他元素的默认值均为none仅能在 dragover 事件中设置该属性值,其他事件中设置均无效
当显示禁止的指针样式时,将无法触发目标元素的 drop 事件。
items
items 属性数据类型为 DataTransferItemList,存储 DataTransfer 对象中所有的数据项。目前只有Chrome浏览器支持该属性。
DataTransferItemList 是个类数组的类型,可以使用索引引用数据项,也有length属性;另外还有clear()和add()方法。
files
files 属性数据类型为FileList
types
types 属性数据类型为DOMStringList,存储DataTransfer对象中所有数据项的数据类型。仅能在dragenter,dragover和drop中获取该属性
DataTransfer的方法
addElement()
void addElement({HTMLElement} element) 方法用于添加一起跟随鼠标移动的元素。
addElement() 方法仅在 dragstart 事件中可以调用。
setDragImage()
void setDragImage({Element} image, {long} x, {long} y) 方法用于设置拖动时跟随鼠标移动的图片,用来替代默认的元素;若image参数不是图片元素则会将元素临时转换为图片;x和y分别用于设置图标与鼠标指针在水平方向和垂直方向上的距离。
setDragImage() 方法仅在 dragstart 事件中可以调用。image参数必须在DOM树中,而且在渲染树中为有效元素,即display不为none,否则会导致没有元素跟随鼠标移动
setData()
boolean setData({DOMString} format, {DOMString} data) 方法将指定格式的数据赋值给dataTransfer或clipboardData,format值范围为URL、Text(或text)和各种MIME类型,其实Text会被自动映射为text/plain,URL会被自动映射为text/uri-list类型。
setData() 方法仅在 dragstart 事件中可以调用。当没有填写第二个入参时,则会根据format来删除相应的数据项
getData()
DOMString getData({DOMString} format) 方法从DataTransfer对象或ClipboardData对象中获取指定格式的数据。
clearData()
void clearData([{DOMString} format]) 方法从DataTransfer对象或ClipboardData对象中删除指定格式或全部kind值为string的数据。
仅在 dragstart 事件中调用,在其他事件中调用会抛InvalidStateError。
数据存储模式Read/Write(读写)模式:dragstart 事件为该模式,可读写数据
Read-only(只读)模式:在 drop 事件为该模式,仅能读取数据
Protected(保护)模式:其他事件为该模式,仅能枚举数据
示例
简单的拖放
下面是一个简单的元素拖放示例,仅仅是将一个p元素拖到div元素中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20(function (){
let p = document.getElementById('drag-p');
let div = document.getElementById('div-1');
p.addEventListener('dragstart', function (e){
e.dataTransfer.setData('text', e.target.id);
});
div.addEventListener('dragover', function(e){
e.preventDefault();
});
div.addEventListener('drop', function (e){
e.preventDefault();
let id = e.dataTransfer.getData('text');
let dragEl = document.getElementById(id);
if (dragEl instanceof Node) {
dragEl.removeAttribute('draggable');
dragEl.innerHTML = '我不允许再拖动了噢';
e.target.appendChild(dragEl);
}
});
})();
把我拖到下面方框试试
首先给p元素添加一个 dragstart 事件监听,在监听函数中向 DataTransfer 对象设置了Text类型的数据,值是被拖动元素的ID。
接下来给目标元素添加了 dragover 事件监听,默认情况下,无法将数据/元素放置到其他元素中,如果设置为允许放置,我们必须阻止对元素的默认处理方式,也就是调用 DragEvent 事件对象的 preventDefault() 方法。
最后又给目标元素设置了 drop 事件监听,用来响应拖动元素放下的动作;调用事件对象的 preventDefault() 方法来避免浏览器对数据的默认处理(drop 事件的默认行为是以链接形式打开);接着获取存在 DataTransfer 对象中的数据(拖动元素的ID),然后将该元素追加到目标元素中。
复制元素
接下来再写一个示例,也很简单,与上一个示例区别就是这次不是移动元素,而是将元素复制一份加入目标元素,拖动过程中注意看鼠标指针的变化。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25(function (){
let p = document.getElementById('drag-p2');
let div = document.getElementById('div-2');
p.addEventListener('dragstart', function (e){
e.dataTransfer.setData('text', e.target.id);
e.dataTransfer.effectAllowed = 'copyMove';
});
div.addEventListener('dragover', function(e){
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
div.addEventListener('drop', function (e){
e.preventDefault();
let id = e.dataTransfer.getData('text');
let dragEl = document.getElementById(id);
if (dragEl instanceof Node) {
let cloneEl = dragEl.cloneNode(true);
cloneEl.removeAttribute('draggable');
cloneEl.innerHTML = '我是不允许拖动的噢';
e.target.appendChild(cloneEl);
}
});
})();
把我拖到下面方框试试
代码与上一个示例相差无几,主要区别在于以下两点:dragstart 事件监听函数中将 DataTransfer 对象的 effectAllowed 属性设置为 copyMove;
dragover 事件监听函数中将 DataTransfer 对象的 dropEffect 属性设置为copy;
这样就可以在拖拽元素拖到目标元素上时改变鼠标指针,最后在 drop 事件监听函数中复制一份拖拽元素并加入目标元素中。