问题
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!
回答1:
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.net/K8544/3/
回答2:
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 ...
回答3:
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.net/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>
.
回答4:
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).
来源:https://stackoverflow.com/questions/11167331/replace-all-text-that-displaying-in-browser