24 янв. 2013 г.

Поддержка HTML5 draggable и contenteditable браузерами

На словах всё прекрасно (поддерживается всеми современными версиями браузеров, включая IE9), а на деле при попытке использовать эти возможности HTML5 даже в простеньком приложении сразу натыкаешься на, мягко говоря, "особенности реализации".

Простой пример - ведение списка заданий в браузере. Карточки заданий визуально находятся в разных списках (новая, в работе, выполнена, закрыта), их можно перетаскивать (draggable) и редактировать (contenteditable). Вроде ничего сложного, но:

  • IE9 и ниже без дополнительных телодвижений позволяет перетаскивать только ссылки и картинки (но предоставляет проприетарный метод dragDrop() для всех элементов). Для перетаскивания, скажем, DIV надо постараться:
    if (typeof (new Element("div")).dragDrop === "function") {
      document.on("selectstart", "[draggable]", function(event, element) {
        event.stop();
        element.dragDrop();
      });
    }
  • почти во всех браузерах для работы drag&drop надо обязательно вешать обработчики на события dragover, dragenter только для того, чтобы вызвать event.stop(); (прекратить обработку события браузером), иначе никакого drag&drop не получится
  • Chrome и Chromium включая билды 26 версии не позволяют редактировать contenteditable элемент, который находится внутри draggable. Описание ошибки и статья на stackoverflow. Решение - выключать draggable при попытке редактирования, и включать обратно после редактирования, минимальный пример:
    <div draggable="true">
      <span contenteditable="true" onfocus="this.parentNode.draggable = false;" onblur="this.parentNode.draggable = true;">text</span>
    </div>
  • Firefox 18.0.1 при клике на contenteditable элемент внутри draggable всегда ставит курсор в начало текста в элементе contenteditable. В простом contenteditable и в IE9/Opera курсор ставится на место, в котором был клик мыши (куда кликнули - там и курсор).

Комментариев нет:

Отправить комментарий