JavaScript: Replacing (all) certain words on a web page - javascript

I am having trouble with some code for a chrome extension. The code is supposed to replace a word with another one. It does this, however, I would only like it to replace a word if it is within certain tags such as <p></p> or header tags. At the moment it replaces all the words in the HTML file within the <body></body>. This sometimes interferes with the HTML code and can break certain features of a website. Here's what I have currently.
document.body.innerHTML = document.body.innerHTML.replace(newRegExp("old", "g"), "new");
Thank you for the help!

So just loop over all the elements that you care about and do the replacement on those elements only.
// Get all the elements that you care about into an array
let elements = Array.prototype.slice.call(document.querySelectorAll("p, header"));
// Loop over the items in the array
elements.forEach(function(el){
// Do the replace on the element
el.textContent = el.textContent.replace(/text/g, "letters");
});
<header>This is some text in a header</header>
<h1>This is some text in an h1</h1>
<div>This is some text in a div</div>
<p>This is some text in a p</p>
<div>This is some text in a div</div>
<div>This is some text in a div
<p>This text is inside of a p with lots of text</p>
</div>

Related

How to get text of every text node in Cheerio?

<div>
<p>Hello World!</p>
foo
</div>
I want to get only the text of the text nodes inside the div, and I can't use $('div').text() because that gives me the text of the p also.
Actually I would like to get the text of every such text node, and I hope there's something as simple as $('textNode').toArray().map((node) => $(node).text()).

Using jQuery to add paragraph tags and skip HTML elements

