【问题标题】:How to access nth parent node如何访问第n个父节点
【发布时间】:2019-03-11 23:54:29
【问题描述】:

我尝试获取子元素的父 div 的高度。

我有一个带有 class="Parent" 的 Parent div 这也有 n 子元素,如 <div data-elementid="el_ryz-E9a349" class="row">

Parent 修复了height: 220px,如果不对该孩子执行scrollIntoView(),我需要知道子元素 (n) <div data-elementid="el_ryz-E9a349" class="row"> 是否出现在父级高度。

重要的是,我无法删除这两个元素,将 div<div class="container" 清空,因为这会影响我的设计。

...
const scrollToBottom = () => {
    const elementNode = document.querySelector(`[data-elementid='${action.payload.id}']`);
    const parentElementNode = elementNode.parentNode;
    const elementsHeight = parentElementNode.offsetHeight;
    const menuContainer = parentElementNode.parentNode.offsetHeight;

    if (elementsHeight > menuContainer) {
      elementNode.scrollIntoView({
        behavior: 'smooth',
        block: 'end',
      });
    }

 };
setTimeout(scrollToBottom, 200);
...

很明显,如果我有n 子元素,那么让elementNode.parentNode.parentNode.parentNode 访问父节点以获取高度属性是多余的。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    使用这个函数在你的元素父母中搜索你的父类名:

    const getParent = (element, cls) => {
        if (element && element.parentElement) {
            const parentClassName = element.parentElement.className;
            if (element.parentElement && parentClassName && parentClassName.match(new RegExp(cls, 'g'))) {
                return element.parentElement; // Found it
            }
            getParent(element.parentElement, cls);
        } else {
            return false; // No parent with such a className
        }
    }
    
    const scrollToBottom = () => {
        const elementNode = document.querySelector(`[data-elementid='${action.payload.id}']`);
        const parentElementNode = getParent(elementNode, 'parent'); // second arg is the parent classname you looking for.
    
        if (parentElementNode) {
            const elementsHeight = parentElementNode.offsetHeight;
            const menuContainer = parentElementNode.parentNode.offsetHeight;
    
            if (elementsHeight > menuContainer) {
                elementNode.scrollIntoView({
                    behavior: 'smooth',
                    block: 'end',
                });
            }
        }
    
        console.log('no parent found!')
    
    };
    
    setTimeout(scrollToBottom, 200);
    

    使用数据属性选择:

    const getParentWithAttr = (element, attr) => {
        if (element && element.parentElement) {
            const parentElement = element.parentElement;
            if (parentElement && parentElement.getAttribute('data-attr') === attr) {
                return parentElement; // Found it
            }
            getParent(parentElement, attr);
        } else {
            return false; // No parent with such a className
        }
    }
    

    用例应该是这样的:

    <div id="..." class="..." data-attr="parent">// parrent
        ... // chilren
    </div>
    
    
    getParentWithAttr(document.querySelector('.element'), 'parent');
    

    【讨论】:

    • 感谢您的快速回答,我无法使用 classnames,在开发模式下它可以 100% 工作,但在生产中 classNames 是散列的。这就是我使用 data-attributes 和 querySelector 来获取该节点的原因。我需要在页面的两个地方使用此功能,并且父级的子级顺序不同。
    • 好的,只需将 className 替换为 dataAttr 并在全局中定义该函数,然后将其导入您想要使用的地方。你会没事的。
    • 我在答案末尾添加了一个带有data-attr 的示例。希望对您有所帮助。
    【解决方案2】:

    由于问题的标签显示 React.js,我将改为参考 ReactJS how to scroll to an element。这使用 React refs 并使您的代码更简单。话虽如此,看起来问题实际上是在静态 HTML 上使用纯 JavaScript。

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    
    class SampleComponent extends Component {
      scrollToDomRef = () => {
        const myDomNode = ReactDOM.findDOMNode(this.myRef.current)
        myDomNode.scrollIntoView()
      };
    
      render() {
        return <> // '<></>' is a React 16.3.0+ feature, use <div> if previous
          <button onClick={this.scrollToDomRef}>Click me</div>
          <div ref={ re => { this.myRef = re } }></div>
        </>
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 2020-09-15
      • 2022-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-10-26
      相关资源
      最近更新 更多