Как разделить окно просмотра браузера на две горизонтальные панели

До HTML 4 можно было создавать макеты с фреймами, загружающими разные HTML файлы в разные панели.

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

Моя идеальная парадигма - это MS Word, которая позволяет разбивать окно на две горизонтальные части, чтобы показывать в каждом из разных разделов того же документа (чрезвычайно полезно при сравнении разных частей документа или при перемещении частей с одной отдаленной стороны на другую на длинных документы) или MS Excel (даже LibreOffice или OpenOffice Calc имеют аналогичную функцию), что позволяет разделить панель листа в 2 (или даже в 4) разделах по той же причине или сохранить видимые некоторые строки сверху или некоторые столбцы в (например, заголовок строки или столбца).

На следующем рисунке показано: Split same window document example.png

Красная стрелка указывает на водосточный желобок, который разбивает оконный документ на две части, позволяя прокручивать каждую часть отдельно, так как вы можете видеть, как выглядит номер строки, которая на верхней панели составляет 3 и 21 на нижней панели. Также водосточный желоб является изменяемым.

Можно ли это сделать с помощью vanilla JS с HTML и CSS (без jQuery или другой структуры, пожалуйста)?

Ограничения:

  1. Документ должен быть одинаковым для всех 2 панелей (сверху и снизу) (старый набор фреймов должен загружать два разных документа или один и тот же документ дважды: я использую это уже, но, если возможно, я хочу более чистый подход!)
  2. Сепаратор (желоб?) Должен быть изменен
  3. Две разные части документа прекрасно синхронизированы в том смысле, что если я что-то модифицирую (с помощью свойства contenteditable) в верхней (или нижней) панели, нижняя (или верхняя) панель мгновенно показывает редактирование, как только MS Word или Excel... поэтому, если я удалю что-то в любой нижней таблице таблицы, даже верхнее содержимое будет соответствующим образом скорректировано (даже размер столбца), как это происходит с MS Word, Excel, Calc и т.д.
  4. Сплит-просмотр будет включен и выключен при нажатии на определенную кнопку
  5. Мне не нужны старые браузеры, только сценарий ECMA 2015 или более поздние
  6. В файле HTML есть много прослушивателей событий, связанных с addEventListener() с различными элементами HTML, такими как кнопки, текстовые поля, флажки, выборки и т.д. Это означает, что ответное решение должно иметь возможность сохранять их в целости и работать в обеих панелях.

Где я буду использовать это?

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

Ситуация:

На данный момент я использую следующий код:

function splitView()
{
    var tgtSrc = location.href;
    var frameset =  '<frameset rows="*,*">' +
                        '<frame name="' + upFrame + '" src="' + tgtSrc + '">' +
                        '<frame name="' + dwFrame + '" src="' + tgtSrc + '">' +
                    '</frameset>';
    document.write(frameset);   
}

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

Плюс алгоритм для синхронизации обоих экземпляров данных документа: он работает, сохраняя при каждом редактировании данных в одном кадре данные в хранилище сеансов этого кадра и перезагружает одни и те же данные в другой фрейм.

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

  1. Теги фреймов и фреймов не поддерживаются в современных HTML5-совместимых файлах, даже если они все еще поддерживаются браузерами
  2. Файл должен быть загружен дважды (один раз за кадр), это означает заметную нехватку производительности и трудно синхронизировать в реальном времени любые изменения в одном кадре с другим фреймом (возможно двунаправленная синхронизация, поэтому редактирование может выполняться как в показанной части документа). К сожалению, даже требуемый процесс синхронизации означает снижение производительности, которая блокирует пользовательский интерфейс в течение некоторого момента каждый цикл синхронизации
  3. Процесс синхронизации не в режиме реального времени, он имеет некоторую задержку (несколько секунд): если я делаю это короче, у меня есть большая нехватка возможностей, которая включает замораживание браузера

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

Что я ищу:

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

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

enter image description here

Посмотрите внимательно на это: есть желоб, который можно перемещать горизонтально (есть вертикальный желоб, но мне все равно, что вертикальное расщепление, просто горизонтальное), и когда таблица листает вниз, строки исчезают под ней: в факт, что первая строка над желобом - это n. 1 первая строка вниз по желову равна n. 45.

