最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Replace all text that displaying in browser - Stack Overflow

programmeradmin0浏览0评论

I want to replace all displaying text with something like "@@@@". It mean user will see all the page is full of "@@@@" instead of texts (except image, iframe or something doesn't exists in the page's HTML code).

This almost replace the html code of the page, but not effect to the tags and codes, just the text that display to user.

For example, I want to replace all the text in this page:

<!DOCTYPE html>
<html>
<body>                  
<ul class="topnav">
    <li>Item 1</li>
    <li>Item 2 
        <ul><li>Nested item 1</li><li>Nested item 2</li><li>Nested item 3</li></ul>
       </li>
    <li>Item 3</li>
</ul>
<div>DIV1</div>
<div>DIV2</div>
<span>SPAN</span>
<table>
<tr>
    <td>Username</td>
</tr>
<tr>
    <td>Password</td>
</tr>
</table>
<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">Remember <strong>password</strong></label>
</p>
<p>Click here to <a href='register.php'>Register</a></p>
</body>
</html>

And the result should be:

<!DOCTYPE html>
<html>
<body>                  
<ul class="topnav">
    <li>@@@@</li>
    <li>@@@@ 
        <ul><li>@@@@</li><li>@@@@</li><li>@@@@</li></ul>
       </li>
    <li>@@@@</li>
</ul>
<div>@@@@</div>
<div>@@@@</div>
<span>@@@@</span>
<table>
<tr>
    <td>@@@@</td>
</tr>
<tr>
    <td>@@@@</td>
</tr>
</table>
<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">@@@@<strong>@@@@</strong></label>
</p>
<p>@@@@<a href='register.php'>@@@@</a></p>
</body>
</html>

Some I've been tried:

