将 React 组件渲染到 GoogleMaps InfoBox - 停止点击
Rendering React Component into GoogleMaps InfoBox - Stop click throughs
我在 React 应用程序中遇到 google 地图信息框的问题。我的目标是在 google 地图实例上打开一个空的信息框,然后使用 ReactDOM.render 将我的组件放入其中。该组件由一组选项卡组成,每个选项卡窗格在打开时通过 redux 和 thunk 进行 API 调用。
一切正常,显示效果很好。问题来自实际单击信息框。我可以通过将 enableEventPropagation 更改为 true 或 false 来使其以两种方式之一工作:
enableEventPropagation = true: 组件工作,所有选项卡和按钮,但是如果我碰巧点击信息框的右侧部分,我的信息框下面的任何标记都会被打开,这完全破坏了我的应用程序的状态和流程。
enableEventPropagation = false:点击不通过地图,但随后 none 反应组件中的点击事件起作用。没有选项卡,没有按钮:什么都没有。看起来不错,但根本不起作用。
这是我创建信息框并使用 ReactDOM 呈现给它的代码:
renderInfoBox() {
let {map, google, infoBox} = this.props;
let markerElement = MarkerElementService.getMarkerElement(infoBox.ui.markerId);
this.infoBox = new this.infoBoxClass({
content: this.refs.infoBoxHolder,
enableEventPropagation: false,
pixelOffset: new google.maps.Size(10, -275),
maxWidth: 350,
zIndex: 99999999,
infoBoxClearance: new google.maps.Size(75, 75)
});
ReactDOM.render(
<Provider store={AppStore}>
<ThemeProvider theme={Theme}>
<InfoBoxComponent google={google} onClose={this.closeButtonClicked.bind(this)} />
</ThemeProvider>
</Provider>,
this.refs.infoBoxHolder,
() => {
this.infoBox.open(map, markerElement);
}
);
}
render() {
return (
<div ref="infoBoxHolder" />
);
}
我尝试了以下解决方案:
正在切换到 GoogleMaps OverLay。完全相同的问题,实际上查看 InfoBox 插件似乎 InfoBox 是 OverLay 的包装器,它有助于消除其中一些问题,但仍然假设它只是非交互式的。
在我的组件内部的各个点禁用事件传播,但效果是它禁用事件传播到 DOM 树,而不是向上,这意味着子组件不起作用!疯了!
看来我剩下的唯一选择是以某种方式计算 InfoBox 渲染后的 Lat/Lng 边界,然后依次禁用该区域中的所有标记,但我想要的是一堆废话避免!
或者我的做法完全错误?
您可以尝试一些方法。
首先,如果你没有很多标记,你绝对可以尝试将标记 optimized 标志设置为 false
。它会将它们呈现为单独的 DOM 元素,从而降低性能,但您不会像您遇到的那样出现奇怪的行为。
我无法使用普通标记重现您的问题,但可以使用默认添加的 POI 重现。为防止打开 InfoBox 后面的任何标记,您可以在 InfoBox 的 enter
和 leave
上创建一个监听器,它将设置一个布尔值,并覆盖 [=16= 的 set
方法] 在悬停时取消默认行为。您仍然可以看到鼠标光标在变化,但是可以使用一些基本的 CSS.
来删除它
这里有一个例子,试试点击Sechelt Aquatic Center
标记打开InfoxBox后,应该是不行的。
function initialize () {
let enableMarkers = true
const set = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function (key, val) {
if (key === 'map') {
if (!enableMarkers) {
return
}
}
set.apply(this, arguments)
}
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: new google.maps.LatLng(49.47216, -123.76307),
mapTypeId: google.maps.MapTypeId.ROADMAP,
})
const marker = new google.maps.Marker({
map,
draggable: true,
position: new google.maps.LatLng(49.47216, -123.76307),
visible: true
})
const box = document.createElement('div')
box.innerHTML = 'Hello <br> Hello <br> Hello'
google.maps.event.addListener(marker, 'click', function (e) {
if (!enableMarkers) { return }
ib.open(map, this)
})
const ib = new InfoBox({
content: box,
zIndex: 10,
pixelOffset: new google.maps.Size(-100, 0),
boxStyle: {
background: 'white',
padding: '5px',
opacity: 0.75,
width: '200px',
},
closeBoxMargin: '2px',
closeBoxURL: 'https://www.google.com/intl/en_us/mapfiles/close.gif',
isHidden: false,
enableEventPropagation: true,
})
box.addEventListener('mouseenter', () => {
enableMarkers = false
})
box.addEventListener('mouseleave', () => {
enableMarkers = true
})
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false"></script>
<script src="https://rawgit.com/googlemaps/v3-utility-library/master/infobox/src/infobox.js"></script>
<body onload="initialize()">
<div id="map" style="width: 100%; height: 200px"></div>
</body>
我还在一些地方看到人们遇到了同样的问题,不得不等待 InfoBox domready
事件开始绑定他们的点击。不要真的认为这是相关的,因为我真的不知道如何使用 React 做到这一点,但仍然值得注意。
我在 React 应用程序中遇到 google 地图信息框的问题。我的目标是在 google 地图实例上打开一个空的信息框,然后使用 ReactDOM.render 将我的组件放入其中。该组件由一组选项卡组成,每个选项卡窗格在打开时通过 redux 和 thunk 进行 API 调用。
一切正常,显示效果很好。问题来自实际单击信息框。我可以通过将 enableEventPropagation 更改为 true 或 false 来使其以两种方式之一工作:
enableEventPropagation = true: 组件工作,所有选项卡和按钮,但是如果我碰巧点击信息框的右侧部分,我的信息框下面的任何标记都会被打开,这完全破坏了我的应用程序的状态和流程。
enableEventPropagation = false:点击不通过地图,但随后 none 反应组件中的点击事件起作用。没有选项卡,没有按钮:什么都没有。看起来不错,但根本不起作用。
这是我创建信息框并使用 ReactDOM 呈现给它的代码:
renderInfoBox() {
let {map, google, infoBox} = this.props;
let markerElement = MarkerElementService.getMarkerElement(infoBox.ui.markerId);
this.infoBox = new this.infoBoxClass({
content: this.refs.infoBoxHolder,
enableEventPropagation: false,
pixelOffset: new google.maps.Size(10, -275),
maxWidth: 350,
zIndex: 99999999,
infoBoxClearance: new google.maps.Size(75, 75)
});
ReactDOM.render(
<Provider store={AppStore}>
<ThemeProvider theme={Theme}>
<InfoBoxComponent google={google} onClose={this.closeButtonClicked.bind(this)} />
</ThemeProvider>
</Provider>,
this.refs.infoBoxHolder,
() => {
this.infoBox.open(map, markerElement);
}
);
}
render() {
return (
<div ref="infoBoxHolder" />
);
}
我尝试了以下解决方案:
正在切换到 GoogleMaps OverLay。完全相同的问题,实际上查看 InfoBox 插件似乎 InfoBox 是 OverLay 的包装器,它有助于消除其中一些问题,但仍然假设它只是非交互式的。
在我的组件内部的各个点禁用事件传播,但效果是它禁用事件传播到 DOM 树,而不是向上,这意味着子组件不起作用!疯了!
看来我剩下的唯一选择是以某种方式计算 InfoBox 渲染后的 Lat/Lng 边界,然后依次禁用该区域中的所有标记,但我想要的是一堆废话避免!
或者我的做法完全错误?
您可以尝试一些方法。
首先,如果你没有很多标记,你绝对可以尝试将标记 optimized 标志设置为 false
。它会将它们呈现为单独的 DOM 元素,从而降低性能,但您不会像您遇到的那样出现奇怪的行为。
我无法使用普通标记重现您的问题,但可以使用默认添加的 POI 重现。为防止打开 InfoBox 后面的任何标记,您可以在 InfoBox 的 enter
和 leave
上创建一个监听器,它将设置一个布尔值,并覆盖 [=16= 的 set
方法] 在悬停时取消默认行为。您仍然可以看到鼠标光标在变化,但是可以使用一些基本的 CSS.
这里有一个例子,试试点击Sechelt Aquatic Center
标记打开InfoxBox后,应该是不行的。
function initialize () {
let enableMarkers = true
const set = google.maps.InfoWindow.prototype.set;
google.maps.InfoWindow.prototype.set = function (key, val) {
if (key === 'map') {
if (!enableMarkers) {
return
}
}
set.apply(this, arguments)
}
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: new google.maps.LatLng(49.47216, -123.76307),
mapTypeId: google.maps.MapTypeId.ROADMAP,
})
const marker = new google.maps.Marker({
map,
draggable: true,
position: new google.maps.LatLng(49.47216, -123.76307),
visible: true
})
const box = document.createElement('div')
box.innerHTML = 'Hello <br> Hello <br> Hello'
google.maps.event.addListener(marker, 'click', function (e) {
if (!enableMarkers) { return }
ib.open(map, this)
})
const ib = new InfoBox({
content: box,
zIndex: 10,
pixelOffset: new google.maps.Size(-100, 0),
boxStyle: {
background: 'white',
padding: '5px',
opacity: 0.75,
width: '200px',
},
closeBoxMargin: '2px',
closeBoxURL: 'https://www.google.com/intl/en_us/mapfiles/close.gif',
isHidden: false,
enableEventPropagation: true,
})
box.addEventListener('mouseenter', () => {
enableMarkers = false
})
box.addEventListener('mouseleave', () => {
enableMarkers = true
})
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false"></script>
<script src="https://rawgit.com/googlemaps/v3-utility-library/master/infobox/src/infobox.js"></script>
<body onload="initialize()">
<div id="map" style="width: 100%; height: 200px"></div>
</body>
我还在一些地方看到人们遇到了同样的问题,不得不等待 InfoBox domready
事件开始绑定他们的点击。不要真的认为这是相关的,因为我真的不知道如何使用 React 做到这一点,但仍然值得注意。