【问题标题】:(jquery) change nested same html tag to other bbcode tag(jquery) 将嵌套的相同 html 标签更改为其他 bbcode 标签
【发布时间】:2012-03-26 15:50:22
【问题描述】:

好的,这就是我所拥有的:

<div id="mydiv">
<font color="green"><font size="3"><font face="helvetica">hello world</font></font></font>
</div>

我知道标签很奇怪,但那是网站制作的。 所以基本上我想把字体标签改成bbcdoe标签,我写的jquery代码:

$("#mydiv").find("font").text(function(){
    var text = $(this).text();
    var size = $(this).attr("size");
    var color = $(this).attr("color");
    var face = $(this).attr("face");;
    if(size!=undefined){
        return '[size="'+size+'"]'+text+'[/size]';
    }
    if(color!=undefined){
        return '[color="'+color+'"]'+text+'[/color]';
    }
    if(face!=undefined){
        return '[type="'+face+'"]'+text+'[/type]';
    }

});

所以我得到的只是:[color="green"] hello world [/color]。总是只有第一个标签。有什么想法吗?

ps:我都试过了,replaceWith,html(),结果都一样。只有第一个标签是变化的。

【问题讨论】:

  • .text() jQuery 函数返回元素内的文本,而不是元素内的 HTML,因此任何 HTML 标记都将被删除。您的代码还有其他问题,例如最后一个 if 检查 size 时应该检查 face
  • 顺便说一下,您的示例代码与您声称的输出不匹配。如果真的要[color="green"] hello world [/color],就应该输出'[color="'+color+"]'+text+'[/color]',即包括text,不包括第一个]

标签: javascript jquery html tags


【解决方案1】:

它不起作用的原因是因为当你打电话时

$("#mydiv").find("font").text("New text")

对于每个字体标签,从第一个标签开始,它将替换该标签内的文本。

这是一个向您展示发生了什么的示例。

Example |代码

$fonts = $("font","#mydiv");

console.log($fonts.text());

$fonts.text(function(){
    return "New text";
});

console.log($fonts.text());

这里是一个例子,你可以这样做

Example |代码

jQuery.fn.reverse = [].reverse;

var attributes= ["size", "color", "face"];
var text = $.trim($("#mydiv").text());

$("font","#mydiv").reverse().each(function(i, e) {
    for (var i = 0; i < attributes.length; ++i){
        var attr = $(e).attr(attributes[i]);

        if( typeof attr != "undefined")
            text = "["+attributes[i]+"="+attr+"]"+text+"[/"+attributes[i]+"]";
    }
});

$("#mydiv").text(text);

【讨论】:

  • 非常感谢,它有效。只是一个问题,reverse()函数是从最后一个子节点开始的?
  • 是的,在这种情况下是这样。您可以查看this question了解更多方式。
【解决方案2】:

满屋子悲伤、哭泣的小猫希望你能摆脱那些 &lt;font&gt; 标记,但你可以通过明确地向下遍历嵌套标记来使其工作。

它之所以会像现在这样,是因为对.text() 的外部调用会针对第一个&lt;font&gt; 标签运行,而它会删除其他标签。

edit — 澄清,当你打电话时

$('#mydiv').find('font')

jQuery 会找到 3 个字体标签。因此,库将为每个元素调用您传递给.text() 的函数。但是,第一次调用将具有从 DOM 中删除其他两个 &lt;font&gt; 元素的效果。即使库继续为这些元素调用您的回调,也没有任何效果,因为它们不再在页面上。

以下是可行的方法:

var $fonts = $('#mydiv').find('font');
var text = $fonts.text();

var attrs = {};
$fonts.each(function(_, font) {
  var names = ["size", "color", "face"];
  for (var i = 0; i < names.length; ++i)
    if (font[names[i]]) attrs[names[i]] = font[names[i]];
});

var newText = "";
for (var name in attrs) {
  if (attrs.hasOwnProperty(name))
    newText += '[' + name + '=' + attrs[name] + ']';
}
newText += text;
for (var name in attrs) {
  if (attrs.hasOwnProperty(name))
    newText += '[/' + name + ']';
}

$('#mydiv').text(newText);

请注意,我不太确定您为什么要将 BBCode 放在这样的页面上,但这似乎是本意。

【讨论】:

  • Ehm... 但是 OP 正在 试图摆脱 &lt;font&gt; 元素。
  • 但是如果我放了alert,它仍然会alert 3次,这意味着它找到了3个字体标签,即使第一个进程应该已经消除了另外两个。
  • 那么 jQuery 会找到所有三个&lt;font&gt; 元素它调用外部.text()。之后,后两个元素已从 DOM 中删除,因此更新它们的内容没有任何区别。
  • @MrLister 好点,我想,但首先是某些东西把它们放在那里,很难向悲伤的小猫解释这种细微差别。
【解决方案3】:

在我看来你的第一行应该是:

$("#mydiv").find("font").each(function(){

【讨论】:

  • 我应该在问题中提到它,我尝试了每个,replaceWith,html(),结果都一样。只有第一个标签是变化的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
相关资源
最近更新 更多