允许在 HTML 5 可拖动子元素上选择文本
Posted
技术标签:
【中文标题】允许在 HTML 5 可拖动子元素上选择文本【英文标题】:Allow select text on a HTML 5 draggable child element 【发布时间】:2017-12-04 22:21:31 【问题描述】:有一个包含可拖动行的表格,其中每一行都是draggable=true
,用户如何仍然能够从列中选择文本?
<table>
<thead>..</thead>
<tbody>
..
<tr draggable="true">
<td>..</td>
<td>Cool text but you can't select me</td>
<td>..</td>
</tr>
..
</tbody>
</table>
另一个简单的例子 (https://codepen.io/anon/pen/qjoBXV)
div
padding: 20px;
margin: 20px;
background: #eee;
.all-copy p
-webkit-user-select: all; /* Chrome all / Safari all */
-moz-user-select: all; /* Firefox all */
-ms-user-select: all; /* IE 10+ */
user-select: all; /* Likely future */
<div class="all-copy" draggable="true">
<p>Select me as text</p>
</div>
【问题讨论】:
不知道是不是只有Mac浏览器,不过还是可以通过右键元素选择文字。 另外,我主观上认为最好有一个清晰且视觉上区分的元素来处理拖放,而不是在您还需要选择文本时允许拖动整行。可拖动区域至少需要与可选文本不同的光标。 是的,不确定在 Windows 中运行的浏览器。 Mozilla 文档说按 Alt 浏览器应该允许选择文本,但从来没有奏效。同意处理程序。我只是遵循规范。 【参考方案1】:我们需要做两件事。
一件事是限制拖动事件仅在指定区域触发,例如拖动手柄。
另外一点是我们只设置了content类的div上的文字可以选择。我们这样做的原因是已经设置为可拖动的元素,在哪个浏览器上会添加一个默认规则user-select: none。
const itemEl = document.querySelector('.item');
const handleEl = document.querySelector('.handle');
let mouseDownEl;
itemEl.onmousedown = function(evt)
mouseDownEl = evt.target;
itemEl.ondragstart = function(evt)
// only the handle div can be picked up to trigger the drag event
if (mouseDownEl.matches('.handle'))
// ...code
else
evt.preventDefault();
.item
width: 70px;
border: 1px solid black;
text-align: center;
.content
border-top: 1px solid gray;
user-select: text;
<div class="item" draggable="true">
<div class='handle'>handle</div>
<div class='content'>content</div>
</div>
【讨论】:
【参考方案2】:我可以看到这项工作的唯一方法是实际检查哪个元素触发了事件
if (e.target === this) ...
堆栈sn-p
(function (elem2drag)
var x_pos = 0, y_pos = 0, x_elem = 0, y_elem = 0;
document.querySelector('#draggable').addEventListener('mousemove', function(e)
x_pos = e.pageX;
y_pos = e.pageY;
if (elem2drag !== null)
elem2drag.style.left = (x_pos - x_elem) + 'px';
elem2drag.style.top = (y_pos - y_elem) + 'px';
)
document.querySelector('#draggable').addEventListener('mousedown', function(e)
if (e.target === this)
elem2drag = this;
x_elem = x_pos - elem2drag.offsetLeft;
y_elem = y_pos - elem2drag.offsetTop;
return false;
)
document.querySelector('#draggable').addEventListener('mouseup', function(e)
elem2drag = null;
)
)(null);
#draggable
display: inline-block;
background: lightgray;
padding:15px;
cursor:move;
position:relative;
span
background: white;
line-height: 25px;
cursor:auto;
<div id="draggable">
<span>Select me as text will work<br>when the mouse is over the text</span>
</div>
由于Firefox has issue with draggable="true"
,我使用了不同的拖动方式。
【讨论】:
以上是关于允许在 HTML 5 可拖动子元素上选择文本的主要内容,如果未能解决你的问题,请参考以下文章