3

我需要使用 jQuery 更改一些 HTML - (我无法控制 HTML,因此我需要使用一些客户端来进行这种轻微的更改)

如果 a<br />是名为“列”的 div 中的第一个元素,那么我需要将其删除。

所以:

<div class="column">
   <br />text here lorem ipsum blah<br />

会成为:

<div class="column">
   text here lorem ipsum blah<br />

注意,我不想去掉所有的<br />标签,只有当<br />标签直接跟在开始标签之后。

我曾希望这样的事情会奏效,但没有快乐

$('<div class="column"><br />').replaceWith('<div class="column">');

任何帮助表示赞赏!非常感谢!

4

6 回答 6

3

Something like this should do it :

var pattern = /^<br\/>/;
$("<div.column").each(function() {
    var $this = $(this),
        text = $this.text();
    if(text.match(pattern)) {
        $this.text(text.replace('<br/>', ''))
    }
});

(ignore - left in place so as to make sense of comments below)

EDIT

Try this :

var pattern = /^\n*\s*<br>/;
$("div.column").each(function() {
    var $this = $(this),
        html = $this.html();
    if(html.match(pattern)) {
        $this.html(html.replace(pattern, ''))
    }
});

DEMO

As @minitech points out, any event handlers and data attached to the original HTML will be lost, so either :

  • do the replacement before attaching any event handlers/data
  • take measures to re-instantiate event handlers/data after replacement
  • delegate event handling to the container element
  • do something completely different that is non-destructive - see @minitech's answer.

Second EDIT

After much playing, at last something concise. Try this near 100% jQuery version of @minitech's approach :

$('.column').each(function() {
    $.each(this.childNodes, function(i, c) {
        return !$(c).filter('br').remove().end().text().trim(); 
    });
});

DEMO

Explanation: The inner loop visits each childNode in turn; its single statement removes the current node if it is a <br> but allows the loop to progress only if the current node is blank or whitespace. Note judicious use of .end() to keep everything in one method chain.

Efficiency: Poor - that jQuery method chain must consume a few CPU cycles but that seems a small price to pay.

Readabiity: Close to nada.

Third EDIT

With a mild mod, this will handle any combination of leading whitespace/BRs/HTML comments :

$('.column').each(function() {
    $(this.childNodes).each(function(i, c) {
        return !$(c).filter('br').remove().end().text().trim(); 
    });
});

The difference from the last version is that the jQuery object $(this.childNodes) remains unaffected by node removal, whereas the raw this.childNodes is affected and the .each() loop doesn't scan properly. At least, that's my best attempt at an explanation.

DEMO

于 2012-07-03T20:08:31.607 回答
1

原始节点操作!

$('.column').each(function() {
    var firstChild = this.firstChild;

    while(firstChild && (firstChild.nodeType === 3 && /^\s*$/.test(firstChild.nodeValue) || firstChild.nodeType === 8)) {
        firstChild = firstChild.nextSibling;
    }

    if(firstChild && firstChild.nodeName === 'BR') {
        this.removeChild(firstChild);
    }
});​

这是一个演示。

于 2012-07-03T20:07:28.353 回答
0

如果它在第一个位置,如何删除它?

var relevantDiv = $('#someDiv');
var divHtml = relevantDiv.html();
if ($.trim(divHtml).indexOf('<br') == 0)
{
    relevantDiv.html(divHtml.substr(divHtml.indexOf('>')+1));
}

一开始就处理各种 br 标签和空格。

于 2012-07-03T20:01:47.627 回答
0

怎么样:

$("div.column").each(function(){
    var ws=true;
    $(this).contents().filter(function(){
        if (this.nodeName.toLowerCase() === 'br' && ws){
            ws = false;
            return true;
        }
        ws &= $.trim($(this).text()) === "" && this.nodeName === "#text";
        return false;
    }).remove();
});​

http://jsfiddle.net/bnWM7/1/

于 2012-07-03T21:13:26.797 回答
-1

这些人怎么样:

var br = $("div.column br:first-child");

if(br.length > 0 && br[0].previousSibling == null)
{
    br.remove();
}

http://jsfiddle.net/zeDn3/3/

于 2012-07-03T20:59:48.003 回答
-2

尝试这样的事情:

    var content = $('div.column').html();
    // there remove <br /> from content if it exits
    $('div.column').empty().append(content);
于 2012-07-03T20:00:37.177 回答