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

时间:2017-07-21 10:54:26

标签: javascript input drag undo

我有两个文本INPUT元素A和B.

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

说“A”包含“快速棕色狐狸”,用户突出显示“狐狸”这个词并将其拖动到“B”。默认情况下,框“A”现在包含“快速棕色”,但我希望它仍然可以说“快速棕色狐狸”。

我不希望'A'只读。

1 个答案:

答案 0 :(得分:1)

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) })
}