在javascript中检查while循环中的元素中的类

时间:2014-04-22 17:01:56

标签: javascript while-loop

*这必须在javascript中完成,而不是jQuery。

我想要做的是在点击innerText类的h4时抓住<a>标记的btn-blue

我意识到我能做到:

element.parentElement.previousElementSibling.children[0].innerText;

但我真的想要更灵活的东西。

这是我到目前为止所做的,当它在控制台(chrome)中运行时它确实有效,但是一旦我将它添加到站点,它就不会拉入h4标签的innerText。

HTML

<div class="border-box clearfix">
    <div class="blah">
        <h4>h4 Title</h4>
        <p>paragraph</p>
    </div>
    <div class="head clearfix">
        <h4>h4 Title</h4>
        <p>paragraph</p>
    </div>
    <p class="float-right">
        <a href="/transactions/" class="btn-blue">anchor tag</a>
    </p>
</div>

的JavaScript

    var el = document.getElementsByClassName('head')[0];
    var parent = el.parentElement;

    while(parent && parent !== document.body && parent.className && parent.className.indexOf('head'){
        parent = parent.previousElementSibling;
    }

    var children = parent.childNodes;

        for(i=0; i < children.length; i++){
            var name = children[i].tagName;
                if(name.toLowerCase() === 'h4'){
                    var text = children[i].innerText || children[i].textContent;
                        return text;
                }
        }

我认为问题在于在while循环中使用parent.className.indexOf('head')。我想要确定的是元素是否具有head类,并且从SO问题(javascript - Test if an element contains a class)中,我看到我可以执行indexOf来检查并查看head是否在类中。< / p>

我还读到我可以使用.classList.contains('head'),但这不包括对早期IE浏览器的支持。

两个问题:

  1. 我是否以最佳方式获得innerText代码的<h4>? (这可能更适合codereview.stackoverflow.com)。

  2. 测试元素在while循环中是否有类的最佳方法是什么?

  3. SOLUTION:

    我最终只使用了@Greg Burghardt的解决方案,因为这对我来说是最容易调整并实现在Google跟踪代码管理器中使用的解决方案。最终的代码看起来像这样:

    function(){
        var element   = {{gtm.element}};
        var elementClass = 'border-box';
    
        while(element && !((" " + element.className + " ").indexOf(" " + elementClass + " ") > -1)){
            element = element.parentNode;
        }
    
        return element.querySelector('h4').innerText || element.querySelector('h4').textContent;
    }
    

3 个答案:

答案 0 :(得分:2)

这个怎么样?

function findHeaderText(element, className) {
    while (element && !element.classList.contains(className)) {
        element = element.parentNode;
    }

    var heading = element.querySelector("h1, h2, h3, h4, h5, h6"),
        text = heading.innerHTML;

    return text;
}


function handleClick(event) {
    var text = findHeaderText(event.target, "border-box");

    alert(text);
}

基本思路是从click事件的目标开始,然后向上走文档树,直到找到包含某个类的元素。从那里,使用querySelector方法获取第一个标题,然后获取其innerHTML或文本。

该函数可能会使用一些额外的错误处理,但我将其作为练习留给您。 :)

答案 1 :(得分:0)

看看这段代码。这可能看起来有点延伸,但它可以完成这项工作!

如果您需要解释,我会提供!

DEMO

<强> HTML

<div class="border-box clearfix">
    <div class="blah">
        <h4>h4 Title</h4>
        <p>paragraph</p>
    </div>
    <div class="head clearfix">
        <h4>h4 Title</h4>
        <p>paragraph</p>
    </div>
    <p class="float-right">
        <a href="#" onclick='return false' class="btn-blue">anchor tag</a>
    </p>
</div>


<div class="border-box clearfix">
    <div class="blah">
        <h4>h4 Title</h4>
        <p>paragraph</p>
    </div>
    <div class="head clearfix">
        <h4>h4 Title2</h4>
        <p>paragraph</p>
    </div>
    <p class="float-right">
        <a href="#" onclick='return false' class="btn-blue">anchor tag</a>
    </p>
</div>

<强>的Javascript

   function attach_(element,listener,ev,tf){

    if(element.attachEvent) {

        element.attachEvent("on"+listener,ev);

        }else{

        element.addEventListener(listener,ev,tf);

        }

    }

function getCls(clsNm){

    return clS = document.querySelectorAll ? document.querySelectorAll("."+clsNm) : document.getElementsByClassName(clsNm);

    }


function returnH4Text(el){

    wrapper = el.parentNode.parentNode;

    divs = wrapper.getElementsByTagName('div');

    if(divs.length>0){

    for(var i=0;i<divs.length;i++){

        if(divs[i].className.match('head')){

            return h4Text = divs[i].getElementsByTagName('h4')[0].innerText ? divs[i].getElementsByTagName('h4')[0].innerText : divs[i].getElementsByTagName('h4')[0].textContent;

            }

        }

    }

    }

var anchors = getCls('btn-blue');

if(anchors.length>0){

    for(var y=0;y<anchors.length;y++){

attach_(anchors[y],'mousedown',function(event){

    evt = event || window.event;
    trg = evt.target || evt.srcElement;

    alert(returnH4Text(trg));

    },false);

    }

}

答案 2 :(得分:0)

我更喜欢使用原型样式。这种OO风格更易于使用和理解。但不幸的是,你无法在IE8之前将原型添加到Element。所以这个解决方案只支持IE8 +和其他浏览器。如果要支持IE7,可以尝试将其更改为功能样式。 http://jsfiddle.net/Wa629/

Element.prototype.getParentByClassName = function(className) {
    if(!this.parentNode)
        return null;
    else if(this.parentNode.hasClass(className))
        return this.parentNode;
    else
        return this.parentNode.getParentByClassName(className);
};

Element.prototype.hasClass = function(className) {
    return (this.classList || this.className.split(' ')).contains(className);
};

Element.prototype.text = function() {
    return this.innerText || this.textContent;
};

if(!Array.prototype.contains)
{
    Array.prototype.contains = function(item) {
        for(var i = 0;i < item.length;++i)
            if(this[i] == item)
                return true;
        return false;
    }
}

现在,您可以使用以下方式获取标题:

element.getParentByClassName('border-box').querySelector('.head h4').text()