Use JQuery to replace all the elements, tags (and it's child) that only contain plain text, this works fine at the beginning:

<ul class="topnav">
    <li>@@@@</li>
    <li>@@@@ 
        <ul><li>@@@@</li><li>@@@@</li><li>@@@@</li></ul>
       </li>
    <li>@@@@</li>
</ul>
<div>@@@@</div>
<div>@@@@</div>
<span>@@@@</span>

But lately I realized that in case of elements, tags have child, it would failed:

<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">Remember <strong>password</strong></label>
</p>
<p>Click here to <a href='register.php'>Register</a></p>

So I tried another way, using document.body.innerText to select all the text, but the HTML format is lost.

I was so tired. Can someone help me?

Thanks a lot!

I want to replace all displaying text with something like "@@@@". It mean user will see all the page is full of "@@@@" instead of texts (except image, iframe or something doesn't exists in the page's HTML code).

This almost replace the html code of the page, but not effect to the tags and codes, just the text that display to user.

For example, I want to replace all the text in this page:

<!DOCTYPE html>
<html>
<body>                  
<ul class="topnav">
    <li>Item 1</li>
    <li>Item 2 
        <ul><li>Nested item 1</li><li>Nested item 2</li><li>Nested item 3</li></ul>
       </li>
    <li>Item 3</li>
</ul>
<div>DIV1</div>
<div>DIV2</div>
<span>SPAN</span>
<table>
<tr>
    <td>Username</td>
</tr>
<tr>
    <td>Password</td>
</tr>
</table>
<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">Remember <strong>password</strong></label>
</p>
<p>Click here to <a href='register.php'>Register</a></p>
</body>
</html>

And the result should be:

<!DOCTYPE html>
<html>
<body>                  
<ul class="topnav">
    <li>@@@@</li>
    <li>@@@@ 
        <ul><li>@@@@</li><li>@@@@</li><li>@@@@</li></ul>
       </li>
    <li>@@@@</li>
</ul>
<div>@@@@</div>
<div>@@@@</div>
<span>@@@@</span>
<table>
<tr>
    <td>@@@@</td>
</tr>
<tr>
    <td>@@@@</td>
</tr>
</table>
<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">@@@@<strong>@@@@</strong></label>
</p>
<p>@@@@<a href='register.php'>@@@@</a></p>
</body>
</html>

Some I've been tried:

Use JQuery to replace all the elements, tags (and it's child) that only contain plain text, this works fine at the beginning:

<ul class="topnav">
    <li>@@@@</li>
    <li>@@@@ 
        <ul><li>@@@@</li><li>@@@@</li><li>@@@@</li></ul>
       </li>
    <li>@@@@</li>
</ul>
<div>@@@@</div>
<div>@@@@</div>
<span>@@@@</span>

But lately I realized that in case of elements, tags have child, it would failed:

<p>
  <input type="checkbox" name="remember" tabindex=3 />
  <label for="checkbox">Remember <strong>password</strong></label>
</p>
<p>Click here to <a href='register.php'>Register</a></p>

So I tried another way, using document.body.innerText to select all the text, but the HTML format is lost.

I was so tired. Can someone help me?

Thanks a lot!

Share Improve this question asked Jun 23, 2012 at 6:08 Tony DinhTony Dinh 6,7265 gold badges41 silver badges58 bronze badges 7
  • in case of elements, tags have child, it would failed: can you explain this case? – Furqan Hameedi Commented Jun 23, 2012 at 6:13
  • You need to replace anything between a > and a < in the body.innerHTML – Scott Stevens Commented Jun 23, 2012 at 6:18
  • @Furqan: If there are child tags, the function would check that is not a "plain text" and ignore them (the example HTML I showed). – Tony Dinh Commented Jun 23, 2012 at 9:20
  • @ScottS: In this case: <p> hello, click <a href=""asd.zxc">here</a></p> my link would be lost. – Tony Dinh Commented Jun 23, 2012 at 9:21
  • @TrungDQ No, since you would only replace between any two tags (be opening or closing). You would check for the > and < symbols, not the opening and closing tags that are on the same parent level. – Scott Stevens Commented Jun 23, 2012 at 9:38
 |  Show 2 more ments

4 Answers 4

Reset to default 9

This code seems to work for me:

$('*').contents().filter(function() {
    return this.nodeType == Node.TEXT_NODE && this.nodeValue.trim() != '';
}).each(function() {
    this.nodeValue = '@@@@';
});

Basically, it replaces the contents of each text node with @@@@.

For a demo, see here: http://jsfiddle/K8544/3/

Try this one. It's a function that replaces inner text with "*", but only if its inner HTML is equal to its inner text. Otherwise, it calls itself recursively, navigating down the DOM until it reaches the innermost element.

    $(document).ready(function() {
        function replaceChildren(node) {
            if ($(node).html() == $(node).text()) $(node).text("@@@@");
            else {
                $(node).children().each(function() {
                    replaceChildren(this);
                });
            }
        }
        replaceChildren($("body"));
    });

It's not perfect, but should be pretty close for most purposes. I tried it on a Stack Overflow page, and most text got replaced. The only place it doesn't work is where there is stray markup and text within the same tag, for example <div>Here is some inner text <strong>and markup</strong></div>. Maybe this suffices for your purpose though ...

A JQuery-only solution:

$("body *").contents().wrap("<obscure></obscure>");
$("obscure").each(function(i,e) {if ($(e).children().length==0) $(e).replaceWith("@@@@");}​);
$("obscure > *").unwrap();

http://jsfiddle/cranio/CW9jY/1/

This code wraps EVERY node with a custom tag (obscure); the use of .contents() makes sure we wrap ALSO the pure text nodes. Then we substitute the obscure nodes which have no children (that were text-only nodes before) with @@@@, hence eliminating also the obscure tags. Finally, we unwrap the other elements that were wrapped with <obscure>.

You can match anything between two tags - these don't have to be the same tag. For instance, <div>aaa<a href="bbb">ccc dd</a></div>, it would find aaa, replace it with @@@, then find ccc dd and replace it with @@@ @@ by looking between > and the next <.

<script type="text/javascript">
function obscure() {
    var newhtml = document.body.innerHTML.split("<");
    for (var i=1; i<newhtml.length; i++) {
        var list = newhtml[i].split(">");
        newhtml[i] = (list[0]) + ">" + ((list[1]).replace(/[^@\s]/gim, "@"));
    }
    newhtml[0] = (newhtml[0].replace(/[^@\s]/gim, "@"));
    document.body.innerHTML = newhtml.join("<");
}
</script>

(Note: This does not replace whitespace, since that appeared to be causing some issues).

发布评论

评论列表(0)

  1. 暂无评论