Предотвратите событие перетаскивания, чтобы помешать входным элементам в Firefox, используя перетаскивание HTML5

Кажется, что входной элемент теряет много функциональности, когда помещается в элемент с draggable = "true". Это похоже на firefox.

Смотрите мой jsfiddle: http://jsfiddle.net/WC9Fe/3/

Html:

<div id="drag" draggable="true">
    Drag this div <br />
    <input id="message" type="text" />
</div>
<div id="drop">
    Drop area
</div>

JS:

$('#drag').on('dragstart', function(e){
    e.originalEvent.dataTransfer.setData('Text', $('#message').val());
    e.originalEvent.dataTransfer.effectAllowed = 'move';
});

var drop = $('#drop');
drop.on('dragover', function(e){
    e.preventDefault();
});
drop.on('dragenter', function(e){
    e.preventDefault();
});
drop.on('drop', function(e){
    alert('Target succesfully dropped: ' + e.originalEvent.dataTransfer.getData('Text'));
    e.preventDefault();
});

Теперь попробуйте выбрать текст во входном файле, используя firefox. Кажется невозможным. Попробуйте то же самое в IE/Chrome. Кажется, все работает нормально.

Ответ 1

Насколько я знаю, это известная ошибка в FF. Быстрое (и "грязное" обходное решение) было бы удалить атрибут draggable при вводе текста focus, добавить его снова в текстовое событие blur и отключить выбор текста на #drag div, чтобы включить перетаскивание, как только вы щелкнув вне сфокусированного ввода (нажав прямо на #div).

Обновлен скрипт здесь.

Пример кода:

JS:

$('#message')
    .on('focus', function(e) {
        $(this).closest('#drag').attr("draggable", false);
    })
    .on('blur', function(e) {
        $(this).closest('#drag').attr("draggable", true);
    });

CSS

.disable-selection {
    /* event if these are not necessary, let just add them */
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;

    /* this will add drag availability once you clicked the 
       #drag div while you're focusing #message div */
    -moz-user-select: none;
}

Надеюсь, это поможет вам.

Ответ 2

См. Firefox дефект.

В качестве альтернативы, установка draggable = "false" на входном событии фокуса и замена на draggable = "true" на событие размытия ввода срабатывает.

См. jsfiddle для примера без каких-либо фреймворков.

HTML:

<div draggable="true" id="draggableDiv">
    <textarea onfocus="onFocus();" onblur="onBlur();">Inside draggable (FIXED)</textarea>
</div>

JS:

onFocus= function(e) {
    document.getElementById("draggableDiv").setAttribute("draggable", "false");
}
onBlur= function(e) {
    document.getElementById("draggableDiv").setAttribute("draggable", "true");
}

Ответ 3

Я использовал функции onMouseEnter и onMouseLeave в текстовом поле, чтобы установить div, перетаскиваемый, только когда мышь находится вне текстового поля.

Я сделал это, потому что мне нужно было сосредоточиться, чтобы оставаться в полях редактирования, в то время как перетаскивание и перетаскивание не запускает событие фокусировки.

Ответ 4

Я также обнаружил, что использование onmouseenter и onmouseleave для переключения атрибута draggable работает лучше, потому что он помещает курсор в поле ввода, где вы на самом деле нажимаете. При использовании onfocus/onblur курсор всегда идет в начало или конец текста, даже если вы нажимаете посередине.