你可能才到事情没那么简单。在Opera和Safari里面keydown事件只能触发一次,所以当用户按下键之后,元素移动一次之后就不动了。在这些浏览器中我们需要keypress。
所以理想情况下,我们使用keypress,如果不支持就是用keydown。但是怎么切换事件呢?你又怎么知道keypress在这个时候不能用呢?
我的解决办法就是给keypress事件设置一个事件处理程序。如果这个程序执行了说明支持keypress,我们就可以安全的切换了。
startDragKeys函数用来设置keydown和keypress事件:
复制代码 代码如下:
addEventSimple(document,'keydown',dragDrop.dragKeys);
addEventSimple(document,'keypress',dragDrop.switchKeyEvents);
首先keydown触发完成拖拽的dragKeys函数。这是第一个触发的事件,而且元素总会移动。然后我们做其他的话,那么元素在Opera和Safari1.3里面移动一次以后就会停止。
这就是为什么我们还需要keypress。第一个keypress事件会触发switchKeyEvents函数,这个函数会调整事件处理程序:
复制代码 代码如下:
switchKeyEvents: function () {
removeEventSimple(document,'keydown',dragDrop.dragKeys);
removeEventSimple(document,'keypress',dragDrop.switchKeyEvents);
addEventSimple(document,'keypress',dragDrop.dragKeys);
},
他会先删除掉原来的事件处理程序,然后将keypress设置为触发dragKeys。因为这个函数只会在支持他的浏览器里面执行,所以我们只在这些浏览器里面将keydown改为keypress。
初始键盘代码
当用户点击了连接激活了元素,那么就会调用startDragKeys。
复制代码 代码如下:
startDragKeys: function () {
dragDrop.startDrag(this.relatedElement);
dragDrop.dXKeys = dragDrop.dYKeys = 0;
addEventSimple(document,'keydown',dragDrop.dragKeys);
addEventSimple(document,'keypress',dragDrop.switchKeyEvents);
this.blur();
return false;
},
首先会调用我们之前讨论过的startDrag函数。他会给这个函数传递relatedElement,也就是要拖拽的元素。
然后将dXKeys和dYKeys设置为0。这些变量用来跟踪元素的位移。
然后设置事件处理程序,上面已经讨论过了。
然后移除刚才点击的链接的焦点。我这样做是因为Enter键会释放元素,但是如果不移除焦点,当用户点击了Enter键之后,元素被释放,但是链接却再次被Enter点击,又成了可拖动的模式。如果我们移除焦点,那么问题就不存在了。
最后返回false来阻止默认动作。
通过键盘拖拽
dragKeys负责键盘拖拽:
复制代码 代码如下:
dragKeys: function(e) {
var evt = e || window.event;
var key = evt.keyCode;
我们首先读取键盘的键值。
然后我们使用switch语句来决定我们怎么做。这部分的目的是更新dXKeys和dYKeys的值,就可以通过设置元素的位置来移动元素了。
复制代码 代码如下:
switch (key) {
case 37: // left
case 63234:
dragDrop.dXKeys -= dragDrop.keySpeed;
break;
case 38: // up
case 63232:
dragDrop.dYKeys -= dragDrop.keySpeed;
break;
case 39: // right
case 63235:
dragDrop.dXKeys += dragDrop.keySpeed;
break;
case 40: // down
case 63233:
dragDrop.dYKeys += dragDrop.keySpeed;
break;
作者通过设置keySpeed来确定每次移动的像素大小。当用户点击左方向键,就减去keySpeed。
这个代码包含63232-63235的情况。因为Safari1.3没有使用标准的37-40的方向键的键值(Safari 3已经支持了)。
复制代码 代码如下: