相关版本:React 16.4.2,Bootstrap 4.1.3,popper.js 1.14.4,Typescript 3.0.3
我在我的Popover应用程序中使用Bootstrap react
功能。
如果页面的其余部分是静态的,则Popover可以很好地工作。当页面被更改时(在浏览器级别),Popover会非常快速和平滑地重新定位,以便在其锚定到的内容可见时保持可见:
这一切都运作良好,因为popper.js
显然正在观看window.scroll
和window.resize
事件,根据这个答案:Bootstrap 4 - how does automatic Popover re-positioning work?
当我的react
应用程序开始显示/隐藏DOM元素时,问题就出现了。因为popper.js
不了解react
,所以它不知道DOM的变化,所以它不知道Popovers可能需要重新定位。
我知道在每个Popover锚上调用popover("update")
都有效,因为我已经添加了这样的代码来间歇地执行它:
window.setInterval(()=> $(this.selfRef).popover("update"), 100);
但那令人讨厌和浪费,而且有点笨拙。
有没有办法让react
告诉我何时更新DOM中的任何节点,那么我可以告诉popper.js
更新弹出窗口的位置?
请注意,导致DOM更改的react
组件不一定位于使用Popover的组件附近。它可能是层次结构中完全独立的部分,恰好在带有弹出窗口的组件之前显示 - 所以我认为解决方案不是componentWillReceiveProps()
或类似于Popover组件的方法,因为它可能不是组件这引起了运动。
请注意,我知道像react-bootstrap
,reactstrap
或react-popper
这样的项目 - 但我不想使用它们。
编辑:似乎MutationObserver可能是一个没有反应的方式来做到这一点。我想,因为React已经完成了所有的协调工作,也许有办法让它在实际编辑DOM时通知我。
“导致DOM更改的react组件不一定位于使用Popover的组件附近。它可能是层次结构完全独立的部分”
如果更改DOM的Component和创建Popover的Component都在同一父级中,则可以在执行.popover('update')
的父级中共享一个方法。更改DOM的组件需要触发此事件,但不需要特别“了解”Popover组件。 Popover组件不需要知道DOM更改组件。
class ChangeDom extends React.Component {
constructor(props) {
super(props);
this.changeDom = this.changeDom.bind(this);
}
changeDom () {
this.props.domChanged();
}
render() {
return (
<div>
<button className="ml-2 btn btn-primary" onClick={this.changeDom}>Change Dom
</button>
</div>)
}
}
class Pop extends React.Component {
constructor(props) {
super(props);
this.togglePopover = this.togglePopover.bind(this);
}
togglePopover() {
$('[data-toggle="popover"]').popover('toggle');
}
render() {
return (
<div class="position-relative">
<button className="mt-4 btn btn-primary" onClick={this.togglePopover} data-toggle="popover"
</button>
</div>)
}
}
class Parent extends React.Component {
domChanged(){
$('[data-toggle="popover"]').popover("update");
}
render() {
return (
<div>
<ChangeDom domChanged={this.domChanged} />
<Pop />
</div>)
}
}
但是:ぁzxswい
这是我目前在基于https://www.codeply.com/go/NhcfE8eAEY的解决方案上的尝试。
MutationObserver
是放置在应用程序层次结构顶部的组件。 UserApp
类在我的应用程序的各个地方被用于一堆东西。
从Popover
事件中发射popover("update")
引起无限递归的可能性使我对长期使用此解决方案持谨慎态度。它似乎现在正在完成这项工作,但这是单方向绑定意在避免的事情之一。
从好的方面来说,即使你的应用程序中有非反应组件(例如,Bootstrap MutationObserver
),这也可以工作。
navbar