【问题标题】:react-input-range does not trigger events(onChange, onClick) inside react-leaflet Mapreact-input-range 不会在 react-leaflet Map 中触发事件(onChange,onClick)
【发布时间】:2018-08-06 21:28:15
【问题描述】:

我这里有一些有趣的案例! 我在 react-leaflet 标记弹出窗口中使用 react-input-range

是这样的:

import React from 'react';
import { Map as LeafletMap, Marker, Popup, TileLayer } from 'react-leaflet';
import InputRange from 'react-input-range';

export default class MapPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: { min: 2, max: 200 },
      name: 'sample name',
    };
  }
  render() {
    return (
      <div>
        {/*
          * This input range outside LeafletMap works
        */}
        <InputRange
          maxValue={300}
          minValue={0}
          value={this.state.value}
          onChange={value => this.setState({ value })}
        />
        <LeafletMap center={[0, 0]} zoom={16}>
          <TileLayer
            attribution="&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
            url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
          />
          <Marker position={[0, 0]}>
            <Popup>
              {/*
                * This input below works
              */}
              <input
                value={this.state.name}
                onChange={({ target }) => this.setState({ name: target.value })}
              />
              {/*
                * This input range INSIDE LeafletMap does not work
              */}
              <InputRange
                maxValue={300}
                minValue={0}
                value={this.state.value}
                onChange={value => this.setState({ value })}
              />
            </Popup>
          </Marker>
        </LeafletMap>
      </div>
    );
  }
}

到目前为止我所知道的

  • input range 组件在LeafletMap 组件之外工作。
  • 原生输入在 LeafletMap 组件内工作!
  • 我已确认本机输入在弹出窗口中有效! input range 适用于移动设备(Android chrome 浏览器)! (滑动和点击事件)

任何想法如何使输入范围在 react-leaflet 映射中工作

这里有一些可能会有所帮助的详细信息:

  • 反应传单:^2.0.0-rc.3
  • 反应:16.4.2
  • 反应输入范围:^1.3.0

测试环境

浏览器:Chrome 64.0.32、Firefox 61 和 Safari 11.1

操作系统:Mac OSX High Sierra 10.13.5

Codepen:https://codepen.io/codepen-theo/pen/OwdLXY?editors=0010

【问题讨论】:

  • 是否有任何控制台错误?另外,您是否尝试过使用此工具调试道具? chrome.google.com/webstore/detail/react-developer-tools/…
  • 没有错误匹配,并且事件根本没有被触发。我正在使用 github.com/react-boilerplate/react-boilerplategithub.com/evgenyrodionov/redux-logger,因为 react-dev 工具不能很好地与样板 @dkniffin 配合使用
  • 它是否适用于多个 InputRange?这个库似乎做了一些非常令人困惑的事情来附加和销毁文档节点上的事件侦听器。我怀疑组件的实例可能会干扰其他 InputRange 组件的全局事件侦听器。
  • 嗨@HåkenLid,我尝试同时添加2个输入范围(地图外),两者都有效。这是否澄清了你的一些假设?
  • 是的。但我怀疑问题可能与 react-input-range 处理事件的方式有关。它需要将事件侦听器附加到文档节点,但是对于传单,使用反应门户和 iframe 会发生一些复杂的事情。所以我的猜测是,在这种情况下,输入范围所做的一些假设是不正确的。您可以链接到代码笔或类似内容中的代码运行示例吗?这两个库的具体组合可能并不常见。

标签: javascript reactjs leaflet react-leaflet react-component


【解决方案1】:

我已经弄清楚发生了什么。但我不确定是否有一种好方法可以让它按你的意愿工作。

当它冒泡到弹出元素时,leaflet.js 将在 mousedown 事件上调用 event.stopPropagation()。此块对合成事件做出反应,使其无法按预期工作。 React 的事件传播独立于原生冒泡/捕获处理。

https://github.com/Leaflet/Leaflet/blob/master/src/layer/Popup.js#L185

您可以在弹出包装器上修改事件侦听器。看这个例子:

https://codepen.io/haakenlid/pen/ejxNKE

这可以通过简单地删除leaflet.js 附加到插件包装器节点的preventDefault 事件侦听器之一来实现。 (以一种非常老套的方式)

class MyPopup extends React.Component {
  componentDidMount(){
    if (!this.popup) return
    const el = this.popup.leafletElement
    el._initLayout()
    const wrapper = el._wrapper
    wrapper.removeEventListener('mousedown', wrapper._leaflet_events['mousedown6'])
    console.log('mount')
  }
  render(){
    return <Popup ref={ el=>this.popup = el } {...this.props} />
  }
}

这只是一个概念证明。很有可能它会在以后版本的 leaflet.js(或以其他方式)中再次崩溃。

【讨论】:

猜你喜欢
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
  • 2022-06-28
  • 1970-01-01
  • 2016-07-21
  • 2021-06-10
相关资源
最近更新 更多