使用 HTML5 拖放防止拖动事件干扰 Firefox 中的输入元素
Posted
技术标签:
【中文标题】使用 HTML5 拖放防止拖动事件干扰 Firefox 中的输入元素【英文标题】:Prevent drag event to interfere with input elements in Firefox using HTML5 drag/drop 【发布时间】:2014-03-07 23:17:39 【问题描述】:似乎输入元素在放入具有可拖动=“真”的元素时失去了很多功能。这似乎只发生在 Firefox 中。
查看我的 jsfiddle: http://jsfiddle.net/WC9Fe/3/
html:
<div id="drag" draggable="true">
Drag this div <br />
<input id="message" type="text" />
</div>
<div id="drop">
Drop area
</div>
JS:
$('#drag').on('dragstart', function(e)
e.originalEvent.dataTransfer.setData('Text', $('#message').val());
e.originalEvent.dataTransfer.effectAllowed = 'move';
);
var drop = $('#drop');
drop.on('dragover', function(e)
e.preventDefault();
);
drop.on('dragenter', function(e)
e.preventDefault();
);
drop.on('drop', function(e)
alert('Target succesfully dropped: ' + e.originalEvent.dataTransfer.getData('Text'));
e.preventDefault();
);
现在尝试使用 firefox 在输入中选择文本。似乎不可能。在 IE/Chrome 中尝试相同的操作。似乎工作得很好。
【问题讨论】:
在 IE 中也观察到此问题...确切地说是 IE 11.0.9600.. 【参考方案1】:据我所知,这是 FF 中的一个已知错误。一个快速(和“dirty”的解决方法)是删除文本输入 focus
事件上的 draggable
属性,在文本输入 blur
事件上再次添加它,并在 # 上禁用文本选择拖动 div 以在您单击焦点输入外部时启用拖动(直接单击#div)。
更新了小提琴here。
示例代码:
JS:
$('#message')
.on('focus', function(e)
$(this).closest('#drag').attr("draggable", false);
)
.on('blur', function(e)
$(this).closest('#drag').attr("draggable", true);
);
CSS:
.disable-selection
/* event if these are not necessary, let's just add them */
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
/* this will add drag availability once you clicked the
#drag div while you're focusing #message div */
-moz-user-select: none;
希望对你有帮助。
【讨论】:
谢谢!确实是一个肮脏的解决方法......至于现在:我从可拖动区域中删除了输入元素,因为我没有在所有浏览器中达到预期的效果(IE8仍然是一个问题)。你会建议不要使用 html5 拖放,而是使用 JQuery UI 拖放吗? 您可以通过以下方式找到更多信息:advantages of html5 drag and drop over jquery ui drag and drop 和 html5 vs jquery ui drag and drop。如果您需要针对各种浏览器(也包括旧版浏览器),如果您不想头疼并且时间紧迫,我建议您使用 jQuery UI 拖放。【参考方案2】:见火狐defect。
作为替代方法,在输入焦点事件上设置 draggable="false" 并在输入模糊事件上替换回 draggable="true"。
请参阅jsfiddle 了解没有任何框架的示例。
HTML:
<div draggable="true" id="draggableDiv">
<textarea onfocus="onFocus();" onblur="onBlur();">Inside draggable (FIXED)</textarea>
</div>
JS:
onFocus= function(e)
document.getElementById("draggableDiv").setAttribute("draggable", "false");
onBlur= function(e)
document.getElementById("draggableDiv").setAttribute("draggable", "true");
【讨论】:
【参考方案3】:我在 textarea 上使用了 onMouseEnter 和 onMouseLeave 函数来设置只有当鼠标在 textarea 之外时 div 才可拖动。
我这样做是因为我需要焦点保持在编辑字段中,而拖动和拖动本身不会触发焦点事件。
【讨论】:
【参考方案4】:我还发现使用 onmouseenter 和 onmouseleave 来切换可拖动属性效果更好,因为它将光标放在您实际单击的输入框中。使用 onfocus/onblur 时,即使单击中间,光标也会始终移动到文本的开头或结尾。
【讨论】:
【参考方案5】:如果你和我一样遇到这个问题,并且正在使用 Sortable.js,你可以使用filter
选项来指定不会触发拖动的元素,从而让输入正常运行。
JQuery:
$('#my-sortable').sortable(
filter: ".my-text-input", // Or whatever class you specify
preventOnFilter: false // Allow the input to operate normally
);
您还可以从此处的 Sortable.js 选项列表中找到此信息: https://github.com/SortableJS/sortablejs
【讨论】:
以上是关于使用 HTML5 拖放防止拖动事件干扰 Firefox 中的输入元素的主要内容,如果未能解决你的问题,请参考以下文章