Дисплей DOM node в нескольких местах без клонирования/копирования

Отказ от ответственности:

Я слишком часто взлетел здесь, пытаясь обеспечить достаточный контекст, чтобы упредить все вопросы, которые у вас есть у меня. Не пугайтесь по длине этого вопроса: многое из того, что я написал, очень скудно (особенно потенциальные решения, которые я придумал).

Цель:

Эффект, который я надеюсь достичь, отображает один и тот же элемент (и всех потомков) в нескольких местах на одной странице. Мое текущее решение (см. Ниже более подробно) включает в себя клонирование/копирование, а затем добавление во все другие места, которые я хочу, чтобы он отображался в DOM. То, что я прошу здесь, - лучшее (более эффективное) решение. У меня есть несколько идей для потенциально более эффективных решений (см. Ниже). Пожалуйста, судите/критикуйте/увольняйте/дополняйте их или добавляйте свое собственное более-блестящее решение!

"Почему?" вы спрашиваете?

Ну, элемент (и его потомки), который я хочу отображать более одного раза, потенциально имеет множество атрибутов и содержимого - поэтому клонирование и добавление его где-то еще (иногда более чем в одном месте) могут быть довольно манипуляционной работой DOM-манипуляции.

Некоторый контекст:

Я не могу точно описать ситуацию (чертовски NDA!), но по существу у меня есть редактор документов WYSIWYG html. Когда человек редактирует DOM, я фактически сохраняю "оригинальный" node и "измененный" node, обертывая их как в div, скрывая "оригинал", так и позволяя пользователю изменять новый ( "изменено" ) node на их содержание в сердце. Таким образом, пользователь может легко просмотреть изменения, которые они сделали, прежде чем сохранять их.

До этого я просто позволял пользователю перемещаться по "diff divs" и временно скрывать "оригинал" node, чтобы показать изменения "inline". То, что я пытаюсь сделать сейчас, - это позволить пользователю увидеть весь "оригинальный" документ и отредактированный ( "измененный" ) документ в бок о бок. И, возможно, я хотел бы сохранить изменения через несколько сеансов редактирования и одновременно показывать "N" количество версий одновременно.

Текущее решение:

Мое текущее решение для достижения этого эффекта следующее:

Оберните весь dang dom (ну, кроме "панелей инструментов" и всего, что они фактически не редактируют) в div (который я назову "pane1" ), и создайте новый div (что я буду вызовите "pane2" ). Затем глубокое клонирование содержимого pane1 в pane2, а в pane1 отображаются только "оригинальные" узлы, а на панели2 отображаются только "измененные" узлы (в областях различий - все, кроме этого, будет отображаться/скрываться тумблером в панель инструментов). Затем повторите это для панелей 3-через-N.

Проблема с текущим решением:

Если документ, редактируемый пользователем, становится очень длинным или содержит изображения/видео (с различными атрибутами src) или содержит множество необычных элементов стиля (столбцы, таблицы и т.д.), тогда DOM может потенциально получить очень большой/сложный, и попытка клонировать и манипулировать им может привести к медленному сканированию браузера или умению (в зависимости от размера/сложности DOM и количества клонов, а также эффективности браузера/машины, на которой он работает). Если размер проблемы, я могу, конечно, сделать что-то вроде удаления на самом деле скрытых узлов из DOM, но это еще больше операций манипулирования DOM с помощью ресурсов hogging.

Потенциальные решения:

1. Найдите способ сделать DOM более простым/легким

так что клонирование/манипулирование, которое я сейчас делаю, более эффективно. (конечно, я пытаюсь сделать это как можно больше, но, возможно, все, что я действительно могу сделать).

2. Создавайте статические представления версий с элементами Canvas или чем-то.

