将文本从一个 INPUT 拖动到另一个 INPUT,而不从源 INPUT 中删除文本

Drag text from one INPUT to another INPUT without text being removed from source INPUT

我有两个文本输入元素 A 和 B。

我希望用户能够 select 将 A 中的部分或全部文本拖动到 B,但文本不会从 A 中消失。

假设 'A' 包含 'quick brown fox',用户突出显示单词 'fox' 并将其拖到 'B'。默认框 'A' 现在包含 'quick brown ',但我希望它仍然显示 'quick brown fox'。

我不想 'A' 是只读的。

function preventDragNDropChangesOn(inputElement) {
  let previousValue = inputElement.value
  let isDragged = false
  let wasDropped = false

  /*
  * event order:
  *   dragstart (prepare for possible text cutting)
  *   drop (input text was not cut out yet at this point, save it to revert it later)
  *   change (input text is already cut out at this point - revert it to the previous value)
  *   dragend (set variables to initial state)
  */

  inputElement.addEventListener('dragstart', () => isDragged = true)
  document.body.addEventListener('drop', () =>
    (wasDropped = isDragged) && (previousValue = inputElement.value))
  inputElement.addEventListener('change', (e) =>
    isDragged && wasDropped && (e.target.value = previousValue))
  inputElement.addEventListener('dragend', () => isDragged = wasDropped = false)
}

const inputElement = document.querySelector(".js-controlled-input")

preventDragNDropChangesOn(inputElement)

function preventDragNDropChangesOn(inputElement) {
  let previousValue = inputElement.value
  let isDragged = false
  let wasDropped = false
  let shouldRevertChanges = () => isDragged && wasDropped
  
  document.body.addEventListener('drop', () => wasDropped = isDragged)
  inputElement.addEventListener('dragstart', () => isDragged = true)
  inputElement.addEventListener('dragend', () => (isDragged = false) || (wasDropped = false))
  inputElement.addEventListener('input', (e) =>
    shouldRevertChanges()
    ? (e.target.value = previousValue)
    : (previousValue = e.target.value) 
  )
}
<input class="js-controlled-input" value="quick brown fox"/>
<input class="js-target"/>

https://jsfiddle.net/91o9mpaz/4/


IE11兼容解决方案:

function preventDragNDropChangesOn(inputElement) {
  let previousValue = inputElement.value
  inputElement.addEventListener('dragstart', function () { previousValue = inputElement.value })
  inputElement.addEventListener('dragend', function () { setTimeout(function() {inputElement.value = previousValue }, 1) })
}