I want to add class to multiple SPAN (but not all SPAN). In this case i'm choosing to add class to last 2 SPAN's.
So currently my code is taking a string and then inserting each letter as SPAN in html.
So then i want the code to read the last 2 (or any other amount) of span to add another .class (in this case .blue)
I believe this is part of the code i need to use, but because i'm doing += it add another extra SPAN to html which is causing duplicates.
if (i >= 5) {
html += '<span class="blue blast">' + split[i] + '</span>';
}
Full code here and CodePen:
function myFunction() {
var string = document.querySelector('.title').innerHTML
var split = string.split('');
var html = '';
for (let i = 0; i < split.length; i++) {
html += '<span class="blast">' + split[i] + '</span>';
if (i >= 5) {
html += '<span class="blue blast">' + split[i] + '</span>';
}
}
document.querySelector('.title').innerHTML = html;
}
myFunction()
https://codepen.io/MariusZMM/pen/MZdpNb
I already have jQuery code that does this for me. But i want to learn Vanila JavaScript.
Update: with the help from tymeJV i have updated CodePen with a fix:
https://codepen.io/MariusZMM/pen/pqmwgL
You only want to write the blue letters when i > 5 - so wrap the other portion in an else block
if (i >= 5) {
html += '<span class="blue blast">' + split[i] + '</span>';
} else {
html += '<span class="blast">' + split[i] + '</span>';
}
This is my proposition:
function myFunction(num) {
const splitted = document.querySelector('.title').innerHTML.split('');
const newContent = splitted.map((letter, i) => {
const className = i >= splitted.length - num ? 'blue blast' : 'blast';
return '<span class="'+className+'">' + letter + '</span>';
}).join('');
document.querySelector('.title').innerHTML = newContent;
}
myFunction(3);
Related
I'm beginner in JS. But, after many hours, i'm really close to the wanted result.
I declare my JS Function in head part
function getPrice(price) {
var tabPrice = price.split("");
var html = "";
var virguleIndex = null;
for (var index = 0; index < tabPrice.length; ++index) {
var priceNumber = tabPrice[index];
if (priceNumber == ',') {
virguleIndex = index;
html += "<span class='p-c'>" + priceNumber + "</span>";
} else if (priceNumber == '-') {
html += "<span class='p-d'>" + priceNumber + "</span>";
} else if (index > virguleIndex && virguleIndex != null) {
html += "<span class='p-" + priceNumber + " p-small'>" + priceNumber + "</span>";
} else {
html += "<span class='p-" + priceNumber + "'>" + priceNumber + "</span>";
}
}
var div = document.getElementsByClassName('price');
div[0].innerHTML = html;
}
and my div in body part
<div class="price"></div>
I made some test - And my function getPrice works perflectly
https://image.noelshack.com/fichiers/2018/02/4/1515663887-functionwork.jpg
Some, the only fail (I think) is that the innerHTML don't work and don't write de var html content in div class price.
I haven't idea yet after many (many) hours of looking.
Can you help me ?
Thanks in advance,
Ludovic
By going through your image it is clear your DOM is not ready. So Please call your function inside this Block.
(function() {
// your page initialization code here
// the DOM will be available here
//Call Your function inside this block. it will work ex. getPrice("100");
})();
Some news (I worked on this few hours), I check for the dom charging. I tried (thank for you answer) the call function / transpose the code and the end / forcing the function after the dom loading (with document.addEventListener("DOMContentLoaded", function(event) {)
Console log still working. But my div still empty :/
Thanks again !
I am trying to use JavaScript to manipulate and change font and font size from a page of text from a word processor (such as Google Docs or Word) inputted by a user, by an HTML word processor (CKEditor). However, after manipulation of font size, when displaying the text into an HTML text field, much of the document formatting is lost such as no indentation, spaces at the end of the line being deleted, titles are not centered.
Is there a way to correctly format a text document using purely HTML?
I have not found a function in CKEditor that allows me to change the font or font size on call within it, or any other HTML word processor for that matter.
Here's the code that manipulates the text, then pastes it into the HTML text area.
editor = CKEDITOR.instances.editor1;
var edata = editor.getData();
edata = CKEDITOR.instances.editor1.document.getBody().getText();
var sin = replaced_text;
var sout = "";
var i;
for(i = 0 ; i < sin.length; i++) {
if(sin.charAt(i) == ",")
{ sout += '<span class=ef>' + sin.charAt(i) + '</span>' }
else if(sin.charAt(i) == ".") { sout += '<span class=ef>' + sin.charAt(i) + '</span>' }
else if(sin.charAt(i) == " " && sin.charAt(i+1) == " ") { sout += 'span class = of>' + sin.charAt(i) + sin.charAt(i+1) + '</span>' }
else if(sin.charAt(i) == " "){ sout += '<span class=of>' + sin.charAt(i) + '</span>' }
else {sout+= '<span class=if>' + sin.charAt(i) + '</span>'}
}
var data = editor.dataProcessor.toDataFormat( sout );
document.getElementById("space").innerHTML = data;
editor.setData(data);
editor.updateElement();
it's helpful for you markedJS.
MarkedJS can parse markdown text, you can use it to marked your text so that keeps text formate
THIS QUESTION IS SOLVED VIA COMMENTS. WORKING SOLUTION IS POSTED BELOW
So I got this piece of code that I am trying to adapt as it ain't showing the way I wish.
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}
The issue is with this line:
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
The problem is that when the row[field[i].name] inside the .value <span> is empty it still shows the name and a empty value field.
So I thought to replace that line with a if/else like if .value <span> is empty then //do nothing else CODE FROM ABOVE.
As I am not going to ask a question without trying to fix it by myself first here are the attempts I made so far, please keep in mind that I placed all these if else at the same place as the single line of code above!
Attempt 1
if $(row[field[i].name]).length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
Attempt 2
if $(row[field[i].name]).val().trim().length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
The attempts are not in the right order but those 2 where left in the document as comments I tried a couple of other things as well including :empty but I already deleted them from the comments section.
Thanks in advance for any help. And if something is not clear please let me know.
Attempt 3 with help from Mike C
var row_id = 0; // row counter
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
if row[field[i].name].length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}
I am answering it myself as I don't want to have too many questions with no answers as it could get me blocked! Can't have that. Too be clear this answers credits should go to MikeC. But he never posted the answer as answer but as comment. I asked him together with some others to please post a answer so we could accept it. He never did so therefore I post his answer myself.
Working solution by Mike C
var row_id = 0; // row counter
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
if (row[field[i].name].length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}
There are similar posts but I can't find a solution for my unique case.
I have a script which highlights a keyword when a user clicks the highlight button. Currently it is only highlighting the word "fox", but I need it to highlight additional words, in this case "fence" and "jumped".
Here is HTML:
<div id="inputText">
The fox quickly jumped over the fence.
</div>
<button onclick="highlight('fox')">Highlight</button>
I tried changing 'fox' to '+fox+','+fence+','+jumped+' but no luck.
The javascript is:
function highlight(text)
{
inputText = document.getElementById("inputText")
var innerHTML = inputText.innerHTML
var index = innerHTML.indexOf(text);
if ( index >= 0 )
{
innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML
}
}
and CSS:
.highlight
{
background-color:yellow;}
<button onclick="highlight('fox')+highlight('jumped')+highlight('fence')">Highlight</button>
Instead of using onclick in your markup, you should try to utilize best practice and bind events through javascript only since it's the most unobtrusive way to attach handlers to DOM elements.
Furthermore you can define the words you want to highlight in an array that you iterate the highlighting code over, like the fiddle below.
(function() {
function highlight() {
var wordsToHighlight = ["fox", "fence", "jumped"];
wordsToHighlight.forEach(function(text) {
inputText = document.getElementById("inputText")
var innerHTML = inputText.innerHTML
var index = innerHTML.indexOf(text);
if (index >= 0) {
innerHTML = innerHTML.substring(0, index) + "<span class='highlight'>" + innerHTML.substring(index, index + text.length) + "</span>" + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML
}
});
}
button = document.getElementById('btn-highlight');
button.onclick = highlight;
})();
.highlight {
background-color: yellow;
}
<div id="inputText">The fox quickly jumped over the fence.</div>
<br/>
<button id="btn-highlight">Highlight</button>
Notice the id="btn-highlight" in the markup, and the binding of the highlight function to the click event.
We can pass a delimited string and then split that into an array. You can use any delimiter you want, but I chose a comma. You can then loop through this array to highlight the words.
jsfiddle
<div id="inputText">
The fox quickly jumped over the fence.
</div>
<button onclick="highlight('fox,fence,jumped')">Highlight</button>
<script>
function highlight(text){
var i, index, words = text.split(",");
var inputText = document.getElementById("inputText");
var innerHTML = inputText.innerHTML;
for(i=0;i<words.length;i++){
index = innerHTML.indexOf(words[i]);
if (index >= 0) {
innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+words[i].length) + "</span>" + innerHTML.substring(index + words[i].length);
inputText.innerHTML = innerHTML;
}
}
}
</script>
Better approach will be to use a pre-made dictionary like object:
DEMO and source : JSnippet DEMO
JS:
var dic = {
fox:['fox','jumped','fence'],
cat:['cat','happy']
};
function parse(target) {
var inputText = document.getElementById("inputText");
inputText.innerHTML = inputText.innerHTML.replace(/(<([^>]+)>)/ig,"");
if (typeof dic[target] === 'object')
for (var i=0; i<dic[target].length; i++)
tokenize(dic[target][i]);
}
function tokenize(text) {
var inputText = document.getElementById("inputText");
var inner = inputText.innerHTML;
var index = inner.indexOf(text);
if ( index >= 0 ) {
inner = inner.substring(0,index) +
"<span class='highlight'>" + inner.substring(index, index + text.length) + "</span>" +
inner.substring(index + text.length);
inputText.innerHTML = inner;
}
}
Is it possible to wrap the last words in a string with span tags excluding the first word? So it'd be for example:
var string = 'My super text';
Becomes
My <span>super text</span>
I have this:
var text = string.split(" ");
// drop the last word and store it in a variable
var last = text.pop();
// join the text back and if it has more than 1 word add the span tag
// to the last word
if (text.length > 0) {
return text.join(" ") + " <span>" + last + "</span>";
}
else {
return "<span>" + text.join(" ") + last + "</span>";
}
Which wraps the last word with span tags if it has at least two but not sure how to modify it.
You just need to use text.shift() which will return the first word, instead of text.pop() which returns the last word. Then it will be much easier to accomplish this.
var text= string.split(" ");
// get the first word and store it in a variable
var first = text.shift();
// join the text back and if it has more than 1 word add the span tag
// to the last word
if (text.length > 0) {
return first + " <span>" + text.join(" ") + "</span>";
} else {
return "<span>" + first + "</span>";
}
You could do it with a regular expression.
text = text.replace(/\s(.*)$/, ' <span>$1</span>');
However, you should probably turn the following into a recursive function...
$('body').contents().filter(function() {
return this.nodeType == 3;
}).each(function() {
var node = this;
// Normalise node.
node.data = $.trim(node.data);
node.data.replace(/\s+(.*)\s*$/, function(all, match, offset) {
var chunk = node.splitText(offset);
chunk.parentNode.removeChild(chunk);
var span = document.createElement('span');
span.appendChild(document.createTextNode(' ' + match));
node.parentNode.appendChild(span);
});
});
jsFiddle.
This will allow you to modify text nodes and insert the span elements without messing with serialised HTML.
var space = string.indexOf(' ');
if (space !== -1) {
return string.slice(0,space) + " <span>" + string.slice( space ) + "</span>";
} else {
return "<span>" + string + "</span>";
}
You don't have to split the text, just check if there is a space, and insert a span there.
This code inserts a span after the first space, and if there is no space (idx == -1), the span is put at the beginning of the string:
var idx = string.indexOf(' ');
return string.substr(0, idx + 1) + "<span>" + string.substr(idx + 1) + "</span>";