2017-05-05 34 views
6

假设我有以下HTML结构:替换元素含量,而无需更换HTML

<test> 
    <div> 
     This is a test 
     </div> 
    <div> 
     This is another test 
     <button> 
      Button test 
     </button> 
    </div> 
</test> 

现在我使用下面的jQuery代码来代替,例如, 'T':

$("test *").each(function(index, value) { 
    $(this).html($(this).html().replace(new RegExp('t', "ig"), "<b>t</b>")); 
}); 

然而,这个结果在下面的HTML结构(这是意想不到的,看到<button>标签,它打破我的HTML):

<test> 
    <div> 
     <b>T</b>his is a <b>t</b>es<b>t</b> 
     </div> 
    <div> 
     <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b> 
     <bu<b>t</b><b>t</b>on> 
      Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b> 
      </bu<b>t</b><b>t</b>on> 
     </div> 
    </test> 

我想实现的是:

<test> 
    <div> 
     <b>T</b>his is a <b>t</b>es<b>t</b> 
     </div> 
    <div> 
     <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b> 
     <button> 
      Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b> 
      </button> 
     </div> 
    </test> 

基本上,我想整个元素内更换,但保留了HTML代码和所有的HTML属性。

+1

所以,如果我理解正确的话,你不想

+0

@ Goose,正确,但这不仅适用于按钮标签,而且适用于当然与正则表达式匹配的所有html标签。 –

回答

1

使用jQuery这可能是相当简单的实现。创建一个函数,它接受你想要更新文本的元素,你想要替换的文本以及你想要替换的文本。然后,在要删除子HTML的函数中,使用替换文本更新元素中剩下的任何文本。然后,您可以递归地为每个子元素运行相同的函数,然后再将它们附加回父代。

function replaceTextInHtmlBlock($element, replaceText, replaceWith) 
 
{ 
 
    var $children = $element.children().detach(); 
 
    //Now that there should only be text nodes left do your replacement 
 
    $element.html($element.text().replace(replaceText, replaceWith)); 
 
    //Run this function for each child element 
 
    $children.each(function(index, me){ 
 
    replaceTextInHtmlBlock($(me), replaceText, replaceWith); 
 
    }); 
 
    $element.append($children); 
 
} 
 

 
$(document).ready(function(){ 
 
    $("#doReplace").click(function(){ 
 
    replaceTextInHtmlBlock($("#top"), $("#replace").val(), $("#with").val()); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="top"> 
 
    <div> 
 
    This is a test 
 
    </div> 
 
    <div> 
 
    This is another test 
 
    <button> 
 
      Button test 
 
      </button> 
 
    </div> 
 
</div> 
 
<br /> 
 
<br /> 
 
<div> 
 
    <label>Replace</label> 
 
    <input id="replace" value="t" /> 
 
    <label>with</label> 
 
    <input id="with" value="<strong>t</strong>" /> 
 
    <button id="doReplace">Do Replace</button> 
 
</div>

+0

感谢您的回答,它似乎很好。 –

0

看起来你想大胆所有的T字符,但你的正则表达式也赶上你的HTML。

对innerText而不是innerHTML执行操作。我在几年中没有使用jQuery,所以可能会有更好的方法来做到这一点,但这应该做到这一点。

$("test *").each(function(index, value) { 
    $(this)[0].innerText = $(this)[0].innerText.replace(new RegExp('t', "ig"), "<b>t</b>"); 
}); 
+0

感谢您的回答,但是这会将所有儿童从父母权利中删除?如果是这样,那是不需要的行为 –

+0

我刚刚测试过你的代码,它根本不保存我的HTML。感谢您分享您的想法 –

+0

啊我明白你现在说的话。好吧,祝你好运! –

0

你能避免jQuery的,而不是担心在讲究button(因为如果你打的input标签等不会帮助),如果您在文本节点只能更换。

我们寻找文本节点,在每种情况下都找到我们看到的第一个“t”(或“T”),将它包装在<b>中,然后继续前进。稍后的文本节点中会找到同一区域中的其他匹配项。

var wrapText = "t"; 
 

 
var el = document.getElementsByTagName('test')[0]; 
 

 
replaceIn(el); 
 

 
function replaceIn(el) { 
 
    var i = 0; 
 

 
    while (i < el.childNodes.length) { 
 
    var cn = el.childNodes[i]; 
 

 
    if (cn.nodeType == 3) { // text node 
 
     var p = cn.textContent.toLowerCase().indexOf(wrapText); 
 

 
     if (p >= 0) { 
 
     var range = new Range(); 
 
     range.setStart(cn, p); 
 
     range.setEnd(cn, p + 1); 
 
     range.surroundContents(document.createElement('b')); 
 
     ++i; // don't check the <b> we just created 
 
     } 
 
    } 
 
    else { 
 
     replaceIn(cn); 
 
    } 
 

 
    ++i; 
 
    } 
 
}
<test> 
 
    <div> 
 
    This is a test 
 
    </div> 
 
    <div> 
 
    This is another test 
 
    <button> 
 
     Button test 
 
    </button> 
 

 
    <input value="input test" /> 
 
    </div> 
 
</test>

+0

感谢您的回复。它效果很好,但是我必须处理一个非常慢的整个页面。当我执行搜索时,网页几乎崩溃。 –

+0

如果您不想处理标签,则必须处理单个文本节点而不是仅处理字符串。老实说,我认为事后并不存在高性能的解决方案。 – Goose