父元素进行拖拽,子元素 input 框无法获取焦点,还有一种情况是定位到拖拽元素的上边的 input 框也无法获取焦点
1、对于点击事件,是按照 mousedown -> mouseup -> click 这个顺序走的
2、对于focus 事件, 是按照 mousedown -> focus -> mouseup -> click 顺序。 所以在 mousedown 的时候是获取不到 focus 事件的
为了大家能看懂前后的代码贴出来一些简单封装的方法
// 绑定事件 兼容处理
export const addEvent = (nodeId, eventType, callback) => {
if (nodeId.addEventListener){
nodeId.addEventListener(eventType, callback, false);
}else {
nodeId.attachEvent('on' + eventType, callback);
}
}
// 判断 event 事件对象 不存在
export const prevent = (event) => {
let e = event || window.event;
if (e.preventDefault) {
e.preventDefault();
}
return e;
}
复制代码
在使用 mousedowm 事件的时候 有event 事件对象,我们能通过 event.target 能获取当前目标对象,如果 enent.target.nodeName 是 INPUT 的时候我们手动让input获取焦点,
我实现的功能是拖动父元素让子元素移动,因为还有缩放功能不能直接添加到元素上因为会缩放的很小shi时候,滚轮和拖拽 都不能获取到事件了。
打个比方: 把拖拽 和 缩放事件放在body 上,但是移动和缩放的是子元素。
/*拖拽功能*/
export default (nodeId) => {
var oParent = nodeId.parentNode;
addEvent(oParent, 'mousedown', function(ev) {
var oEvent = prevent(ev);
if(oEvent.target.nodeName.toLowerCase() === 'input'){ //如果目标元素是input则跳出滑动事件
oEvent.target.focus()
return;
}
......
// 如果 目标元素是 input 的话 下边的逻辑就不会处理
})
}
复制代码
还有一个重点是关于内存消耗的,我们都知道每当拖动一次就会注册 一次 mousedowm 事件,这样就会造成内存的泄露,所以在mouseup 的时候需要删除事件的这里就不重点说了。
removeEvent(oParent, 'mousemove', startMove);
removeEvent(oParent, 'mouseup', endMove);
复制代码