jQuery:检查BR是否存在第一个或最后一个元素,包括段落中的文本节点

时间:2011-02-06 17:26:08

标签: javascript jquery

我希望在jQuery中测试是否存在<br />作为段落中的第一个或最后一个元素(包括文本节点)。下面的两个例子是正确的:


<p>
    <br />
    Lorem ipsum dolor sit amet consectetur, adiscipling elit.
</p>


<p>
    Lorem ipsum dolor sit amet consectetur, adiscipling elit.
    <br />
</p>

虽然这个例子是假的:


<!-- This is false -->
<p>
    Lorem ipsum dolor sit amet consectetur, adiscipling elit
    <br />
    Lorem ipsum dolor sit amet consectetur, adiscipling elit.
</p>

如果为true,则class的{​​{1}}个diog-fail brbr将应用于包含的段落元素。

8 个答案:

答案 0 :(得分:3)

使用通用支持的DOM属性很容易。 jQuery在这里用得不多。

function isBr(el) {
    return el && el.nodeType == 1 && el.tagName == "BR";
}

function isWhitespaceNode(node) {
    return node.nodeType == 3 && /^\s*$/.test(node.data);
}

function isFirstOrLastChildBr(el) {
    var first = el.firstChild;
    if (isWhitespaceNode(first)) first = first.nextSibling;
    if (isBr(first)) return true;

    var last = el.lastChild;
    if (isWhitespaceNode(last)) last = last.previousSibling;
    if (isBr(last)) return true;

    return false;
}

因此,如果您的<p>元素具有id“foo”:

var $foo = $("#foo");
if ( isFirstOrLastChildBr($foo[0]) ) {
    $foo.addClass("diog-fail brbr");
}

更新多个元素的示例

将此应用于一组匹配的元素:

// All paragraphs
$("p").filter(function() {
    return isFirstOrLastChildBr(this);
}).addClass("diog-fail brbr");

答案 1 :(得分:2)

这是jsfiddle:

Using RegEx and If Else condition

    $('p').each(function() {
        var temp = this.innerHTML.replace(/^\s*|\s(?=\s)|\s*$/g, "").toLowerCase();
        if (temp.substring(0, 5) == '<br/>' || temp.substring(0, 4) == '<br>' || temp.substring(0, 6) == '<br />') {
            $(this).addClass('diog-fail brbr');
            console.log('start: true');
        } else if (temp.substring(temp.length - 5, temp.length) == '<br/>' || temp.substring(temp.length - 4, temp.length) == '<br>' || temp.substring(temp.length - 6, temp.length) == '<br />') {
            $(this).addClass('diog-fail brbr');
            console.log('end: true');
        } else {
            console.log('none: ' + false);
        }
    });

首先获取所有段落,然后在innerHTML上使用RegEx,并通过删除空格,换行符等将其展平。然后,如果还有条件,请查看第一个和最后几个子字符串是否匹配<br>, <br/> or <br />

答案 2 :(得分:2)

根据您提供的测试用例,这将有效:

$('p').each(function ()
{
    var $this = $(this),
        $brs = $this.children('br'),
        numBRs = $brs.length,
        firstBR = $brs.get(0),
        firstBRprev = firstBR ? firstBR.previousSibling : null,
        firstBRnext = (firstBR && numBRs == 1) ? firstBR.nextSibling : null,
        lastBR = numBRs > 1 ? $brs.get(numBRs) : null,
        lastBRnext = lastBR ? lastBR.nextSibling : null;

    if ((firstBRprev && !firstBRprev.nodeValue.trim()) ||
        (firstBRnext && !firstBRnext.nodeValue.trim()) ||
        (lastBRnext && !lastBRnext.nodeValue.trim()))
    {
        console.log(this);
        $this.addClass('diog-fail brbr');
    }
});

jQuery并不多,因为jQuery隐藏了许多讨厌的DOM业务,包括文本节点。

Demo →

答案 3 :(得分:0)

怎么样:

function brIsFirstOrLast(selector) {
    var contents = $(selector).contents().filter(function() {
        return this.nodeType !== 3 || $.trim($(this).text().replace("\n", "")) !== "";
    });

    var last = contents.last()[0];
    var first = contents.first()[0];

    return (!!last.tagName && last.tagName.toLowerCase() === "br") ||
        (!!first.tagName && first.tagName.toLowerCase() === "br");
}

用法:

brIsFirstOrLast("p:first");

请注意,此函数需要选择器返回一个结果。您可以添加更多验证,但这应该可以让您开始。

看到它正常工作:http://jsfiddle.net/andrewwhitaker/F2dwm/

答案 4 :(得分:0)

我建议使用一点RegExp:

//returns true if there is a <br/>   at begin or end, otherwise false 
$.trim($('p').html()).match(/(^<br\s*\/?>|<br\s*\/?>$)/i)

否则,您将不得不在处理空格的浏览器依赖性方面遇到困难,如textNodes

答案 5 :(得分:0)

好的,这是一个(只有略微笨重)的方式,给出以下html用于演示目的:

HTML

<div class="testThis">
    <p>Some text, or other with a 'br' at the end.<br /></p>
</div>

<div class="testThis">
    <p><br />Some more text, with a 'br' at the beginning.</p>
</div>

<div class="testThis">
    <p>Some text with a 'br' <br /> in the middle</p>
</div>

CSS

.testThis {
    border: 1px solid #ccc;
    margin: 0 auto 1em auto;
    padding: 0.5em;
    width: 80%;
    border-radius: 1em;
}

.brFirst {
    border-color: #f00;
}

.brLast {
    border-color: #00f;
}

的jQuery

$('.testThis').each(
    function(){
        var haystack = $(this).find('p').html();
        var needle = '<br>';

        //alert(haystack.indexOf('<br>'));
        if (haystack.indexOf(needle) == 0) {
            $(this).addClass('brFirst');
        }
        else if (haystack.indexOf(needle) == (haystack.length - needle.length)) {
            $(this).addClass('brLast');
        }
    });

JS Fiddle demo


已编辑更新jQuery,使用trim()方法(因此将删除变量haystack的开头和结尾处的空格):

$('.testThis').each(
    function(){
        var haystack = $(this).find('p').html().trim();
        var needle = '<br>'; // Tested in Chrome the `<br />` element is converted to `<br>`

        if (haystack.indexOf(needle) == 0) {
            $(this).addClass('brFirst');
        }
        else if (haystack.indexOf(needle) == (haystack.length - needle.length)) {
            $(this).addClass('brLast');
        }
    });

Updated JS Fiddle demo

答案 6 :(得分:0)

要从嵌入式编辑器中的<br>内删除<p>,我使用:

target.find('p').find('br').each(function () {
    if(! $(this)[0].nextSibling || ! $(this)[0].previousSibling) $(this).remove();
    });

测试和更改<p>课程:

target.find('p').each(function () {
    let ancestor = $(this);
    $(this).find('br').each(function () {
        console.log(! $(this)[0].nextSibling || ! $(this)[0].previousSibling ? 'edge' : '!edge');
        ancestor.addClass('zorglubissime');
    });
});

我希望这会有所帮助......

糟糕!这更好:

target.find('p').each(function () {
    let ancestor = $(this);
    $(this).find('br').each(function () {
        if(! $(this)[0].nextSibling || ! $(this)[0].previousSibling)
            ancestor.addClass('zorglubissime');
    });
});

答案 7 :(得分:-1)

使用:first-child:last-child选择器

所以$('p > br:first-child, p > br:last-child').length > 0