Итак, в моих тестах в Chrome все, что связано с вводом в текстовый ввод, обрабатывается непосредственно браузером (и я ожидаю, что то же самое для других браузеров). Я предполагаю, что любые события мыши, которые SO подключил к своей панели поиска, мешают перетаскиванию оттуда на другой вход, но любой нормальный вход, который я тестировал, работает нормально. -входы.
Есть две части этого. Во-первых, вы можете получить текущий выделенный текст с помощью window.getSelection()
. Сложность в том, что вам нужно выяснить, что находится под вашим курсором, когда вы закончите перетаскивать этот текст куда-нибудь. Решение о том, как это сделать, было взято из Решение № 2 для этого ответа .
Мы хотим использовать document.caretPositionFromPoint()
, но это новое имя для метода, который так поддерживается только в Firefox. Поэтому, используя простое выражение if / else из MDN , мы можем охватить все, кроме IE, что я и делаю в приведенном ниже фрагменте. Более полное решение, включающее поддержку IE, можно найти в другой ссылке. Стратегия
Basi c:
- на
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% пути как минимум.