Reputation: 23
Sentence: Mr Blue has a blue house and a blue car.
JavaScript Code: `
function myFunction(){
var str = document.getElementById("sentence").innerHTML;
for(var i=0; i<str.length;i++){
if(i == 0 )
{
var res = str.replace(str.charAt(i+1), "<u>"+str.charAt(i+1)+"</u>");
document.getElementById("sentence").innerHTML = res;
}else if(str.charAt(i) == " ")
{
var res = str.replace(str.charAt(i+1), "<u>"+str.charAt(i+1)+"</u>");
document.getElementById("sentence").innerHTML = res;
}
}`
Problem: I am trying to underline the first character in every word of a paragraph when a button is pressed. With the code I have only the C from car is underlined. if anyone can see where I have gone wrong or if there is a better way of doing this problem.
Thanks
Upvotes: 2
Views: 1022
Reputation: 23
Thanks guys for the help, greatly appreciated.
Full Solutions:
<!DOCTYPE html>
<html>
<body>
<p id="Sentence">Mr Blue has a blue house and a blue car.</p>
<button onclick="myFunction()">Click</button>
<script>
function myFunction() {
var str = document.getElementById("Sentence").innerHTML;
var res = str.replace(/([^\s]+)/g,function(str){
return "<u>"+str.charAt(0)+"</u>" + str.slice(1);
});
document.getElementById("Sentence").innerHTML = res;
}
</script>
</body>
</html>
Upvotes: 0
Reputation: 1095
Your code is working partially correct. It works on every word of the string but is getting updated again with next word.
You can make it simple by using a regex.
str.replace(/([^\s]+)/g,function(str){
return "<u>"+str.charAt(0)+"</u>" + str.slice(1);
})
Explanation of the regex:
(: Capturing group start
[^: Negated set - Match anything which is not in the set.
\s: Matches any whitespace character (spaces)
]: set ends
): Capturing group ends
Looking at the syntax of the javascript replace function:
str.replace(regexp|substr, newSubstr|function)
function (replacement)
A function to be invoked to create the new substring to be used to replace the matches to the given regexp or substr. The arguments supplied to this function are match, submatch, offset and the original string. (Source: MDN)
Edit: You are still not using the accepted solution in your answer properly. This is how your function will look now:
<script>
function myFunction() {
var str = document.getElementById("Sentence").innerHTML;
var result = str.replace(/([^\s]+)/g,function(str){
return "<u>"+str.charAt(0)+"</u>" + str.slice(1);
});
document.getElementById("Sentence").innerHTML = result;
}
</script>
and if you are comfortable with ES6:
<script>
function myFunction() {
const str = document.getElementById("Sentence").innerHTML;
const result = str.replace(/([^\s]+)/g, p1 => `<u>${p1.charAt(0)}</u>${p1.slice(1)}` );
document.getElementById("Sentence").innerHTML = result;
}
</script>
Upvotes: 2
Reputation: 29
var str = document.getElementById("sentence").innerHTML;
var words = str.match(/\S*/g);
var words2 = [];
words.forEach(function(item, i, arr) {
if (item!="")
{
words2.push(item.replace(item.charAt(1), "<u>"+item.charAt(1)+"</a>"));
}
});
document.getElementById("sentence").innerHTML = words2.join(" ");
Upvotes: 0
Reputation: 138267
You store the mutation inside res
, but you don't update str
, so at the next iteration the previous changes get discarded. Instead just mutate str
:
str = str.replace(str.charAt(i+1), "<u>"+str.charAt(i+1)+"</u>");
And then after the loop is done reflect it to the DOM once:
document.getElementById("sentence").innerHTML = str;
How i would solve that:
function underline(selector) {
const el = document.querySelectorAll(selector);
let result = "";
for(const word of el.innerHTML.split(" ")) {
result += `<u>${word[0]}</u>${word.substr(1)}`;
}
el.innerHtML = result;
}
underline("#sentence");
Upvotes: 0