Также обратите внимание на маленькую двуглавую белую стрелку, обозначенную большой красной стрелкой в крайнем левом углу изображения.

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

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

Обратите внимание:

Свойство CSS

position: sticky;

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

Ответ 1

Любопытно, если это локальные файлы на вашем компьютере, почему вы пытаетесь редактировать данные таблицы из файлов csv в браузере вместо того, чтобы просто использовать собственные возможности такой программы, как Excel, упомянутый выше? Или, если вы хотите сделать это в браузере, листы google позволяют разделить экран? Нет неуважения, я просто не понимаю, почему не использовать программу, предназначенную и оптимизированную для такого рода работ.

если вы хотите продолжать использовать фреймы, вы сможете загрузить файл обратно в один фрейм и просто скопировать innerHTML из одного кадра в другой, что-то вроде следующего. Если вы используете хранилище сеансов, хотя он должен (?) Быстрее сохранять изменения для этого и csv файла, но загружать из хранилища сеансов вместо файла.

window.frames[upFrame].document.body.innerHTML = window.frames[dwFrame].document.body.innerHTML;

Вместо использования фреймов вы можете использовать DIVs в качестве контейнеров, загружать их в локальное хранилище, как вы предлагаете, и заполнять оба DIV. saves будет передаваться как в файл csv, так и в локальное хранилище, как решение для фреймов. Javascript может отслеживать верхнюю часть прокрутки, поэтому после перезагрузки из локального хранилища вы можете "поместить" два раздела в строки, в которых они были.

Более быстрое решение, хотя могло бы хранить данные csv в памяти (массиве) и сохранять в csv, но обновление из памяти было бы намного быстрее, чем файл в теории правильно :)

Ответ 2

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

Если вы хотите взять всю страницу и просто разделить ее, вы можете использовать решение для набора фреймов, но вместо того, чтобы браузер дважды загружал ресурс, вы можете просто скопировать его HTML и записать его в фреймы:

<html>
  <head>
    <style type="text/css">
        body { color: red; } /* Only used to test if CSS is copied as well
    </style>
  </head>
  <body>
      Hello world!
  </body>

  <script type="text/javascript">
    function inFrame () {
      try {
    return window.self !== window.top;
      } catch (e) {
        return true;
      }
    }


    function buildFrames() {
      const documentHTML = document.documentElement.innerHTML;

      const frameset = document.createElement('frameset');
      frameset.rows = '*,*';

      const frame1 = document.createElement('frame');
      const frame2 = document.createElement('frame');

      document.documentElement.innerHTML = '<html><body></body></html>';

      frameset.appendChild(frame1);
      frameset.appendChild(frame2);

      document.body.appendChild(frameset);

      frame1.src = 'data:text/html;charset=utf-8,' + encodeURI(documentHTML);
      frame2.src = 'data:text/html;charset=utf-8,' + encodeURI(documentHTML);
    }

    if (!inFrame()) {
        buildFrames();
    }
  </script>
</html>

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

Ответ 3

Я думаю, вы можете добиться этого с помощью div.

сначала создайте два divs, чтобы удерживать верхний и нижний виды.

затем клонировать то основное содержимое каждого div.

регулируя размеры и положение для каждого div, вы можете получить представление одного div, разделенного на две части

также вы можете создать сценарий re size для управления высотой каждого представления div

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

наконец извините за плохие объяснения.

я сделал jsfiddle, чтобы объяснить подход

[1]: https://jsfiddle.net/EmadElpurgy/r9w93zo7/ sample code

Ответ 4

Я только частично рассмотрю ваш вопрос, так как у меня нет полного решения.

Теги фреймов и фреймов не поддерживаются в современных HTML5-совместимых файлах, даже если они все еще поддерживаются браузерами

Рамка устарела в пользу iframe. Это должно вести себя примерно так же.

Чтобы гарантировать синхронизацию между двумя панелями с ограничениями, которые вы выложили, вам придется писать пользовательские JS, тем более, что вы не уверены в структуре/пакете.