ContentEditable DIV - отключение перетаскивания

Можно ли отключить функцию перетаскивания на элементах, для которых атрибут contentEditable установлен в true.

У меня есть следующая страница HTML.

<!DOCTYPE html>
<html><meta charset="utf-8"><head><title>ContentEditable</title></head>
<body>
    <div contenteditable="true">This is editable content</div>
    <span>This is not editable content</span>
    <img src="bookmark.png" title="Click to do foo" onclick= "foo()">
    </span>
</body>
</html>

Основная проблема, с которой я сталкиваюсь, заключается в том, что можно перетащить изображение в DIV, и оно копируется (вместе с заголовком и обработчиком кликов)

Ответы

Ответ 1

Следующий фрагмент будет препятствовать тому, чтобы ваш div получал перетаскиваемый контент:

jQuery('div').bind('dragover drop', function(event){
    event.preventDefault();
    return false;
});

I (и несколько других) считают этот api странным и контр-интуитивным, но это предотвращает получение контента, содержащего контент, все браузеры, кроме IE8 (включая IE9 beta). На данный момент я не могу помешать IE8 принимать контент-контент.

Я обновлю этот ответ, если найду способ сделать это.

Ответ 2

Интересно, я не знаю интерфейса перетаскивания достаточно хорошо, чтобы быть уверенным, но похоже, что здесь есть какая-то ошибка. Я немного изменил ваш код, чтобы добавить обработчик события drop на редактируемый div:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ContentEditable</title>
</head>
<body>
    <div contenteditable="true" ondrop="window.alert('dropped!');return false;">This is editable content</div>
    <span>This is not editable content</span>
    <span>
        <img src="bookmark.png" title="Click to do foo" onclick="foo()">
    </span>
</body>
</html>

Я тестирую в Firefox 3.7 alpha: если я перетаскиваю изображение на середину текста, событие срабатывает, я получаю предупреждение, а return false останавливает удаляемое изображение. Однако, если я перейду к началу текста, событие не запускается, но изображение будет вставлено внутри div. Имейте в виду, что в Firefox 3.6 и Chromium 6.0 событие вообще не срабатывает, так что либо я полностью неправильно понял, как он работает, либо ничто из этого не работает достаточно хорошо, чтобы полагаться на него.

Ответ 3

В Chrome и Firefox вам нужно отменить событие ondragover для события ondrag. Я также рекомендовал бы отменить события ondragenter и ondragleave.

http://jsbin.com/itugu/2

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ContentEditable</title>
</head>
<body>
    <div contenteditable="true" ondragenter="return false;" ondragleave="return false;" ondragover="return false;" ondrop="window.alert('dropped!');return false;">This is editable content</div>
    <span>This is not editable content</span>
    <span>
        <img src="bookmark.png" title="Click to do foo" onclick="foo()">
    </span>
</body>
</html>

Такое поведение не является ошибкой; в спецификации HTML5 говорится, что ondragover должен быть отменен для ondrag для запуска. Это не имеет никакого смысла делать это таким образом, поэтому я надеюсь, что они скоро изменят его. См. http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html

Ответ 4

Я обнаружил, что мне нужно установить dropEffect как "none" для dragenter и dragover, чтобы отклонить перетаскивание. Если вы не привязываете dragenter, курсор будет мерцать при перетаскивании элемента, поэтому код будет выглядеть следующим образом:

<div contenteditable="true" ondragenter="event.preventDefault(); event.dataTransfer.dropEffect = 'none'" ondragover="event.preventDefault(); event.dataTransfer.dropEffect = 'none'">This is editable content</div>
<span>This is not editable content</span>
<img src="bookmark.png" title="Click to do foo" onclick= "foo()">

Ответ 5

Можно ли отключить все события mousedown на изображении?

$('img').on('mousedown', function(){
    return false;
});