Я слышал там трюк, в котором вы можете обернуть HTML в элементе SVG, а затем использовать его как источник изображения и нарисовать на холсте. Я думаю, что эти статические холсты (canvi?) Будут иметь гораздо меньший объем памяти, чем клонированные узлы DOM. И манипулирование DOM (скрытие/отображение соответствующих узлов), затем рисование изображения (полоскание и повторение) должно быть более быстрым и эффективным, чем клонирование node и манипулирование клонами. (может быть, я ошибаюсь в этом? Пожалуйста, скажите мне!)

Я пробовал это в ограниченной емкости, но обертываю свой HTML в беспорядках SVG тем, как он отображался в нескольких странных случаях - возможно, мне просто нужно немного сообщить о элементах, чтобы они отображались правильно.

3. Найдите волшебный элемент

который просто ссылается на другой node и выглядит/действует как он, не будучи настоящим клоном (и, следовательно, как-то волшебным намного более легким). Даже если это означало, что я не мог манипулировать этим волшебным элементом отдельно от node его "ссылки" (или его поддельных детей) - в этом случае я все еще мог бы использовать это для неизменных частей и, надеюсь, сбрил бы использование памяти /DOM Manipulation.

4. Выполните некоторые шаги на стороне сервера.

У меня есть возможность выполнять код на стороне сервера, так что, возможно, это намного эффективнее (некоторые из моих пользователей могут быть на мобильных или старых устройствах), чтобы получить все ajax-y и отправить соответствующую часть DOM (может быть "корнем" документа, который пользователь редактирует, или просто особо "diff divs" ) на клонированный/управляемый сервер, затем запрашивать "клоны", управляемые сервером, и вставлять их в соответствующие области/места.

5. Подделайте его, чтобы сделать его "более комфортным"

Вместо того, чтобы выполнять эти операции за один раз и заставляя браузер ждать, пока не будут выполнены операции для повторного рисования пользовательского интерфейса, я мог бы выполнять операции в "кусках" и позволить браузеру повторно отображать и перехватывать передышку раньше делая следующий кусок. Вероятно, это на самом деле приведет к увеличению времени, но для обычного пользователя он может "чувствовать" быстрее (ха-ха, глупые дураки...). В конце концов, я полагаю, именно это очень важно для пользователей.

Сноска:

Опять же, я NDA'd, который мешает мне публиковать фактический код здесь, насколько я бы хотел. Я думаю, что я подробно объяснил ситуацию (возможно, слишком тщательно - если такая вещь существует), поэтому вам не нужно будет видеть код, чтобы дать мне общий ответ. В случае необходимости, я полагаю, я мог бы написать примерный код, который достаточно отличается от моего IP-адреса компании и публикует его здесь. Дайте мне знать, если вы хотите, чтобы я сделал это, и я буду рад обязать (ну, на самом деле, но я все равно сделаю это).

Заранее благодарим за любой совет!

Ответ 1

Взгляните на фоновые элементы CSS. Они позволяют вам отображать узлы DOM в другом месте/многократно. Конечно, они доступны только для чтения, но должны обновляться в реальном времени.

Вам все равно придется придумать много волшебства, но это похожее решение:

  • Создание статических представлений версий с элементами Canvas или что-то в этом роде.

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

Ответ 2

Честно говоря, после прочтения вопроса я почти оставил мысль, что он принадлежит к "слишком жесткой корзине", но после некоторой мысли, возможно, у меня есть некоторые идеи.

Это действительно сложная проблема, и чем больше я думаю об этом, тем больше осознаю, что нет реального способа избежать необходимости клонирования. Вы правы в том, что вы можете создать SVG или Canvas, но он не будет выглядеть одинаково, хотя с достаточным количеством усилий я уверен, что вы можете приблизиться, но не знаете, насколько он эффективен. Вы можете отобразить сервер HTML на стороне сервера, сделать снимок и отправить изображение клиенту, но это определенно не масштабируется.

