状态更改后的 Bootstrap Dropdown 更新位置
Posted
技术标签:
【中文标题】状态更改后的 Bootstrap Dropdown 更新位置【英文标题】:Bootstrap Dropdown update position after state change 【发布时间】:2021-09-07 07:04:41 【问题描述】:我在引导下拉菜单中使用搜索输入框。当我搜索任何值时,它会过滤下拉列表以仅显示过滤后的下拉项目。
这里的问题是当下拉位置向上并且我过滤列表时,下拉项目的起点保持不变,在下拉项目和下拉列表之间留下间隙。但是在底部位置打开下拉菜单时可以正常工作。
当我单击下拉按钮时,Bootstrap 会添加x-placement="top-start"
,如下所示,当我过滤值时它永远不会更新。我想更新位置,以便每次从下拉列表开始并且之间没有间隙。
<div class="dropdown show">
<div class="dropdown-menu show"
x-placement="top-start"
style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, -279px, 0px);">
...
</div>
</div>
我已经添加了问题的codeandbox
https://stackblitz.com/edit/react-xz1jvq?file=src/App.js
过滤器后的下拉菜单在两者之间留出空间。基本上我想在过滤后每次更新它的位置
【问题讨论】:
你有一个codeandbox以便更好地测试它吗? @Apostolos 使用代码框链接更新了问题。 嗯,这很棘手 你检查我的答案了吗? 是的@Apostolos,使用 jQuery 效果很好。但我正在尝试使用 ReactJS 的一些方法。 ReactJS 有没有办法实现同样的效果。 【参考方案1】:绝对不是最好的解决方案,但我认为你可以使用这个
关键部分: 我删除了所有用于打开模式的引导代码并更改了切换按钮的单击功能。
然后,在 componentDidUpdate
内部,我使用选择器和原版 js 强制隐藏下拉菜单并再次显示,以便再次计算测量值。
import React from 'react';
import './style.css';
import ReactDOM from 'react-dom';
import $ from 'jquery';
class App extends React.Component
constructor(props)
super(props);
this.state =
isDropdownOpen: false,
inputValue: '',
options: ['action', 'newAction', 'oldAction']
;
componentDidUpdate(prevProps, prevState)
if (
$('.dropdown-menu')
.attr('class')
.indexOf('show') >= 0
)
$('#dropdownMenuButton').trigger('click.bs.dropdown');
$('#dropdownMenuButton').trigger('click.bs.dropdown');
else
$('#dropdownMenuButton').trigger('click.bs.dropdown');
$('#search').focus();
handleChange = evt =>
const value = evt.target.value;
this.setState( inputValue: value );
;
render()
return (
<div>
<h1>Hello StackBlitz!</h1>
<h1>Hello StackBlitz!</h1>
<h1>Hello StackBlitz!</h1>
<h1>Hello StackBlitz!</h1>
<h1>Hello StackBlitz!</h1>
<h1>Hello StackBlitz!</h1>
<div className="dropdown" ref=node => (this.DDRef = node)>
<button
className="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
onClick=() =>
this.setState( isDropdownOpen: !this.state.isDropdownOpen )
>
this.state.isDropdownOpen ? (
<div style= display: 'flex' >
<input
id="search"
type="text"
defaultValue=''
value=this.state.inputValue
placeholder='Search'
ref=node => (this.inputRef = node)
onChange=this.handleChange
/>
<span
className="cancel-icon"
ref=node => (this.cancelRef = node)
>
x
</span>
</div>
) : (
<div>Dropdown button</div>
)
</button>
<div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
this.state.options
.filter(el => el.startsWith(this.state.inputValue))
.map(option =>
return (
<a className="dropdown-item" href="#">
option
</a>
);
)
</div>
</div>
</div>
);
export default App;
【讨论】:
该方法基本上解决了我的问题。我没有在 componentDidUpdate 下使用它,而是使用 react 尝试了以下操作。handleChange = evt => this.setState(inputValue: this.inputRef.value, () => this.buttonRef.click(); this.inputRef.focus(); ); this.dropdownRef.click();
太棒了!我也会尝试这样做,因为它在某种程度上对我来说不适用于 refs。我可能做错了什么以上是关于状态更改后的 Bootstrap Dropdown 更新位置的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap 4 Dropdown Navbar 使用 Plus 和 Minus Fontawesome 5 更改插入符号
Keep-bootstrap-3-dropdown-open-when-clicked