javascript 是否在组件上触发“调整大小”事件?

w1jd8yoj  于 2023-02-15  发布在  Java
关注(0)|答案(2)|浏览(124)

我正在编写一个组件装饰器,它能够检测到DOM元素的大小何时被改变(通过css、javascript、窗口大小调整等)。
它已经完美地工作了,我现在正在努力使它的API易于使用,那么,还有什么比这更容易的呢?

class Foobar extends React.Component {
  render() {
    return <div onResize={() => console.log('resized!')}>Foobar</div>;
  }
}
ReactDOM.render(resizeAware(Foobar), app);

我面临的问题是,当我触发onResize事件时,它没有被触发...
以下是触发事件的两种尝试:

// method 1
onResize() {
  const resizeEvent = document.createEvent('HTMLEvents');
  resizeEvent.initEvent('resize', true, true);
  console.log('triggering resize...');
  findDOMNode(this.componentNode).dispatchEvent(resizeEvent);
}

// method 2
onResize() {
    console.log('triggering resize...');
    findDOMNode(this.componentNode).dispatchEvent(new Event('resize'));
}

如果我使用以下命令侦听事件:

findDOMNode(this).addEventListener('resize', () => console.log('resized'));

一切正常,所以我所分派的事件似乎是由真实的的DOM元素接收的,而不是由虚拟DOM接收的。
现在的问题是,为什么不调用onResize回调?
如果没有解决方案,您将如何使我的装饰器API可用?
NB:我不需要一种方法来检测组件的大小调整,我只需要向React分派一个事件,并使用onResize访问它

cwtwac6a

cwtwac6a1#

Another NPM lib侦听div的resize事件。检查demo

c90pui9n

c90pui9n2#

我使用了这篇文章,并简单地将其转换为一个React组件。您所需要做的就是在componentDidMount中定义一个MutationObserver,以便它可以监视大小调整

class ResizableDiv extends React.Component {
    constructor(props) {
        super(props);
        this.ref = React.createRef();
    }
    
    componentDidMount() {
        const element = this.ref.current;
        element.addEventListener('resize', (event) => console.log(event.detail));
        function checkResize(mutations) {
            const el = mutations[0].target;
            const w = el.clientWidth;
            const h = el.clientHeight;

            const isChange = mutations
                .map((m) => `${m.oldValue}`)
                .some((prev) => prev.indexOf(`width: ${w}px`) === -1 || prev.indexOf(`height: ${h}px`) === -1);

            if (!isChange) { return; }
            const event = new CustomEvent('resize', { detail: { width: w, height: h } });
            el.dispatchEvent(event);
        }
        const observer = new MutationObserver(checkResize);
        observer.observe(element, { attributes: true, attributeOldValue: true, attributeFilter: ['style'] });
    }
    
    
    render() {
      return ( <div ref={this.ref} className='drag'> Resize me! < /div>);
      }
    }

    ReactDOM.render( < ResizableDiv / > ,
      document.getElementById('root')
    );
.drag {
  border: 1px solid red;
  width: 200px;
  height: 100px;
  resize: both;
  overflow: hidden;
}
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="root" />

相关问题