如何使用JavaScript修改内联toc元素的类?

如何使用JavaScript修改内联toc元素的类?,javascript,html,css,Javascript,Html,Css,问题 您好,我正在创建一个简单的导航站点,我想知道如何更改/添加一个类到右侧内联toc的li元素之一,以使用css对其进行样式设置 我的网页到目前为止 我希望实现的页面行为: (如果上下滚动主页,您将看到右侧toc元素的样式发生变化) 在这里可以看到同样的行为: (上下滚动页面时,请参见右侧toc更改) 我曾试图研究本页后面的JavaScript,但很难理解,而且脚本看起来过于复杂 有什么想法吗 谢谢 萨钦 注意-问题已得到回答,并根据下面给出的答案更新了上面链接中的代码 使用的代码 到目前

问题

您好,我正在创建一个简单的导航站点,我想知道如何更改/添加一个类到右侧内联toc的li元素之一,以使用css对其进行样式设置

我的网页到目前为止

我希望实现的页面行为:

(如果上下滚动主页,您将看到右侧toc元素的样式发生变化)

在这里可以看到同样的行为: (上下滚动页面时,请参见右侧toc更改)

我曾试图研究本页后面的JavaScript,但很难理解,而且脚本看起来过于复杂

有什么想法吗

谢谢

萨钦

注意-问题已得到回答,并根据下面给出的答案更新了上面链接中的代码

使用的代码

到目前为止,我拥有的CSS:

HTML的相关部分



正如我所理解的,你不想给它一个风格,只是添加一个类? 如果你想直接给一个li一些样式,例如,你可以这样做

document.getElementsByTagName("li").addEventListener("click",()=>{
 this.style = "color:red";
})
但我想你应该添加已经准备好的类,这样你就需要ClasList了

document.getElementById("myDIV").classList.add("mystyle");
加上

除去

document.getElementById("myDIV").classList.toggle("mystyle");
切换


在这种情况下,您需要分别向它们添加类添加ID或相同的类,以按类[0]、类[1]等获取每个ID。。。 你需要两样东西

 `document.body.scrollTop;`
对于每个高度,添加如上所示的等级 e、 g

如果要从以前的版本中删除,请使用更好的版本

if(document.body.scrollTop == 100px){
    for(let i = 0;i<classOfLis.length,i++){
    classOfLis[i].classList.remove("selected");
}
    document.getElementById("myDIV").classList.add("mystyle");
}
if(document.body.scrollTop==100px){

对于(设i=0;i我已经用一个
段落
类包围了每个部分的内容,该类用于观察,并且还向其内容添加了一个类
内容
——该类实际上还没有在任何地方使用,但我仍然建议这样做

编辑:综合您的想法,如何在多个交点的情况下选择图元


尝试jQuery toggleClass或AddClass问题解决了一半。除了我的页面之外,没有给出与以下相同的行为:(例如,当两个h2/h3在视口中时,或者对于较长的部分,h2/h3标记从视口中消失)根据Paul Belowi Nairi的评论,问题完全解决了。我想添加到li的类叫做“selected”-指的是上面的CSS脚本,它将对任何li应用正确的样式,类为“selected”。所以JavaScript需要做的就是添加“selected”当页面的这一部分被滚动到时,我正试图弄明白如何将类添加到正确的li标记的类中。在这种情况下,您需要分别添加ID或相同的类,以便按类[0],类[1]获取每个li标记等等…您需要两件事
document.body.scrollTop;
并为每个高度添加如上所示的类,例如if(document.body.scrollTop==100px){document.getElementById(“myDIV”).classList.add(“mystyle”);},如果您想从以前的if(document.body.scrollTop==100px){for(让我=0;我感谢你的帮助Nairi。根据Paul提供的评论,经过进一步的讨论,我现在有了一个可行的解决方案thinking@Sachin我要出去一段时间。我需要休息一下。所以,不要怀疑我这边没有更多的答案祝你的项目好运!谢谢Paul。我刚刚看到了你的代码。我想我已经设法解决了多个条目可见的问题(使用上面更新的JS代码)-我决定如果两个元素可见,则显示最低的元素。代码很长,因为isIntersecting类是只读的,所以我必须创建另一个名为visible的数组-但我不确定代码是否可以简化。再次感谢您的帮助。我将再次检查,看看是否可以解决问题的其他部分(长长的部分)和你的代码。@Sachin检查一下:我整合了你的想法,并对其进行了改进和简化。我也编辑了我的文章。现在我真的出来了。;)再次感谢!效果很好,但如果你向上滚动,最后一项仍然突出显示…:(我正在研究一个完整的解决方案,合并(相当不情愿地)一个滚动事件..将发布解决方案soonOk-终于完成了。您设置选择器的一行,放置了两大块代码,因此非常有用!以上是迄今为止我所能做的最好的事情。我想在处理程序函数中放置用于检测滚动方向的滚动函数,但只有在处理程序函数n被解雇了,我得到了一个glitchy行为(handler是一个异步函数?),所以我(不定期地)将它放在一个窗口中。onscroll包装器-现在…我得到了我想要的粘性菜单行为-不需要包装“p”标记。这比我最初想象的要困难得多!
document.getElementById("myDIV").classList.remove("mystyle");
document.getElementById("myDIV").classList.toggle("mystyle");
 `document.body.scrollTop;`
 if(document.body.scrollTop == 100px){
     document.getElementById("myDIV").classList.add("mystyle");
 }
if(document.body.scrollTop == 100px){
    for(let i = 0;i<classOfLis.length,i++){
    classOfLis[i].classList.remove("selected");
}
    document.getElementById("myDIV").classList.add("mystyle");
}
let observer = new IntersectionObserver(handler, {
  threshold: [0.2]
});
let selection;
let paragraphs = [...document.querySelectorAll("#main .paragraph")];
let submenu = [...document.querySelectorAll("ul.section-nav a")];
let paragraphMenuMap = paragraphs.reduce((acc, p) => {
  let id = p.firstElementChild.id;
  acc[id] = submenu.find(a => a.getAttribute("href") === "#" + id);
  return acc;
}, {})

paragraphs.forEach(elem => observer.observe(elem));

function handler(entries) {

  // Update selection with current entries.
  selection = (selection || entries).map(
    s => entries.find(e => e.target.firstElementChild.id === s.target.firstElementChild.id) || s
  );

  // Find last visible/intersecting (use a copied array for that, since reverse is an in place method)
  let lastVisibleId = [...selection].reverse().find(x => x.isIntersecting).target.firstElementChild.id;

  for (s of selection) {
    let targetId = s.target.firstElementChild.id;
    // avoid searching the dom and just get the entry from our map.
    let a = paragraphMenuMap[targetId];

    if (lastVisibleId === targetId) {
      let parentElem = a;
      // ensure that parent menu entries are selected too
      while (parentElem = parentElem.parentElement.closest(".toc-entry")) {
        parentElem.classList.add("selected");
      }
    } else {
      a.parentElement.classList.remove("selected");
    }
  }
};