How do i remove the character "," from a div. for example,
<div class="something">This, is, the, text. </div>
Now i want to remove all the ","s from that div using javascript.
Please forgive me for being too noob in javascript.
var elements = document.getElementsByClassName("something");
elements[0].innerHTML = elements[0].innerHTML.replace(/,/g,'');
Check this example out:
http://jsfiddle.net/QpJNZ/
Update:
var elements = document.getElementsByClassName("something");
for (var i = 0; i < elements.length; ++i) {
elements[i].innerHTML = elements[i].innerHTML.replace(/,/g,'');
}
This is how to make this work for more than one element.
Check this example out:
http://jsfiddle.net/VBEaQ/2/
If the element only contains text and no other elements, you can simply do get the inner content of the element then perform string replacement:
element.innerHTML = element.innerHTML.replace(/,/g, '');
To replace all occurrences of a character sequence, you have to use a regular expression with the global modifier.
If the element contains other elements, you can iterate over all child text nodes:
function replace(element, needle, repl) {
var children = element.childNodes, // get a list of child nodes
pattern = new RegExp(needle, 'g'), // prepare pattern
child, i, l;
for(i = 0, l = children.length; i < l; i++) {
child = children[i];
if(child.nodeType === 3) { // if we deal with a text node
child.nodeValue = child.nodeValue.replace(pattern, repl); // replace
}
}
}
Things to watch out for:
If the text you are searching for contains special regular expression characters, you have to properly escape them first.
If you want to replace the text inside child elements as well, you have to call this function recursively for each element node (nodeType is 1).
Reference: String.replace, Node.childNodes, Node.nodeType, Node.nodeValue, RegExp
Related
I am looking for a way to find instances of a certain character within a certain element. I am aware of doing something like:
var string = 'this is a string';
string.indexOf('a');
however, i want indexOf to look at a particular tag within a particular html file. (in this case, p tags). I have commented out what i tried to use in order to achieve this.
function findQuestion() {
// var string1 = document.getElementsByTagName('p');
var string2 = '??';
if (string2.indexOf('?') !== -1) {
console.log('foundQuestion');
}
else {
console.log('nothing');
}
}
findQuestion();
This code obviously just checks to see that there is a '?' in string2, but how do i write this to find all instances of '?' within p tags and return all content preceding that up to the opening p tag in which the '?' was found?
thanks.
How you could do that:
Get all p elements.
Create an empty array, results
Iterate over them and check for each p element
If the p's innerHTML contains a question mark split the string at the question mark, get the first part and add a question mark. Then add this new string to the results array
Return the results array
Example Code:
function findQuestion() {
var ps = document.getElementsByTagName('p');
var result = [];
for(var i = 0; i < ps.length; i++){
var p = ps[i];
if (p.innerHTML.indexOf('?') !== -1) {
result.push(p.innerHTML.split("?")[0] + "?");
}
}
return result;
}
findQuestion();
http://jsfiddle.net/3o4tcchL/1/
Use a loop condition to check the entirety of the content within , after that use something like slice, which will grab everything up to a particular index you specify.
I m new to javascript and would be great if you could help me with this issue I m facing.
In the HTML code below, I m trying to highlight a particular word(say "message")by replacing the word by appending to it to make it bold.
<body>
<img src="http://some.web.site/image.jpg" title="abcd" />
This is a test message.
</body>
The String "This is a test message" is found directly in the body element(so there is no id, and hence no getElementById can be used to extract the text).
So I got the entire body element and extracted the text by using textContent.(this gave me the text and ignored the image that is above the text in the html.)
Then after highlighting the word I set the 'body's textContent back to the new String.
The problem is that now I m not able to preserve the image that was above the text, and the new body has only the value of the textContent in it, and the image is lost. This is the JS I used(but now I m replacing message with the word phone).
<script>
function myFunction(){
var x = document.getElementsByTagName('body')[0].textContent;
var v = x.replace("message","phone");
document.getElementsByTagName('body')[0].textContent = v;
}
</script>
Is there any other way to replace text that is placed directly under the body, which has other elements too?
In order to do something like this, you would need to loop through all text nodes in the document, search for the word, and wrap it.
Something like this:
function highlight(str,node) {
if( !node) node = document.body;
var c = node.children, l = c.length, i, p;
for( i=0; i<l; i++) {
if( c[i].nodeType == 1) highlight(str,c[i]);
if( c[i].nodeType == 3) {
if( (p=c[i].data.indexOf(str)) > -1) {
c[i].splitText(p);
c[i].nextSibling.deleteData(0,str.length);
c[i].parentNode.insertBefore(
document.createElement('b'),c[i].nextSibling
).appendChild(document.createTextNode(str));
}
}
}
}
That should do it. To use, just call highlight("message"), with whatever text you want. Note that this will be case-sensitive - if you need caseless matching, let me know and I'll edit to take that into account (although for the most part you could probably get away with highlight("message"); highlight("Message");)
Also, you can limit the search to a particular element. Let's say you have <div id="replace-me">, you can limit the search to that element like so:
highlight("message",document.getElementById('replace-me'));
(You can use any way to get the node, this is just the easiest)
The textContent property sets or returns the textual content of the specified node, and all its descendants.
If you set the textContent proerty, any child nodes are removed and replaced by a single Text node containing the specified string.
refer to here
Try
var children = document.body.childNodes;
for(var len = children.length, child=0; child<len; child++){
if (children[child].nodeType === 3){ // textnode
var contents = children[child].nodeValue;
children[child].nodeValue = contents.replace(/message/gi, 'phone');
}
}
imagine this html on a page
<div id="hpl_content_wrap">
<p class="foobar">this is one word and then another word comes in foobar and then more words and then foobar again.</p>
<p>this is a link with foobar in an attribute but only the foobar inside of the link should be replaced.</p>
</div>
using javascript, how to change all 'foobar' words to 'herpderp' without changing any inside of html tags?
ie. only plain text should be changed.
so the successful html changed will be
<div id="hpl_content_wrap">
<p class="foobar">this is one word and then another word comes in herpderp and then more words and then herpderp again.</p>
<p>this is a link with herpderp in an attribute but only the herpderp inside of the link should be replaced. </p>
</div>
Here is what you need to do...
Get a reference to a bunch of elements.
Recursively walk the children, replacing text in text nodes only.
Sorry for the delay, I was sidetracked before I could add the code.
var replaceText = function me(parentNode, find, replace) {
var children = parentNode.childNodes;
for (var i = 0, length = children.length; i < length; i++) {
if (children[i].nodeType == 1) {
me(children[i], find, replace);
} else if (children[i].nodeType == 3) {
children[i].data = children[i].data.replace(find, replace);
}
}
return parentNode;
}
replaceText(document.body, /foobar/g, "herpderp");
jsFiddle.
It's a simple matter of:
identifying all text nodes in the DOM tree,
then replacing all foobar strings in them.
Here's the full code:
// from: https://stackoverflow.com/questions/298750/how-do-i-select-text-nodes-with-jquery
var getTextNodesIn = function (el) {
return $(el).find(":not(iframe)").andSelf().contents().filter(function() {
return this.nodeType == 3;
});
};
var replaceAllText = function (pattern, replacement, root) {
var nodes = getTextNodesIn(root || $('body'))
var re = new RegExp(pattern, 'g')
nodes.each(function (i, e) {
if (e.textContent && e.textContent.indexOf(pattern) != -1) {
e.textContent = e.textContent.replace(re, replacement);
}
});
};
// replace all text nodes in document's body
replaceAllText('foobar', 'herpderp');
// replace all text nodes under element with ID 'someRootElement'
replaceAllText('foobar', 'herpderp', $('#someRootElement'));
Note that I do a precheck on foobar to avoid processing crazy long strings with a regexp. May or may not be a good idea.
If you do not want to use jQuery, but only pure JavaScript, follow the link in the code snippet ( How do I select text nodes with jQuery? ) where you'll also find a JS only version to fetch nodes. You'd then simply iterate over the returned elements in a similar fashion.
In some forum I join, they just replace some link with something like spam or deleted. Example: www.rapidshare.com/download/123 will automatically turn to www.spam.com/download/123 OR word MONEY will change to BOSS.
Its really annoyed me because I have to rename back manually if I want to download. Is there any Javascript that can solve this that will replace back www.spam.com to www.rapidshare.com? I mean in client side.
Thanks
If these URLs are in href attributes...
var replaceHrefAttributes = function (element, search, replace) {
var nodes = element.getElementsByTagName('a');
for (var i = 0, length = nodes.length; i < length; i++) {
var node = nodes[i];
if (node.href == undefined) {
continue;
}
node.href = node.href.replace(new RegExp(search, 'g'), replace);
}
}
Your usage may be something like...
replaceHrefAttributes(document.body, 'www.spam.com', 'www.rapidshare.com');
If these URLs are inline text...
You could iterate over all text nodes, using replace() to replace any string with another.
Here is a general purpose recursive function I've written to do this...
var replaceText = function replaceText(element, search, replace) {
var nodes = element.childNodes;
for (var i = 0, length = nodes.length; i < length; i++) {
var node = nodes[i];
if (node.childNodes.length) {
replaceText(node, search, replace);
continue;
}
if (node.nodeType != 3) {
continue;
}
node.data = node.data.replace(new RegExp(search, 'g'), replace);
}
}
Your usage may be something like...
replaceText(document.body, 'www.spam.com', 'www.rapidshare.com');
If you are curious as to how the code works, here is a brief explanation...
Get all child nodes of the element. This will get text nodes and elements.
Iterate over all of them.
If this node has child nodes of its own, call the function again with element as the element in the loop. continue because we can't modify this as it is not a text node.
If this node's nodeType property is not 3 (i.e. a text node), then continue as again we can't modify any text.
We are confident this is a text node now, so replace the text.
You could make this function more flexible by passing search straight to it, allowing it to search for text using a string or a regular expression.
var a = document.getElementsByTagName('a');
for (var i = 0, len = a.length ; i < len ; i += 1) {
a.firstChild.nodeValue = a.href;
}
My current project involves gathering text content from an element and all of its descendants, based on a provided selector.
For example, when supplied the selector #content and run against this HTML:
<div id="content">
<p>This is some text.</p>
<script type="text/javascript">
var test = true;
</script>
<p>This is some more text.</p>
</div>
my script would return (after a little whitespace cleanup):
This is some text. var test = true; This is some more text.
However, I need to disregard text nodes that occur within <script> elements.
This is an excerpt of my current code (technically, it matches based on one or more provided selectors):
// get text content of all matching elements
for (x = 0; x < selectors.length; x++) { // 'selectors' is an array of CSS selectors from which to gather text content
matches = Sizzle(selectors[x], document);
for (y = 0; y < matches.length; y++) {
match = matches[y];
if (match.innerText) { // IE
content += match.innerText + ' ';
} else if (match.textContent) { // other browsers
content += match.textContent + ' ';
}
}
}
It's a bit simplistic in that it just returns all text nodes within the element (and its descendants) that matches the provided selector. The solution I'm looking for would return all text nodes except for those that fall within <script> elements. It doesn't need to be especially high-performance, but I do need it to ultimately be cross-browser compatible.
I'm assuming that I'll need to somehow loop through all children of the element that matches the selector and accumulate all text nodes other than ones within <script> elements; it doesn't look like there's any way to identify JavaScript once it's already rolled into the string accumulated from all of the text nodes.
I can't use jQuery (for performance/bandwidth reasons), although you may have noticed that I do use its Sizzle selector engine, so jQuery's selector logic is available.
function getTextContentExceptScript(element) {
var text= [];
for (var i= 0, n= element.childNodes.length; i<n; i++) {
var child= element.childNodes[i];
if (child.nodeType===1 && child.tagName.toLowerCase()!=='script')
text.push(getTextContentExceptScript(child));
else if (child.nodeType===3)
text.push(child.data);
}
return text.join('');
}
Or, if you are allowed to change the DOM to remove the <script> elements (which wouldn't usually have noticeable side effects), quicker:
var scripts= element.getElementsByTagName('script');
while (scripts.length!==0)
scripts[0].parentNode.removeChild(scripts[0]);
return 'textContent' in element? element.textContent : element.innerText;
EDIT:
Well first let me say im not too familar with Sizzle on its lonesome, jsut within libraries that use it... That said..
if i had to do this i would do something like:
var selectors = new Array('#main-content', '#side-bar');
function findText(selectors) {
var rText = '';
sNodes = typeof selectors = 'array' ? $(selectors.join(',')) : $(selectors);
for(var i = 0; i < sNodes.length; i++) {
var nodes = $(':not(script)', sNodes[i]);
for(var j=0; j < nodes.length; j++) {
if(nodes[j].nodeType != 1 && node[j].childNodes.length) {
/* recursion - this would work in jQ not sure if
* Sizzle takes a node as a selector you may need
* to tweak.
*/
rText += findText(node[j]);
}
}
}
return rText;
}
I didnt test any of that but it should give you an idea. Hopefully someone else will pipe up with more direction :-)
Cant you just grab the parent node and check the nodeName in your loop... like:
if(match.parentNode.nodeName.toLowerCase() != 'script' && match.nodeName.toLowerCase() != 'script' ) {
match = matches[y];
if (match.innerText) { // IE
content += match.innerText + ' ';
} else if (match.textContent) { // other browsers
content += match.textContent + ' ';
}
}
ofcourse jquery supports the not() syntax in selectors so could you just do $(':not(script)')?