I have some HTML being fed in to me for blogs and want to be able to ensure it's parsed properly.
I am using this jQuery function (below) to ensure text is being wrapped in a paragraph tag however it seems to be filtering out the strong and a tags into their own paragraph tags.
Here is the original HTML:
<div id="demo">
<h2>This is a title</h2>
This is content that will need to be wrapped in a paragraph tag <strong>and this is bold</strong> and this is a link.<br />
More content here.
</div>
Now using this function to filter this:
$('#demo')
.contents()
.filter(function() {
return this.nodeType === 3 && $.trim(this.textContent).length;
})
.wrap('</p>');
Renders me this HTML:
<div id="demo">
<h2>This is a title</h2>
<p>This is content that will need to be wrapped in a paragraph tag </p>
<strong>and this is bold</strong>
<p> and this is a </p>
link.
<p>More content here.</p>
</div>
As you can see, I'm getting half of what I need but it's separating the HTML elements outside of the paragraph tag. Is there a way I can allow these HTML elements to remain inside the paragraph tag?
Thanks
You can store the h2 element, remove it from the structure, wrap what remains and add back in the h2.
let cloned = $("#demo > h2").clone(); // Clone the <h2>
$("#demo > h2").remove(); // Remove the <h2>
$("#demo").wrapInner("<p>"); // Wrap everyting left over
cloned.insertBefore("p"); // Put <h2> back
console.log($("#demo").html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="demo">
<h2>This is a title</h2>
This is content that will need to be wrapped in a paragraph tag <strong>and this is bold</strong> and this is a link.
More content here.
</div>

JavaScript - Use innerHTML as actual html instead of plain text

When I'm trying to change document.documentElement.innerHTML using the innerHTML of a textarea like this:
document.documentElement.innerHTML = document.querySelector('#mytextarea').innerHTML
The innerHTML of #mytextarea is not used as actual HTML to change the DOM, but as plain text.
For example: if the innerHTML of #mytextarea is <p>A paragraph</p>.
Then the document after loading looks like: <p>A paragraph</p> instead of A paragraph
How should I do it so the value inside the #mytextarea could be used to change the DOM? (ex. appending new elements)
Use .value to get the contents of a textarea without it being encoded.
document.getElementById("documentElement").innerHTML = document.querySelector('#mytextarea').value;
<textarea id="mytextarea">
<p>A paragraph</p>
</textarea>
<div id="documentElement">
</div>
You can easily achieve this without the use of any JavaScript. You just have to insert special characters into your HTML code.
<p>A paragraph</p>
That weird code will show up as
<p>A paragraph</p>
If you don't know the codes, just use this: HTML Encoder
EDIT:
They are called HTML escape characters, or, HTML entities. Here is a list of a lot of them: List

JQuery replace all contents in a div except tags

I have to replace some characters in all a div, but when I run the code, the function replaces me also the html tags characters
my code is:
$("#main").children().each(function() {
$(this).html($(this).html().replace(/s/g, "K"));
})
<div id="main">
<p>Some contents that will be replaced... <span>this will not be in a span tag :(</span></p>
</div>
result:
<div id="main">
<p>Kome contentK that will be replaced... <Kpan>this will not be in a Kpan tag :(</Kpan></p>
</div>
If your goal is to preserve all the markup within the div but replace text within all those tags, that's difficult. You need to find just the text nodes and no other nodes and do the replacement within each of the text nodes individually.
This question may help: How do I select text nodes with jQuery?

JQuery - Paste event, stripping rich text

I have a contentEditable field where I'd like to do the following. When a user pastse rich text into the field (microsoft word, or otherwise) I'd like to strip all the rich text, but retain the line breaks.
My thinking was: If you paste rich text into a plain <texarea>, it removes all the formatting and retains the breaks (created by explicit new lines, as well as block level elements). I'd like to somehow simulate this. In other words, create a temporary textarea, intercept the paste event, apply it to the Textarea, retrieve the results, and insert them back into the original Content Editable field.
However, i haven't found a way to simulate this. If I paste the contents into a textarea via jquery, it seems to retan all the rich text formatting when I try and copy it from there, back to the original fields
You could achieve something like this without needing a textarea, just processing the code in the content editable div every time that there is a change in its value, and removing all the tags but the paragraphs and line breaks.
The idea would be that every time that the content changes in the div (listen to the input event):
Replace in the inner HTML all </p> and <br> for non-HTML tokens (e.g.: [p] and [br] respectively).
Remove all HTML tags (you can do it with .text())
Replace the tokens that you used for their equivalents (and their openings!)
Wrap everything between <p> and </p>.
Here a simple demo:
$("#editable").on("input", function() {
$this = $(this);
// replace all br and closing p tags with special tokens
$this.html($this.html().replace(/\<\/p\>/g,"[p]").replace(/\<br\>/g,"[br]"));
// remove all the tags, and then replace the tokens for their original values
$this.html("<p>" + $this.text().replace(/\[p\]/g, "</p><p>").replace(/\[br\]/g,"<br>") + "</p>");
});
div#editable, div#demo {
border:1px solid gray;
padding:6px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div contenteditable="true" id="editable"></div>
<h3>Demo</h3>
<p>Copy this code and paste it on the editable div above:</p>
<div id="demo">
<p>This <b>is</b> <i>a</i> styled paragraph.</p>
<p> </p>
<p>The <span style="font-weight:bold">above paragraph</span> is empty.</p>
<p>And this is a new paragraph…<br>with a line break!</p>
</div>
You can also see it running on this JSFiddle: http://jsfiddle.net/v5rae96w/
I tried this solution with MS Word and HTML and it works fine. But it has one issue: it only does line breaks with p and br (that works nicely with MS Word and other word processors). If the user copies HTML like div (or other block elements that cause a line break), it won't work as nicely. If you need to break with all block elements, this solution may require some changes.
To fix that, you could replace all the block tags with p (or div or the element that you want), by indicating it on the regular expression:
$this.html().replace(/(\<\/p\>|\<\/h1\>|\<\/h2\>|\<\/div\>)/gi,"[p]")
As you can see here:
$("#editable").on("input", function() {
$this = $(this);
// replace all closing block tags with special token
$this.html($this.html().replace(/(\<\/p\>|\<\/h1\>|\<\/h2\>|\<\/h3\>|\<\/h4\>|\<\/h5\>|\<\/h6\>|\<\/div\>)/gi,"[p]").replace(/\<br\>/gi,"[br]"));
// remove all the tags
$this.html("<p>" + $this.text().replace(/\[p\]/g,"</div><p>").replace(/\[br\]/g,"<br>") + "</p>");
});
div#editable, div#demo {
border:1px solid gray;
padding:6px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div contenteditable="true" id="editable"></div>
<div>
<h3>Demo</h3>
<p>Copy this code and paste it on the editable div above:</p>
<div id="demo">
<p>This <b>is</b> <i>a</i> styled paragraph.</p>
<p> </p>
<p>The <span style="font-weight:bold">above paragraph</span> is empty.</p>
<p>And this is a new paragraph…<br>with a line break!</p>
</div>
</div>
Or on this JSFiddle: http://jsfiddle.net/v5rae96w/1/

Categories

Resources