【问题标题】:How do I update an element class based on a separate element's active class?如何根据单独元素的活动类更新元素类?
【发布时间】:2019-07-18 16:50:50
【问题描述】:

我试图在 Chaptr 的网站上重现效果,大约在页面的一半处,滚动经过列表元素会更改粘性/固定的单独元素的类别。此处示例:https://chaptr.studio/,“品牌、创意、代码、增长”部分。

我已经设法使部分效果与以下代码一起使用,尽管它不是最干净的。无论如何,我可以得到左侧的元素列表“投资、教育、指导”,以匹配非粘性列表正在发生的事情。

const halfWindow = (window.innerHeight / 2) - 50
const listItems = document.querySelectorAll('.scroll-item')

const firstItem = listItems[0]
const lastItem = listItems[listItems.length - 1]

const updateSection = () => {
  const pixels = window.pageYOffset

  listItems.forEach(item => {

    // find the position of each item
    const itemTop = item.offsetTop - pixels
    const itemBottom = (item.offsetTop + item.offsetHeight) - pixels

    // first item top
    const firstItemTop = firstItem.offsetTop - pixels
    const firstItemBottom = (firstItem.offsetTop + firstItem.offsetHeight) - pixels

    // target the first item in the array
    if (firstItemBottom <= halfWindow) {
      firstItem.classList.remove('active')
      firstItem.classList.remove('current')
    } else if (firstItemBottom >= halfWindow) {
      firstItem.classList.add('current')
    }

    // working sort of - clean up
    if ((itemTop <= halfWindow) && (itemBottom <= halfWindow)) {
      item.classList.remove('active')   
      if (item === lastItem) {
        item.classList.add('current')
      }
    } else if ((itemTop <= halfWindow) && (itemBottom >= halfWindow)) {
      item.classList.add('active')
      item.classList.remove('current')
    } else {
      item.classList.remove('active')
    }

  })
}

document.addEventListener("scroll", updateSection)

这是一个代码笔示例: https://codepen.io/anon/pen/gVOZzp?

我需要弄清楚的主要一点是,当右侧的每个列表项都变为“活动”时,如何将左侧列表项与活动匹配。

【问题讨论】:

    标签: javascript jquery html scroll


    【解决方案1】:

    一种方法是这样的。首先,选择所有内部项目以将它们存储在global variable 中:

    const innerItems = document.querySelectorAll('.sticky-inner li');
    

    然后,你可以在updateSectionfunction的末尾加上这个:

      if (document.querySelector('.sticky-inner .active')) {
        document.querySelector('.sticky-inner .active').classList.remove('active');
      }
      if (listItems[0].classList.contains('active')) {
        innerItems[0].classList.add('active');
      } else if (listItems[1].classList.contains('active')) {
        innerItems[1].classList.add('active');
      } else if (listItems[2].classList.contains('active')) {
        innerItems[2].classList.add('active');
      }
    

    它将始终比较双手以匹配它们并添加/删除activeclass

    【讨论】:

    • 非常感谢 Azametzin,这让我开始测试其他方法。
    【解决方案2】:

    最后我像 Azametzin 所说的那样设置了变量:

    const innerItems = document.querySelectorAll('.sticky-inner li')
    

    然后使用classList.containsgetAttribute 比较两个列表——检查它们是否匹配。见以下代码:

    const updateSectionHeadings = () => {
    
      listItems.forEach(item => {
    
        // if the item has the active or current class
        if (item.classList.contains('active') || item.classList.contains('current')) {
    
          // set itemData to the data attribute's value
          let itemData = item.getAttribute('data-name')
    
          // loop through the section list
          innerItems.forEach(innerItem => {
            // set innerItemData to the data attribute's value
            let innerItemData = innerItem.getAttribute('data-name')
    
            if (itemData !== innerItemData) {
              // if itemData is not the same as innerItemData
              innerItem.classList.remove('active')
            } else if (itemData === innerItemData) {
              // if itemData is the same as innerItemData
              innerItem.classList.add('active')
            }
    
          })
    
        }
    
      })
    
    }
    
    document.addEventListener("scroll", updateSectionHeadings)
    window.addEventListener("resize", updateSectionHeadings)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      相关资源
      最近更新 更多