遍历HTML结构以搜索属性

Traversing an HTML structure searching for attribute

本文关键字:搜索 属性 结构 HTML 遍历      更新时间:2023-09-26

我有一个包含两个方法up()down()traverse对象,这些方法的目标是在html中向上或向下循环,查找特定dataset-attribute的第一个出现,如果找到,则返回该元素。

"特定"dataset-attribute作为参数传递到方法中,例如我们有data-updata-down

var o1 = traverse.up(e.target,'up');
var o2 = traverse.down(e.target,'down');

现在,向上遍历方法traverse.up(e.target,'up')工作得很好,因为parentNode与单击的元素(e.target)是一对一的关系。然而,我的问题是,当尝试向下遍历时,因为单击的元素可能有多个子元素,我需要循环遍历每个子元素及其子元素,等等…搜索dataset-down属性。

问题:为什么我的traverse.down(e.target,'down')方法不返回具有dataset-down属性的HTML元素的第一个出现?

这是JSFiddle演示

//HTML

<body>
    <div id='black'>
        <div id='red' data-up='upwards'>
            <div id='blue'>
                <div id='green'>
                    <div id='yellow'></div>
                    <div id='royalblue' data-down='downwards'></div>
                    <div id='fuscia'></div>
                </div>
            </div>
        </div>  
    </div>
</body>

//JS-

function init(){
    document.getElementById('black').addEventListener('click', handles);
}
function handles(e){
//  var o1 = traverse.up(e.target,'up');
    var o2 = traverse.down(e.target,'down');
    console.log(o2);
}
traverse={
    up:function(o,a){
        while(o.dataset[a] === undefined){
            if(o.parentNode.tagName === 'HTML') break;
            o = o.parentNode;
        }
        return o;
    },
    down:function(o,a){
        if(o.dataset[a] === undefined){
            if(o.children.length > 0){
                o.children.forEach((o)=>{
                    traverse.down(o,a);
                })
            }
            else console.log("DOES NOT HAVE CHILD");
        }
        else{
            //console.log(o) **this does return the correct element with the data-down attribute however the return statement below isn't returning it back to the original caller.
            return o;
        }
    }
};
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
document.onreadystatechange=()=>(document.readyState === 'interactive') ? init() : null;

类似这样的东西:

if(o.children.length > 0){
    o.children.forEach((o)=>{
        var t = traverse.down(o,a);
        if (t) return t; // return the first element that matches. There might be more but we're ignoring them
    });
    // none were found
    return false;
}