将所选文本拖动到网页中的 copy/move 吗?
Dragging selected text to copy/move it within a webpage?
我想复制拖动 selected 文本的行为,将其移动到 in/into 网页中的文本输入或文本区域。
我想知道是否有可能(使用鼠标拖动 selection)到:
copy/move select将文本从一个文本输入编辑到另一个
copy/move select 将输入中的文本编辑到另一个位置
- copy/move select 编辑文本从 header/paragraph(即非输入)到 input/textarea.
- 使用 javascript
以编程方式填充拖动的文本
- (奖励:copy/move select 将文本编辑到外部程序)
例如绿色箭头演示了该行为的工作,但是,我想让它在网页内工作(红色箭头)。
到目前为止我找到的所有 google 建议都与拖放 HTML 元素相关,与文本无关。
我正在使用 chrome,但如果它是跨浏览器解决方案,则加分。不要介意解决方案是 HTML、CSS 还是 javascript.
,但对于 visual studio 代码 - 不是网页。
** 更新**
我觉得自己很愚蠢(但我会责怪可用性)。如果我 select 文本,然后 确保鼠标没有移动并单击,然后拖动鼠标 ,点 1-3 按预期工作并拖动 select编辑文本。 (我怀疑我的问题是我不耐烦,在点击拖动之前微妙地移动了鼠标。)
@cjl750 的回答仍然有效。我已将问题更改为关注第 4 点。
因此,在我在 Chrome 中的测试中,任何涉及放入文本输入的内容都由浏览器本地处理(我希望其他浏览器也是如此)。我猜 SO 连接到他们的搜索栏的任何鼠标事件都会干扰从那里拖放到另一个输入,但我测试的任何正常输入都可以正常工作。
这让您只需要处理拖入非输入。
其中有两个部分。首先,您可以使用 window.getSelection()
获取当前突出显示的文本。棘手的部分是,当您将文本拖到某处后,您需要弄清楚光标下的内容。有关如何做到这一点的解决方案的灵感来自 Solution #2 on this answer.
我们想使用 document.caretPositionFromPoint()
,但这是迄今为止仅在 Firefox 中支持的方法的新名称。因此,使用简单的 if/else 语句 from MDN 我们可以涵盖除 IE 之外的所有内容,这就是我在下面的代码片段中所做的。在另一个 link.
中可以找到包含 IE 支持的更完整的解决方案
基本攻略:
- 在
mousedown
,检查突出显示的文本
- 如果我们有一些突出显示的文本,请监听
dragend
事件
- 假设我们停止在文本节点上拖动,使用
document.caretPositionFromPoint()
或 document.caretRangeFromPoint()
检查该节点内的光标位置
- 使用 #3 中的插入符位置以及我们突出显示的文本在其较大字符串中的位置,切分我们的字符串并输出结果
(() => {
document.addEventListener('mouseup', checkForSelection);
let textBeingDragged;
let originalNode
function checkForSelection(event) {
const selection = window.getSelection();
const selectedText = selection.toString();
if (selectedText) {
originalNode = selection.anchorNode.parentNode;
textBeingDragged = selectedText;
document.addEventListener('dragend', handleDragEnd);
}
}
function handleDragEnd(event) {
const charRange = getCharPosition(event);
const elemDrugOver = charRange.endContainer;
if (elemDrugOver.nodeType === 3) {
const offset = charRange.startOffset;
const startText = elemDrugOver.wholeText.slice(0, offset);
const endText = elemDrugOver.wholeText.slice(offset);
elemDrugOver.textContent = `${startText}${textBeingDragged}${endText}`;
const origText = originalNode.textContent;
const indexOfSelection = origText.indexOf(textBeingDragged);
const origStartText = origText.slice(0, indexOfSelection);
const origEndText = origText.slice(offset + textBeingDragged.length);
originalNode.textContent = `${origStartText}${origEndText}`;
textBeingDragged = undefined;
originalNode = undefined;
}
document.removeEventListener('dragend', handleDragEnd);
}
function getCharPosition(event) {
if (document.caretPositionFromPoint) {
return document.caretPositionFromPoint(event.clientX, event.clientY);
} else if (document.caretRangeFromPoint) {
return document.caretRangeFromPoint(event.clientX, event.clientY);
}
return false;
}
})();
<h1>This is a (try to move me) header</h1>
<h2>This is another header</h2>
我会留给你添加任何你想要的增强功能,但这至少应该让你完成 95% 的事情。
我想复制拖动 selected 文本的行为,将其移动到 in/into 网页中的文本输入或文本区域。
我想知道是否有可能(使用鼠标拖动 selection)到:
copy/move select将文本从一个文本输入编辑到另一个copy/move select 将输入中的文本编辑到另一个位置- copy/move select 编辑文本从 header/paragraph(即非输入)到 input/textarea.
- 使用 javascript 以编程方式填充拖动的文本
- (奖励:copy/move select 将文本编辑到外部程序)
例如绿色箭头演示了该行为的工作,但是,我想让它在网页内工作(红色箭头)。
到目前为止我找到的所有 google 建议都与拖放 HTML 元素相关,与文本无关。
我正在使用 chrome,但如果它是跨浏览器解决方案,则加分。不要介意解决方案是 HTML、CSS 还是 javascript.
** 更新**
我觉得自己很愚蠢(但我会责怪可用性)。如果我 select 文本,然后 确保鼠标没有移动并单击,然后拖动鼠标 ,点 1-3 按预期工作并拖动 select编辑文本。 (我怀疑我的问题是我不耐烦,在点击拖动之前微妙地移动了鼠标。)
@cjl750 的回答仍然有效。我已将问题更改为关注第 4 点。
因此,在我在 Chrome 中的测试中,任何涉及放入文本输入的内容都由浏览器本地处理(我希望其他浏览器也是如此)。我猜 SO 连接到他们的搜索栏的任何鼠标事件都会干扰从那里拖放到另一个输入,但我测试的任何正常输入都可以正常工作。
这让您只需要处理拖入非输入。
其中有两个部分。首先,您可以使用 window.getSelection()
获取当前突出显示的文本。棘手的部分是,当您将文本拖到某处后,您需要弄清楚光标下的内容。有关如何做到这一点的解决方案的灵感来自 Solution #2 on this answer.
我们想使用 document.caretPositionFromPoint()
,但这是迄今为止仅在 Firefox 中支持的方法的新名称。因此,使用简单的 if/else 语句 from MDN 我们可以涵盖除 IE 之外的所有内容,这就是我在下面的代码片段中所做的。在另一个 link.
基本攻略:
- 在
mousedown
,检查突出显示的文本 - 如果我们有一些突出显示的文本,请监听
dragend
事件 - 假设我们停止在文本节点上拖动,使用
document.caretPositionFromPoint()
或document.caretRangeFromPoint()
检查该节点内的光标位置
- 使用 #3 中的插入符位置以及我们突出显示的文本在其较大字符串中的位置,切分我们的字符串并输出结果
(() => {
document.addEventListener('mouseup', checkForSelection);
let textBeingDragged;
let originalNode
function checkForSelection(event) {
const selection = window.getSelection();
const selectedText = selection.toString();
if (selectedText) {
originalNode = selection.anchorNode.parentNode;
textBeingDragged = selectedText;
document.addEventListener('dragend', handleDragEnd);
}
}
function handleDragEnd(event) {
const charRange = getCharPosition(event);
const elemDrugOver = charRange.endContainer;
if (elemDrugOver.nodeType === 3) {
const offset = charRange.startOffset;
const startText = elemDrugOver.wholeText.slice(0, offset);
const endText = elemDrugOver.wholeText.slice(offset);
elemDrugOver.textContent = `${startText}${textBeingDragged}${endText}`;
const origText = originalNode.textContent;
const indexOfSelection = origText.indexOf(textBeingDragged);
const origStartText = origText.slice(0, indexOfSelection);
const origEndText = origText.slice(offset + textBeingDragged.length);
originalNode.textContent = `${origStartText}${origEndText}`;
textBeingDragged = undefined;
originalNode = undefined;
}
document.removeEventListener('dragend', handleDragEnd);
}
function getCharPosition(event) {
if (document.caretPositionFromPoint) {
return document.caretPositionFromPoint(event.clientX, event.clientY);
} else if (document.caretRangeFromPoint) {
return document.caretRangeFromPoint(event.clientX, event.clientY);
}
return false;
}
})();
<h1>This is a (try to move me) header</h1>
<h2>This is another header</h2>
我会留给你添加任何你想要的增强功能,但这至少应该让你完成 95% 的事情。