#javascript #reactjs #react-router
#javascript #reactjs #react-маршрутизатор
Вопрос:
У меня есть один ul
, и внутри него у меня есть .У меня есть li
. ul
max-width
400
Я хочу показать только несколько li
‘ (до 400px
) после того, что я хочу показать More link
.когда пользователь нажимает на more link
него, отображается оставшееся li
. поэтому я хочу рассчитать ширину li
элемента, чтобы я мог разбить свои li
(до большего количества li и оставшегося li). можем ли мы рассчитать li
и сравнить всегда общую li
ширину с 400px
тем, достигнута она или нет.
вот мой код https://codesandbox.io/s/dazzling-stonebraker-usly9?file=/src/styles.css
Я могу получить ширину parent
(400 пикселей), но мне нужна ширина всех li
присутствующих внутри ul
export default function App() {
const [activeIndex, setActiveIndex] = useState(0);
const navRef = useRef();
useEffect(() => {
if (navRef) {
console.log(navRef.current.offsetWidth);
}
}, []);
return (
<div className="cls">
<ul className="nav" ref={navRef}>
{links.map(({ text, url }, index) => {
return (
<li
key={index}
className={[`${index === activeIndex ? "active" : ""}`].join(" ")}
>
<a data-target="rc64panel_2" href={url}>
<span>{text}</span>
</a>
</li>
);
})}
</ul>
</div>
);
}
Я вычисляю ширину, потому что хочу знать, сколько элементов я покажу раньше, а остальные я хочу знать во всплывающем окне
Спасибо @KS . updating
Пример
Давайте возьмем пример, у меня 5 li. используя css, это как 3 li. как я узнаю, что осталось 2? позвольте взять, я хочу показать оставшийся элемент во всплывающем окне
Ответ №1:
Вы можете сделать это с помощью pure CSS
и просто заменить класс, когда вам нужно.
.cls {
max-width: 400px;
overflow-x: hidden;
}
И когда вам больше не нужен этот класс (при нажатии кнопки), вы просто удаляете его.
// you store the class name in the state
const [classes, setClasses] = useState('cls')
//
const handleShowMore = () => {
setClasses('') // or anything else
}
...
return <div>
<div className={classes}>your li go here</div>
<button onClick={handleShowMore}>show more</button>
</div>
Обновить
Вы можете получить скрытые, обратившись к ссылке, которая у вас уже есть.
[...navRef.current.children].forEach((item, index) => {
item.offsetWidth // will get you the li width
})
теперь вы можете либо получить индексы элементов, либо переместить их в узел, в котором вы хотите их отобразить (div в модальном) с помощью appendChild .
Комментарии:
1. @ks спасибо за ответ. но как узнать, сколько осталось элементов
2.давайте возьмем пример, который у меня есть
5 li's
. используя css, это как3
li
. как я узнаю, что осталось 2? позвольте, я хочу показать оставшийся элемент во всплывающем окне.3. Вы должны обновить вопрос с учетом этих требований.
4. вот почему я пытаюсь рассчитать ширину, чтобы я мог принимать переменную в состоянии, пока она не отобразится. и оставшееся я покажу во всплывающем окне. конечно, я обновлю это
5. @Ks это возможно или?
Ответ №2:
Вы могли бы получить ширину каждого li, прежде чем помещать их в dom, суммировать их и при достижении порогового значения скрывать остальные элементы, пока пользователь не нажмет на дополнительную ссылку
Самый простой подход
const links = [
{
text: "Technology",
url: "placeholder.html"
},
{
text: "Beauty",
url: "placeholder.html"
},
{
text: "Construction",
url: "placeholder.html"
},
{
text: "Manufactoring",
url: "placeholder.html"
},
{
text: "Transportation",
url: "placeholder.html"
},
{
text: "Real Estate",
url: "placeholder.html"
},
];
const { useRef, useState, useEffect } = React;
const App = () => {
const [clickedMore, setClickMore] = useState(false);
const onClick = () => setClickMore(true);
const renderListItems = function*() {
const widthThreshold = 200;
let totalWidth = 0;
let index = 0;
for(const link of links) {
const test = document.createElement("li");
test.textContent = link.text;
test.style.visibility = 'hidden';
test.style.position = 'absolute';
document.body.appendChild(test);
const offsetWidth = test.offsetWidth;
test.parentNode.removeChild(test);
const style = {
display: "list-item",
}
if(!clickedMore amp;amp; totalWidth offsetWidth > widthThreshold) {
style.display = "none";
}
totalWidth = offsetWidth;
yield (<li style={style} key={index}>{link.text}</li>);
index ;
}
}
return <div><ul className="nav">
{[...renderListItems()]}
</ul>
{clickedMore ? null : <div>
<button onClick={onClick}>More link</button>
</div>}
</div>;
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
* {
padding: 0;
margin: 0;
list-style: none;
}
.cls {
max-width: 400px;
}
.nav {
display: flex;
width: 100%;
position: relative;
padding-right: calc(44px - 0.9em);
}
.nav > li {
flex-grow: 1;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js"></script>
<div id="root"></div>