Единственные предложения, о которых я могу думать, следующие, извините, если они длинны:

  • Как вы делаете этот клон? Если вы проходите через каждый элемент, и когда вы проходите через каждый, вы создаете клон и копируете атрибуты один за другим, то это heaavvvyy. Я бы настоятельно предложил использовать клон jQuery, поскольку я предполагаю, что он более эффективен, чем ваше решение. Кроме того, когда вы делаете структурные изменения, может быть полезно использовать методы jquery detach/remove (native JS: removeChild()), поскольку это приведет к выходу элемента из DOM, чтобы вы могли изменить его перед повторным вставкой.
  • Я не уверен, как вы получили свой WYSIWYG, но избегайте использования ресурсов, поскольку они тяжелые. Если вы должны, то я предполагаю, что они не похожи на входы, поэтому просто замените их другим элементом и стилем (CSS) для соответствия. Убедитесь, что вы выполняете эти свопы, прежде чем повторно вставить клон в DOM.
  • Не помещайте видеоролик во время показа пользовательских сравнений. Последнее, что мы хотим сделать, это ввести сторонние объекты на страницу. Используйте изображение, вам нужно только это сделать, сравнивая. Еще раз, сделайте своп, прежде чем вставлять клон в DOM.
  • Я предполагаю, что клонированные элементы не будут прикреплены к ним javascript (если их удалять, менее движущиеся части более эффективны). Однако "измененные" элементы, вероятно, будут связаны с некоторыми событиями JS, поэтому, возможно, удалите их за период сравнения.
  • Используйте инструменты перерисовки /reff Chrome/FF, чтобы увидеть, как работает ваша страница при реструктуризации DOM. Это важно, потому что вы можете делать несколько "потрясающих" анимаций, которые обойдутся вам в интенсивных ресурсах. См. http://paulirish.com/2011/viewing-chromes-paint-cycle/
  • Используйте CSS по встроенному стилю, где это возможно, поскольку современные браузеры оптимизированы для обработки документов CSS.
  • Можете ли вы сделать так, чтобы ваши пользователи использовали быстрый современный браузер, например Chrome? Если он внутренний, то может стоить того.
  • Можете ли вы сделать это в Silverlight или Adobe Air? Эти объекты получают специальные права доступа к ресурсам, поэтому это, скорее всего, решит вашу проблему (в соответствии с тем, что я представляю себе в глубине проблемы).
  • Это немного левое поле, но вы можете открыть его в другом окне? Современные браузеры, такие как Chrome, будут запускать другое окно в своем собственном процессе, который может помочь.

Несомненно, вы, вероятно, заглянули в эти вещи больше, чем я, но удачи в этом. Было бы любопытно, как вы его решили.

Ответ 3

Вы также можете попробовать: http://html2canvas.hertzen.com/
Если это сработает для вас, у холста есть лучшая поддержка.

Ответ 4

Чтобы получить ваш "бок о бок" оригинальный документ и модифицированный документ.. вместо клонирования всей панели в pane2.. вы могли бы просто загрузить исходный документ в iframe рядом с редактируемым контентом? Гораздо меньше громоздких?

Вы можете настроить способ отображения документа, когда он находится в iframe (например, скрывать материал вне редактируемого содержимого).

А может быть, когда вы сохраните изменения, напишите изменения в файле (или temp) и откройте его в новом iframe? Это может выполнить ваши "несколько сеансов редактирования"... с несколькими фреймами, отображающими документ в разных состояниях.

Просто вслух...

(Извините, если я потерял/не понял ни одну из ваших целей/требований)

Ответ 5

Я не знаю, было ли это уже для вас, но вы должны рассмотреть возможность использования библиотеки jQuery, поскольку она позволяет выполнять различные виды манипуляций с элементами DOM, такие как создание контента и вставка его в несколько элементов сразу или выбор элемента на страницу и вставить ее в другую.

Посмотрите на .appendTo(),.html(),.text(),.addClass(),.css(),.attr(),.clone()

http://api.jquery.com/category/manipulation/

Извините, если я просто укажу то, что вы уже знаете или даже работаете, но ваш NDA находится на пути более точного ответа.