Как синхронизировать c множественную ручную горизонтальную прокрутку - PullRequest
6 голосов
/ 01 апреля 2020

У меня есть 3 handsontable в моем представлении React. Мне нужно, чтобы они были синхронизированы, когда пользователь прокручивает по горизонтали и вертикали. Я пытался использовать javascript для горизонтальной работы без удачи.

import React from 'react';
import ReactDOM from 'react-dom';

const handsontableData = Handsontable.helper.createSpreadsheetData(6, 50);
const Table1 = () => (
  <div>
    <Handsontable.react.HotTable
      id="T1"
      data={handsontableData}
      colHeaders
      rowHeaders
      colWidths={[100]}
      height={200}
      width="100vw"
    />
  </div>
);

const Table2 = () => (
  <div>
    <Handsontable.react.HotTable
      id="T2"
      data={handsontableData}
      colHeaders
      rowHeaders
      colWidths={[100]}
      height={200}
      width="100vw"
    />
  </div>
);

const Table3 = () => (
  <div>
    <Handsontable.react.HotTable
      id="T3"
      data={handsontableData}
      colHeaders
      rowHeaders
      colWidths={[100]}
      height={200}
      width="100vw"
    />
  </div>
);

const App = () => {
  const T1Obj = document.getElementById('T1');
  const T2Obj = document.getElementById('T2');
  const T3Obj = document.getElementById('T3');

  function getScroll(event) {
    let elem;
    if (event.type === 'scroll') {
      elem = (event.srcElement) ? event.srcElement : event.target;
      if (elem.id === 'T1') {
        T2Obj.scrollLeft = elem.scrollLeft;
        T3Obj.scrollLeft = elem.scrollLeft;
      } else if (elem.id === 'T2') {
        T1Obj.scrollLeft = elem.scrollLeft;
        T3Obj.scrollLeft = elem.scrollLeft;
      } else if (elem.id === 'T3') {
        T1Obj.scrollLeft = elem.scrollLeft;
        T2Obj.scrollLeft = elem.scrollLeft;
      }
    }
  }

  if (typeof addEventListener !== 'undefined') {
    T1Obj && T1Obj.addEventListener('scroll', getScroll);
    T2Obj && T2Obj.addEventListener('scroll', getScroll);
  } else {
    T1Obj && T1Obj.attachEvent('onscroll', getScroll);
    T2Obj && T2Obj.attachEvent('onscroll', getScroll);
  }
  return (
    <div>
      <Table1 />
      <br />
      <Table2 />
      <br />
      <Table3 />
      <br />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('example1'));
<link href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@handsontable/react/dist/react-handsontable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Не удалось запустить его в редакторе кода StackOverflow. так вот ссылка на jsfiddle ссылка

1 Ответ

6 голосов
/ 07 апреля 2020

Как-то так?

    function syncScroll(elements) {

      function getScrollPositions() {
        return elements.map((el) => ({
          scrollLeft: el.scrollLeft,
          scrollTop: el.scrollTop,
        }));
      }

      let scrollPositions = getScrollPositions();

      elements.forEach((el) =>
        el.addEventListener("scroll", () => {
          let currentPositions = getScrollPositions();

          for (let [i, position] of currentPositions.entries()) {
            for (let dim of ["scrollLeft", "scrollTop"]) {
              if (position[dim] != scrollPositions[i][dim]) {
                for (let element of elements) {
                  element[dim] = position[dim];
                }
              }
            }
          }

          scrollPositions = currentPositions;
        })
      );

    }

    syncScroll([T1Obj, T2Obj, T3Obj]);

https://jsfiddle.net/xowvp3a9/

Также имейте в виду, что элементы прокрутки не являются #T1, #T2, #T3, но внутри них. Вы можете увидеть это с помощью тега прокрутки. dev tools scroll

По этой причине:

  const T1Obj = document.querySelector('#T1 .wtHolder');
  const T2Obj = document.querySelector('#T2 .wtHolder');
  const T3Obj = document.querySelector('#T3 .wtHolder');
...