如何同步多个handsontable水平滚动

Posted

技术标签:

【中文标题】如何同步多个handsontable水平滚动【英文标题】:How to sync multiple handsontable horizontal scrolling 【发布时间】:2020-07-13 12:51:30 【问题描述】:

我的 React 视图中有 3 个实践表。当用户水平和垂直滚动时,我需要它们同步。我尝试使用 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
      
    />
  </div>
);

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

const Table3 = () => (
  <div>
    <Handsontable.react.HotTable
      id="T3"
      data=handsontableData
      colHeaders
      rowHeaders
      colWidths=[100]
      height=200
      
    />
  </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>

我无法在 *** 代码编辑器中运行它。所以这里是 jsfiddle 的链接 link

【问题讨论】:

【参考方案1】:

这样的?

    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,而是其中的一个div。您可以使用滚动标签查看它。

出于这个原因:

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

【讨论】:

其实我只需要在水平滚动上同步? 删除循环 for (let dim of ["scrollLeft", "scrollTop"]) 并将所有出现的 dim 替换为 "scrollLeft"

以上是关于如何同步多个handsontable水平滚动的主要内容,如果未能解决你的问题,请参考以下文章

Handsontable:jquery 合并标题,水平滚动错误

如何同步容器内动态水平滚动视图的滚动视图位置?

表视图行中集合视图的同步水平滚动

handsontable常规配置的中文API

[转]handsontable常规配置的中文API

delphi6 两个dbgrid如何实现水平滚动条同步滚动?