js中设置div可拖动后,内部input无法输入怎么办?

js中设置div可拖动后,内部input无法输入怎么办?
最新回答
我污但不色

2021-09-24 23:47:43

在JS中设置div可拖动后,若内部input无法输入,可通过判断鼠标点击的标签名来阻止拖动事件对input的拦截,确保其可输入。 具体原因及解决方案如下:

  • 问题原因:当为div设置拖动功能时,通常通过监听mousedown、mousemove和mouseup事件实现。但拖动逻辑会拦截鼠标事件,导致点击div内部的input时,事件被拖动逻辑处理,input无法触发焦点获取和输入操作。

  • 核心解决思路:在mousedown事件中判断触发事件的元素是否为input。若是,则阻止拖动逻辑的执行;若不是,则正常执行拖动操作。

  • 具体实现步骤

    获取触发元素:使用document.elementFromPoint(x, y)方法,根据鼠标点击的坐标获取对应的DOM元素。该方法返回文档中位于指定坐标处的最顶层元素。

    判断元素类型:检查获取到的元素的标签名是否为input(需转换为小写以兼容不同大小写写法)。

    阻止拖动逻辑:若元素为input,通过return false终止当前mousedown事件的处理,避免触发后续的拖动逻辑。

    正常执行拖动:若元素非input,则调用拖动相关函数(如getObject(this, e || event))继续处理拖动操作。

  • 代码示例

document.getElementById("log_window").onmousedown = function(e) { // 获取鼠标点击位置的元素 var obj = document.elementFromPoint(e.clientX, e.clientY); // 判断是否为input元素 if (obj.tagName.toLowerCase() === 'input') { return false; // 阻止拖动逻辑 } // 非input元素时执行拖动操作 getObject(this, e || event);};
  • 注意事项

    事件对象兼容性:代码中e || event用于兼容不同浏览器的事件对象传递方式。现代浏览器通常直接使用参数e,但部分旧版浏览器(如IE)需通过全局event对象获取。

    动态元素处理:若div或input是动态生成的,需确保在元素添加到DOM后重新绑定事件监听器,或使用事件委托机制(如将事件绑定到父元素,通过事件冒泡处理)。

    其他可输入元素:若div内还包含其他可输入元素(如textarea、select),需扩展判断条件,例如:

if (['input', 'textarea', 'select'].includes(obj.tagName.toLowerCase())) { return false;}- 性能优化:`document.elementFromPoint`在复杂DOM结构中可能影响性能,若拖动逻辑频繁触发,建议优化为通过事件目标(`e.target`)直接判断,但需注意事件冒泡可能导致`e.target`为子元素而非直接点击的input(此时需结合`closest`方法或手动遍历父节点判断)。
  • 替代方案:若上述方法仍无法满足需求,可考虑以下两种方式:

    调整拖动区域:将拖动操作绑定到div内特定区域(如标题栏),而非整个div,从而避免与input冲突。

    使用现成库:引入支持拖动与内部元素交互的库(如interact.js、draggable等),这些库通常已处理此类事件冲突问题。

通过以上方法,可有效解决div拖动导致内部input无法输入的问题,同时保持拖动功能的完整性。