gpt4 book ai didi

ios - React Bootstrap OverlayTrigger with trigger ="focus"bug work around

转载 作者:行者123 更新时间:2023-11-28 16:08:10 27 4
gpt4 key购买 nike

在 iOS Safari 中,带有 trigger="focus"的 OverlayTrigger 在点击外部时无法关闭。这是我的代码:

<OverlayTrigger
trigger="focus"
placement="right"
overlay={ <Popover id="popoverID" title="Popover Title">
What a popover...
</Popover> } >
<a bsStyle="default" className="btn btn-default btn-circle" role="Button" tabIndex={18}>
<div className="btn-circle-text">?</div>
</a>
</OverlayTrigger>

我知道这是 Bootstrap 的一个已知错误,因为它甚至不适用于 their own website在 iOS 中,但有谁知道解决它的方法吗?如果它不需要 jQuery,那将是最好的,但欢迎使用 jQuery 解决方案。谢谢。

最佳答案

好吧,因为没有其他人给我一个变通办法,我和我的同事一起解决了这个问题 3 天,我们想出了这个沉重的解决方案:

问题:

使用 trigger="focus",Bootstrap Popover/Tooltip 可以在 Popover/Tooltip 外点击时关闭,但不能触摸。 Android 浏览器显然会自动将触摸更改为点击,因此在 Android 上一切正常。但是 iOS safari 和基于 iOS safari 的浏览器(iOS chrome、iOS firefox 等)不会这样做。

解决方法:

我们发现在 React Bootstrap 中,Overlay 组件实际上可以让你自定义何时显示 Popover/Tooltip,所以我们基于 Overlay 构建了这个组件 InfoOverlay。为了处理组件外部的点击,我们需要为 Popover/Tooltip 和窗口添加事件监听器,以处理“mousedown”和“touchstart”。此外,由于组件的 padding-right 最初为 0px,因此此方法会使 Popover 始终具有其最小宽度,并且我们根据某些父组件的宽度进行制作,以便它基于父组件进行响应。代码如下所示:

import React, { Component, PropTypes as PT } from 'react';
import {Popover, Overlay} from 'react-bootstrap';

export default class InfoOverlay extends Component {

static propTypes = {
PopoverId: PT.string,
PopoverTitle: PT.string,
PopoverContent: PT.node,
// You need to add this prop and pass it some numbers
// if you need to customize the arrowOffsetTop, it's sketchy...
arrowOffsetTop: PT.number,
// This is to be able to select the parent component
componentId: PT.string
}

constructor(props) {
super(props);
this.state = {
showPopover: false,
popoverClicked: false
};
}

componentDidMount() {
// Here are the event listeners and an algorithm
// so that clicking popover would not dismiss itself
const popover = document.getElementById('popoverTrigger');
if (popover) {
popover.addEventListener('mousedown', () => {
this.setState({
popoverClicked: true
});
});
popover.addEventListener('touchstart', () => {
this.setState({
popoverClicked: true
});
});
}
window.addEventListener('mousedown', () => {
if (!this.state.popoverClicked) {
this.setState({
showPopover: false
});
} else {
this.setState({
popoverClicked: false
});
}
});
window.addEventListener('touchstart', () => {
if (!this.state.popoverClicked) {
this.setState({
showPopover: false
});
} else {
this.setState({
popoverClicked: false
});
}
});

// this is to resize padding-right when window resizes
window.onresize = ()=>{
this.setState({});
};
}

// This function sets the style and more importantly, padding-right
getStyle() {
if (document.getElementById(this.props.componentId) && document.getElementById('popoverTrigger')) {
const offsetRight = document.getElementById(this.props.componentId).offsetWidth - document.getElementById('popoverTrigger').offsetLeft - 15;
return (
{display: 'inline-block', position: 'absolute', 'paddingRight': offsetRight + 'px'}
);
}
return (
{display: 'inline-block', position: 'absolute'}
);
}

overlayOnClick() {
this.setState({
showPopover: !(this.state.showPopover)
});
}

render() {
const customPopover = (props) => {
return (
{/* The reason why Popover is wrapped by another
invisible Popover is so that we can customize
the arrowOffsetTop, it's sketchy... */}
<div id="customPopover">
<Popover style={{'visibility': 'hidden', 'width': '100%'}}>
<Popover {...props} arrowOffsetTop={props.arrowOffsetTop + 30} id={this.props.PopoverId} title={this.props.PopoverTitle} style={{'marginLeft': '25px', 'marginTop': '-25px', 'visibility': 'visible'}}>
{this.props.PopoverContent}
</Popover>
</Popover>
</div>
);
};

return (
<div id="popoverTrigger" style={this.getStyle()}>
<a bsStyle="default" className="btn btn-default btn-circle" onClick={this.overlayOnClick.bind(this)} role="Button" tabIndex={13}>
<div id="info-button" className="btn-circle-text">?</div>
</a>
<Overlay
show={this.state.showPopover}
placement="right"
onHide={()=>{this.setState({showPopover: false});}}
container={this}>
{customPopover(this.props)}
</Overlay>
</div>
);
}
}

最后,这是一项繁重的工作,因为它需要大量代码来修复,而且您可能会感觉到您的站点由于 4 个事件监听器而稍微变慢了。最好的解决方案就是告诉 Bootstrap 解决这个问题......

关于ios - React Bootstrap OverlayTrigger with trigger ="focus"bug work around,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38793531/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com