我想从始终具有其最宽元素宽度的项目列表中进行选择。选中的项目是始终显示的项目,其他选项则显示在悬停上。
这是一个简单的CSS下拉列表,理想情况下,我希望看到纯CSS解决方案。由于我正在使用React,并且此下拉列表是一个组件,因此可以接受js解决方案(如果可能,则不使用jQuery或其他库)。
const Dropdown = (props) => (
<div className="dropdown">
<div className="dropdown-item">{props.active}</div>
<div className="dropdown-body">
{props.items
.filter(x => x !== props.active)
.map(x => <div className="dropdown-item">{x}</div>)}
</div>
</div>
)
var items = [
"abc", "abcdcdssd", "a"
]
ReactDOM.render(
<div>Hello <Dropdown items={items} active={"abc"} /> world.</div>,
document.querySelector("#app")
)
.dropdown {
display: inline-block;
background-color: blue;
text-align: center;
}
.dropdown .dropdown-item {
background-color: red;
width: auto;
padding: 0 6px;
}
.dropdown .dropdown-body {
display: none;
position: absolute;
z-index: 1000;
}
.dropdown:hover .dropdown-body {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
在上面的示例中,我希望"abc"
元素的宽度大于最大元素"abcdcdssd"
的宽度。
答案 0 :(得分:2)
一个纯CSS解决方案是给您的容器一个width: auto
并在您的商品上使用visibility
样式而不是display
来隐藏它们:
const Dropdown = (props) => (
<div className="dropdown">
<div className="dropdown-item">{props.active}</div>
<div className="dropdown-body">
{props.items
.filter(x => x !== props.active)
.map(x => <div className="dropdown-item">{x}</div>)}
</div>
</div>
)
var items = [
"abc", "abcdcdssd", "a"
]
ReactDOM.render(
<div>Hello <Dropdown items={items} active={"abc"} /> world.</div>,
document.querySelector("#app")
)
var items = [
"abc", "abcdcdssd", "a"
]
ReactDOM.render(
<div>Hello <Dropdown items={items} active={"abc"} /> world.</div>,
document.querySelector("#app")
)
.dropdown {
display: inline-block;
text-align: center;
vertical-align: top;
width: auto;
}
.dropdown .dropdown-item {
background-color: red;
padding: 0 6px;
}
.dropdown .dropdown-body {
visibility: hidden;
z-index: 1000;
}
.dropdown:hover .dropdown-body {
visibility: visible;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>
需要注意的是,因为只有在选择了文本后,这些项目才会被隐藏,所以隐藏的项目也会被选中。
您可以在初始渲染后测量下拉实体的宽度,并将其应用于活动的下拉项目。为此,您最初需要使用visibility: hidden
而不是display: none
,因为只能测量隐藏元素的宽度。您可以在对其进行初步测量后立即将其隐藏。
以下示例使用了需要版本>16.8
的react钩子,但也可以使用基于componentDidMount
的基于类的组件来实现。
const {useRef, useState, useLayoutEffect} = React;
const Dropdown = props => {
const bodyRef = useRef();
const [bodyWidth, setWidth] = useState(null);
const [itemsHidden, setItemsHidden] = useState(false);
useLayoutEffect(() => {
setWidth(bodyRef.current.clientWidth);
setItemsHidden(true);
}, []);
return (
<div style={{width: bodyWidth || 'auto'}} className="dropdown">
<div className="dropdown-item">{props.active}</div>
<div ref={bodyRef} className={`dropdown-body${itemsHidden ? ' hidden' : ''}`}>
{props.items
.filter(x => x !== props.active)
.map((x, idx) => (
<div key={idx} className="dropdown-item">{x}</div>
))}
</div>
</div>
);
};
var items = [
"abc", "abcdcdssd", "a"
]
ReactDOM.render(
<div>Hello <Dropdown items={items} active={"abc"} /> world.</div>,
document.querySelector("#app")
)
.dropdown {
display: inline-block;
background-color: blue;
text-align: center;
}
.dropdown .dropdown-item {
background-color: red;
width: auto;
padding: 0 6px;
}
.dropdown .dropdown-body {
position: absolute;
z-index: 1000;
}
.dropdown .dropdown-body.hidden {
display: none;
position: absolute;
z-index: 1000;
}
.dropdown:hover .dropdown-body {
display: block;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>