【问题标题】:How to prevent event bubbling on child of React-Leaflet Map如何防止 React-Leaflet Map 的子级事件冒泡
【发布时间】:2019-11-21 18:21:26
【问题描述】:

我有一个React-Leaflet 地图,我在里面渲染了一个div

由于某种原因,与 div 的内容交互会导致下面的地图做出响应(例如:双击将缩放地图,拖动将平移地图)——即使我在附加的处理程序中调用 e.stopPropagation()到 div。

据我了解,调用 stopPropagation() 应该可以防止 DOM 事件到达地图本身。

为什么stopPropagation() 似乎被忽略了?

我怎样才能在地图内渲染一个 div 而不会将它的事件冒泡到地图本身?

Here is an example codepen 显示问题。

import { Map, TileLayer } from 'react-leaflet';

const MyMap = props => (
  <Map zoom={13} center={[51.505, -0.09]}>
    <TileLayer url={"http://{s}.tile.osm.org/{z}/{x}/{y}.png"} />

    {/* 
          HOW do I get this div to NOT pass it's events down to the map?!?! 
          Why does e.stopPropagation() appear to not work?
    */}
    <div 
      id="zone"
      onClick={e => e.stopPropagation()}
      onMouseDown={e => e.stopPropagation()}
      onMouseUp={e => e.stopPropagation()}
    >
      <p>Double-click or click and drag inside this square</p>
      <p>Why does the map zoom/pan?</p>
    </div>

  </Map>
);

ReactDOM.render(<MyMap />, document.getElementById('root'));

【问题讨论】:

    标签: javascript reactjs dom leaflet react-leaflet


    【解决方案1】:

    对于传单地图,请使用 L.DomEvent.disableClickPropagation 代替:

    stopPropagation 添加到元素的'click''doubleclick''mousedown''touchstart' 事件。

    例子

    function MyMap() {
      return (
        <div>
          <Map zoom={13} center={[51.505, -0.09]}>
            <TileLayer url={"http://{s}.tile.osm.org/{z}/{x}/{y}.png"} />
            <MyInfo />
          </Map>
        </div>
      );
    }
    

    在哪里

    function MyInfo() {
      const divRef = useRef(null);
    
      useEffect(() => {
        L.DomEvent.disableClickPropagation(divRef.current);
      });
    
      return (
        <div ref={divRef} id="zone">
          <p>Double-click or click and drag inside this square</p>
          <p>Why does the map zoom/pan?</p>
        </div>
      );
    }
    

    Updated codepen

    备选方案

    阻止 div 元素传播到地图事件的另一种选择是将 div 放在地图元素之外

    <div>
      <Map zoom={13} center={[51.505, -0.09]}>
        <TileLayer url={"http://{s}.tile.osm.org/{z}/{x}/{y}.png"} />
      </Map>
      <MyInfo />
    </div>
    

    在哪里

    function MyInfo() {
      return (
        <div id="zone">
          <p>Double-click or click and drag inside this square</p>
          <p>Why does the map zoom/pan?</p>
        </div>
      );
    }
    

    【讨论】:

    • 我很想知道为什么 div 本身上的e.stopPropagation() 不起作用。如果没有从 div 传递这些事件,Leaflet 如何接收这些事件?
    • Leaflet 注册事件监听器internally 的方式,执行一些额外的步骤来为Leaflet 控件(例如ZoomIn 控件)注册click 事件处理程序。 only 为 div 元素注册 stopPropagation 不会阻止传单控件单击事件触发(这就是地图放大/缩小的原因)
    • 出现错误信息L is not defined
    • @Tekson import L from 'leaflet';
    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2018-07-25
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多