繁体   English   中英

React.js - 如何检查 div 是否在屏幕底部(动态)

[英]React.js - How to check if the div is at the bottom of the screen (dynamically)

有什么方法可以检查 div 是否位于另一个 div 的底部(充当父级或容器)。

我试过的

所以基本上我做了演示,其中 div 中有可以添加和删除的子元素( items, setItems ),您也可以通过单击 div 更改它们的高度(在这里很重要)。 还有另一个 div,它不在items state 中,我想更改该项目的标题,如果它位于他的父 div 的底部( items也具有与此 div 相同的父项)。

我的解决方案有问题

我已经尝试了一些方法,我正在查看父容器的getBoundingClientRect()和这个“蓝色” div,让我们这样称呼它,它会正常工作,只有items具有相同的高度,但尽快删除一项并通过单击 div 更改它的高度,它将不起作用。 它将显示它位于屏幕底部(标题为真),但实际上并非如此。

我的代码

App.js - 仅用于演示目的

import "./styles.css";
import { useState, useEffect, useRef } from "react";

export default function App() {
  const arrayItems = [
    {
      id: 1,
      name: "test",
      resized: false
    },
    {
      id: 2,
      name: "test1",
      resized: false
    },
    {
      id: 3,
      name: "test2",
      resized: false
    }
  ];
  const [items, setItems] = useState(arrayItems);
  const [title, setTitle] = useState(false);
  const parentRef = useRef(null);
  const itemsRef = useRef(null);

  useEffect(() => {
    if (
      parentRef?.current.getBoundingClientRect().bottom -
        itemsRef?.current.getBoundingClientRect().height <=
      itemsRef?.current.getBoundingClientRect().top
    ) {
      setTitle(true);
    } else {
      setTitle(false);
    }
  }, [parentRef, items]);

  const handleClick = () => {
    const maxValue = Math.max(...items.map((item) => item.id)) + 1;
    setItems((prev) => [
      ...prev,
      { id: maxValue, name: "testValue", resized: false }
    ]);
  };

  const handleDelete = () => {
    setItems((prev) => prev.slice(0, prev.length - 1));
  };

  const handleResize = (item) => {
    setItems((prev) =>
      prev.map((itemOld) => {
        if (itemOld.id === item.id) {
          return itemOld.resized === true
            ? { ...itemOld, resized: false }
            : { ...itemOld, resized: true };
        } else {
          return itemOld;
        }
      })
    );
  };

  console.log(items);

  return (
    <div className="App">
      <button onClick={handleClick}>Add new</button>
      <button onClick={handleDelete}>Delete last</button>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div ref={parentRef} className="container">
        {items?.map((item) => {
          return (
            <div
              onClick={() => handleResize(item)}
              style={{ height: item.resized ? "70px" : "20px" }}
              key={item.id}
              className="container-item"
            >
              <p>{item.name}</p>
            </div>
          );
        })}
        <div ref={itemsRef} id="title-div">
          {title ? "At the bottom" : "Not at the bottom"}
        </div>
      </div>
    </div>
  );
}

styles.css

.App {
  font-family: sans-serif;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin-top: 1rem;
}

* {
  margin: 0;
  padding: 0;
}

.container {
  width: 600px;
  height: 300px;
  background-color: gray;
  display: flex;
  flex-direction: column;
}

.container-item {
  width: 100%;
  background-color: hotpink;
}
#title-div {
  width: 100%;
  padding: 1rem;  
  background-color: blue;
  color: white;
}

我想做的

正如标题所示,我想查看 div 是否位于容器/父 div 的底部。 就是这样,该父 div 中的其他项目不能干扰该 div,从某种意义上说,添加、调整大小、删除这些项目不会突然改变我要分析的 div 的 position(看看它是否在屏幕底部)

我想出了我自己的解决方案,它总是有效的。 我只需要从 parentsRef 中减去“top”,从 itemsRef 中减去“top”,然后添加 itemsRef 的 clientHeight。 这样,它将始终位于容器的底部,无论我是否删除项目、调整它们的大小等。

编码

  useEffect(() => {
    if (
      parentRef?.current.clientHeight <=
      itemsRef?.current.getBoundingClientRect().top -
        parentRef?.current.getBoundingClientRect().top +
        itemsRef?.current.clientHeight
    ) {
      setTitle(true);
    } else {
      setTitle(false);
    }
  }, [parentRef, items, itemsRef]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM