返回位于视口中的组件的ID

huangapple go评论77阅读模式
英文:

Returning the ID of the component which is in viewport

问题

我想返回当前在视口中的组件的值。为了做到这一点,我参考了一些文档,并认为可以使用 Ant Design 来实现。

我参考的 Ant Design 函数是 Anchor。我想获取 Anchor 标签的 key 值。
有一个文档解释了如何使用它,但不知道如何使用它来获取当前组件的值。

我在我的代码中创建了三个组件,想在顶部显示它们的编号。我可以知道如何做吗?

对不起,问题可能有点难以理解,但如果您查看我的代码或下面的 CodeSandBox,我相信您会更好地理解。谢谢

代码:

import styled from "styled-components";
import { Anchor } from "antd";
import { useState } from "react";

export default function App() {

  // 尝试使用这些,但失败了
  const [currentView, setCurrentView] = useState();
  console.log(currentView);
  window.addEventListener("scroll", () => {});

  return (
    <Wrap>
      <Anchor
        targetOffset={currentView}
        style={{ display: "none" }}
        items={[
          {
            key: "part-1",
            href: "#part-1",
            title: "Part 1"
          },
          {
            key: "part-2",
            href: "#part-2",
            title: "Part 2"
          },
          {
            key: "part-3",
            href: "#part-3",
            title: "Part 3"
          }
        ]}
      />
      <div className="fixed">当前组件{currentView}</div>
      <div>{currentView}</div>
      <div id="part-1" className="compo1">
        组件1
      </div>
      <div id="part-2" className="compo2">
        组件2
      </div>
      <div id="part-3" className="compo3">
        组件3
      </div>
    </Wrap>
  );
}

const Wrap = styled.div`
  border: 3px solid black;
  width: 100vw;
  box-sizing: border-box;

  .fixed {
    position: sticky;
    top: 0;
  }

  .compo1 {
    border: 3px solid red;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }

  .compo2 {
    border: 3px solid blue;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }

  .compo3 {
    border: 3px solid green;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }
};

CodeSandBox:
CodeSandBox

英文:

I want to return the value of the component currently in viewport.
To do this, I referd some documents, and thought I could make it by using Ant Design.

The function I refered to Ant Design is Anchor. I want to get key value of Anchor tag.
There is a document explaining usage of it, but don't know how to use it to get value of current component.

I made three components in my codes. And want to show their number at the top.
Can I know how to make it?

Sorry for difficult question to understand but I'm sure you could understand better if you see my code or CodeSandBox below. Thanks

code :

import styled from &quot;styled-components&quot;;
import { Anchor } from &quot;antd&quot;;
import { useState } from &quot;react&quot;;

export default function App() {

  //tried to use these, but failed
  const [currentView, setCurrentView] = useState();
  console.log(currentView);
  window.addEventListener(&quot;scroll&quot;, () =&gt; {});

  return (
    &lt;Wrap&gt;
      &lt;Anchor
        targetOffset={currentView}
        style={{ display: &quot;none&quot; }}
        items={[
          {
            key: &quot;part-1&quot;,
            href: &quot;#part-1&quot;,
            title: &quot;Part 1&quot;
          },
          {
            key: &quot;part-2&quot;,
            href: &quot;#part-2&quot;,
            title: &quot;Part 2&quot;
          },
          {
            key: &quot;part-3&quot;,
            href: &quot;#part-3&quot;,
            title: &quot;Part 3&quot;
          }
        ]}
      /&gt;
      &lt;div className=&quot;fixed&quot;&gt;currentcomponent : {currentView}&lt;/div&gt;
      &lt;div&gt;{currentView}&lt;/div&gt;
      &lt;div id=&quot;part-1&quot; className=&quot;compo1&quot;&gt;
        components 1
      &lt;/div&gt;
      &lt;div id=&quot;part-2&quot; className=&quot;compo2&quot;&gt;
        components 2
      &lt;/div&gt;
      &lt;div id=&quot;part-3&quot; className=&quot;compo3&quot;&gt;
        components 3
      &lt;/div&gt;
    &lt;/Wrap&gt;
  );
}

const Wrap = styled.div`
  border: 3px solid black;
  width: 100vw;
  box-sizing: border-box;

  .fixed {
    position: sticky;
    top: 0;
  }

  .compo1 {
    border: 3px solid red;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }

  .compo2 {
    border: 3px solid blue;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }

  .compo3 {
    border: 3px solid green;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 70vh;
  }
`;

CodeSandBox:
CodeSandBox

答案1

得分: 1

你可以使用Intersection Observer API来观察视口中的组件,你可以在useEffect钩子中添加观察器,不需要依赖项,以便仅在组件初始加载时运行。

import styled from "styled-components";
import { Anchor } from "antd";
import { useState, useEffect } from "react";

export default function App() {
  const [currentView, setCurrentView] = useState();
  window.addEventListener("scroll", () => {});

  useEffect(() => {
    const components = document.querySelectorAll(".comp");
    const componentObserver = new IntersectionObserver(function (
      entries,
      observer
    ) {
      entries.forEach(function (entry) {
        if (entry.isIntersecting) {
          setCurrentView(entry.target.id);
        }
      });
    });
    components.forEach((comp) => {
      componentObserver.observe(comp);
    });
  }, []);

  return (
    <Wrap>
      <Anchor
        targetOffset={currentView}
        style={{ display: "none" }}
        items={[
          {
            key: "part-1",
            href: "#part-1",
            title: "Part 1"
          },
          {
            key: "part-2",
            href: "#part-2",
            title: "Part 2"
          },
          {
            key: "part-3",
            href: "#part-3",
            title: "Part 3"
          }
        ]}
      />
      <div className="fixed">当前组件{currentView}</div>
      <div>{currentView}</div>
      <div id="part-1" className="compo1 comp">
        组件 1
      </div>
      <div id="part-2" className="compo2 comp">
        组件 2
      </div>
      <div id="part-3" className="compo3 comp">
        组件 3
      </div>
    </Wrap>
  );
}

const Wrap = styled.div`
  border: 3px solid black;
  width: 100vw;
  box-sizing: border-box;

  .fixed {
    position: sticky;
    top: 0;
  }

  .compo1 {
    border: 3px solid red;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 100vh;
  }

  .compo2 {
    border: 3px solid blue;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 100vh;
  }

  .compo3 {
    border: 3px solid green;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 100vh;
  }
`;

返回位于视口中的组件的ID

英文:

You can use Intersection Observer API, to observe the component in the viewport, you can add the observer in the useEffect hook without dependences to only run on the component initial load.

import styled from &quot;styled-components&quot;;
import { Anchor } from &quot;antd&quot;;
import { useState, useEffect } from &quot;react&quot;;
export default function App() {
const [currentView, setCurrentView] = useState();
window.addEventListener(&quot;scroll&quot;, () =&gt; {});
useEffect(() =&gt; {
const components = document.querySelectorAll(&quot;.comp&quot;);
const componentObserver = new IntersectionObserver(function (
entries,
observer
) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
setCurrentView(entry.target.id);
}
});
});
components.forEach((comp) =&gt; {
componentObserver.observe(comp);
});
}, []);
return (
&lt;Wrap&gt;
&lt;Anchor
targetOffset={currentView}
style={{ display: &quot;none&quot; }}
items={[
{
key: &quot;part-1&quot;,
href: &quot;#part-1&quot;,
title: &quot;Part 1&quot;
},
{
key: &quot;part-2&quot;,
href: &quot;#part-2&quot;,
title: &quot;Part 2&quot;
},
{
key: &quot;part-3&quot;,
href: &quot;#part-3&quot;,
title: &quot;Part 3&quot;
}
]}
/&gt;
&lt;div className=&quot;fixed&quot;&gt;currentcomponent : {currentView}&lt;/div&gt;
&lt;div&gt;{currentView}&lt;/div&gt;
&lt;div id=&quot;part-1&quot; className=&quot;compo1 comp&quot;&gt;
components 1
&lt;/div&gt;
&lt;div id=&quot;part-2&quot; className=&quot;compo2 comp&quot;&gt;
components 2
&lt;/div&gt;
&lt;div id=&quot;part-3&quot; className=&quot;compo3 comp&quot;&gt;
components 3
&lt;/div&gt;
&lt;/Wrap&gt;
);
}
const Wrap = styled.div`
border: 3px solid black;
width: 100vw;
box-sizing: border-box;
.fixed {
position: sticky;
top: 0;
}
.compo1 {
border: 3px solid red;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.compo2 {
border: 3px solid blue;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.compo3 {
border: 3px solid green;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
`;

返回位于视口中的组件的ID

huangapple
  • 本文由 发表于 2023年2月16日 15:16:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75468925.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定