How to add margin on targeted letter javascript - javascript

I have this in html
<div id="content">
<h1 class="entry-title">"Homepage SlideShow"</h1>
</div>
I also have this in js
var content = document.getElementById("content");
var entryTitle = content.getElementsByClassName('entry-title')[0];
var str = entryTitle.innerHTML;
var newTitle = "";
for (var i = 0; i < str.length; i++) {
if (str[i] == 'e') {
newTitle += str.charAt(i).fontcolor("red");
}
else {
newTitle += str[i];
}
}
entryTitle.innerHTML = newTitle;
I added a color on the targeted letter but I don't have an idea how to add a margin. I want to add margin on the targeted letter like margin = -20px;. I'm new to javascript and I'm hoping someone could help. Thanks
Here's my JSFiddle
Edit:
I have this font that doesn't look good on letter spacing. I don't want to use a span class in my html since I don't want to do it manually on every single page or post that I make.
For example: I want to move all i's to the left since it has the same spacing in any word.

Append with some span element.Then apply the style for that span element using inline style or class name with css
var entryTitle = document.getElementsByClassName('entry-title')[0];
var str = entryTitle.innerHTML;
var newTitle = "";
for (var i = 0; i < str.length; i++) {
if (str[i] == 'e') {
newTitle += '<span class="add">' + str[i] + '</span>'
} else {
newTitle += str[i];
}
}
entryTitle.innerHTML = newTitle;
.add{
/*add your style here*/
color:red;
margin:-20px;
}
<h1 class="entry-title">"Homepage SlideShow"</h1>

var content = document.getElementById("content");
var entryTitle = content.getElementsByClassName('entry-title')[0];
var str = entryTitle.innerHTML;
var newTitle = "";
for (var i = 0; i < str.length; i++) {
if (str[i] == 'e') {
newTitle += "<span style='margin: 20px;'>" + str.charAt(i).fontcolor("red") + "</span>";
} else {
newTitle += str[i];
}
}
entryTitle.innerHTML = newTitle;
<div id="content">
<h1 class="entry-title">"Homepage SlideShow"</h1>
</div>

You can accomplish this with the CSS property letter-spacing apply on a <span> markup.
Here my jsfiddle bro --> http://jsfiddle.net/f6zn0svk/
.letter-spacing { letter-spacing: 10px; }
<h1 class="entry-title">"Hom<span class="letter-spacing">ep</span>age SlideShow"</h1>

Related

HTML + JS - Trying to surround some content that is created with a for loop with a div

I am coding an adventure game and have a primitive sortInventory() function. It cycles through the player.inventory array and displays each item in its own <div>. I want to surround the entire completed 'inventory' with a <div class="inv"> - here are the functions:
function sortInventory() {
var rowCount = 0;
var firstRowDone = false;
for(var i = 0; i < player.inventory.length; i++) {
rowCount++;
if(rowCount == 6 && firstRowDone == false) {
firstRowDone = true;
rowCount = 0;
dock.innerHTML += "<br>"
}
if(rowCount == 5 && firstRowDone) {
dock.innerHTML += "<br>"
rowCount = 0;
}
dock.innerHTML += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
}
}
function showInventory() {
dock.innerHTML = "<div class='inv'>";
sortInventory();
dock.innerHTML += "</div>"
}
This currently outputs:
<div class="inv"></div>
<div class="inv-item">..</div>
<div class="inv-item">..</div>
<!-- and so on -->
But I would like it to output:
<div class="inv">
<div class="inv-item">..</div>
<div class="inv-item">..</div>
<!-- and so on -->
</div>
How could I get it to achieve this and why does it close the tag early? Thanks in advance.
Instead of trying to write it in pieces, store it in a variable and write it all at once.
function sortInventory() {
var rowCount = 0;
var invList = '';
for(var i = 0; i < player.inventory.length; i++) {
rowCount++;
if(rowCount == 6 && firstRowDone == false) {
firstRowDone = true;
rowCount = 0;
dock.innerHTML += "<br>"
}
if(rowCount == 5 && firstRowDone) {
dock.innerHTML += "<br>"
rowCount = 0;
}
invList += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
}
return invList;
}
function showInventory() {
dock.innerHTML = "<div class='inv'>" + sortInventory() + "</div>";
}
This is happening because an open tag cannot live within the DOM without a close tag, with few exceptions like <br /> which is still valid as <br >, so most browsers will try to compensate for this and write the close tag for you.
In short, writing incrementally into the innerHTML tag is always a bad idea and will lead to unexpected results as most all browsers will try to correct it.
Using innerHTML can be cumbersome, not to mention (at times) dangerous. Instead, I would use the document.createElement and Node.appendChild methods.
function sortInventory() {
var rowCount = 0;
var inv = document.createElement('div');
inv.classList.add('inv');
for(var i = 0; i < player.inventory.length; i++) {
rowCount++;
if(rowCount == 6 && firstRowDone == false) {
firstRowDone = true;
rowCount = 0;
inv.appendChild(document.createElement('br'));
}
if(rowCount == 5 && firstRowDone) {
inv.appendChild(document.createElement('br'));
rowCount = 0;
}
var invItem = document.createElement('div');
invItem.classList.add('inv-item');
var invImg = document.createElement('img');
invImg.classList.add('inv-img');
invImg.setAttribute('src', player.inventory[i].img);
invItem.appendChild(invImg);
inv.appendChild(invItem);
}
dock.appendChild(inv);
}
function showInventory() {
sortInventory();
}
I think it closes the tag prematurely because the value received by .innerHTML removes all of the element's descendants and replaces them with nodes constructed by parsing the HTML given in the string. With constructed nodes, it means (in this case) if there is any unclosed tag, it will close it first (so it is a constructed node).
So in order to solve this, first build the string, and finally use the innerHTML in order to set the built value.
Following your logic, it would be something like this:
var newHtml = "";
function sortInventory() {
var rowCount = 0;
for(var i = 0; i < player.inventory.length; i++) {
rowCount++;
if(rowCount == 6 && firstRowDone == false) {
firstRowDone = true;
rowCount = 0;
newHtml += "<br>"
}
if(rowCount == 5 && firstRowDone) {
newHtml += "<br>"
rowCount = 0;
}
newHtml += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
}
}
function showInventory() {
newHtml = "<div class='inv'>";
sortInventory();
newHtml += "</div>"
dock.innerHTML = newHtml;
}
In order to create a wrapper element with the class .inv around the elements with .inv-item classes, construct the HTML content at a string in the sortInventory function, then return as the content to use, when setting the dock element's innerHTML:
var boxIcon = 'https://image.flaticon.com/icons/svg/122/122186.svg';
var player = {
inventory: [
{img: boxIcon},
{img: boxIcon},
{img: boxIcon}
]
};
var dock = document.getElementById('dock');
function sortInventory(inv) {
var rowCount = 0;
var content = ''
for (var i = 0; i < player.inventory.length; i++) {
rowCount++;
if (rowCount == 6 && firstRowDone == false) {
firstRowDone = true;
rowCount = 0;
content += "<br>"
}
if (rowCount == 5 && firstRowDone) {
content += "<br>"
rowCount = 0;
}
content += "<div class='inv-item'><img class='inv-img' width='32px' src='" + player.inventory[i].img + "'></img></div>";
}
return content;
}
function showInventory() {
dock.innerHTML = "<div class='inv'>" + sortInventory() + "</div>";
}
showInventory();
.inv {
background: #CCC;
}
<div id="dock"></div>
Credits to Flaticon
You could first create the item with the class "inv" and then get it by class name with document.getElementByClassName("inv") and then add with a forloop document.getElementByClassName("inv").innerHtml += <div class="inv-item">..<div>
Construct the HTML string completely then assign to innerHTML of the div, instead of assigning innerHTML 3 times.
Change sortInventory function to return string, append all the string and assign it as innerHTML at once.

Loop that changes letter colors

The purpose is to change color of all characters in #text one by one, I made a loop:
function myFunction() {
var letters = document.getElementById('text');
for (var i = 0; i < letters.innerHTML.length; i++) {
//only change the one you want to
letters.innerHTML = letters.innerHTML.replace(letters[i], '<span style="color: yellow;">'+letters[i]+'</span>');
}
}
It doesnt work but also doesnt show any errors.
https://jsfiddle.net/zkbctk2h/
I suggest to store the text of the element with id = "text" and build a new string out of the old text, because replace would replace the first found character which may not the wanted character, because the replaced character cold contain a character which should not be replaced.
function myFunction() {
var letters = document.getElementById('text'),
text = letters.innerHTML
letters.innerHTML = '';
for (var i = 0; i < text.length; i++) {
letters.innerHTML += '<span style="background-color: yellow;">' + text[i] + '</span>';
}
}
myFunction();
<div id="text">abracadabra</div>
Some typewriter functionality with setInterval and clearInterval
function myFunction() {
var letters = document.getElementById('text'),
text = letters.innerHTML,
i = 0;
return function () {
var j;
if (i < text.length) {
letters.innerHTML = '';
for (j = 0; j <= i; j++) {
letters.innerHTML += '<span style="background-color: yellow;">' + text[j] + '</span>';
}
letters.innerHTML += text.slice(j);
i++;
} else {
clearInterval(interval);
}
}
}
var interval = setInterval(myFunction(), 500);
<div id="text">abracadabra</div>
This is because you are updating the letters, and reading the next letter afterwards. You should use innerText instead of innerHTML because then you only get the text.
Example fiddle: https://jsfiddle.net/zkbctk2h/25/
function myFunction() {
var letters = document.getElementById('text'),
str = letters.innerText,
newString = "";
for (var i = 0; i < str.length; i++) {
//only change the one you want to
newString += '<span style="color: yellow;">'+str[i]+'</span>';
}
letters.innerHTML = newString;
}
I suggest to read once and write once to the dom. If you read and write a force redraw is triggered in the browser. Therefor it can get slow if you have large text.
Just suggesting a more functional approach:
const myFunction = id =>
document.getElementById(id).innerHTML
.split('')
.map(c =>
`<span style="color: green;">${c}</span>`
)
.join('')
document.getElementById('text').innerHTML = myFunction('text')
<div id="text">Hello World</div>

Regex: Match a word that is not surrounded by other characters and is also not in an HTML tag

I have no idea what is wrong with my code. For some reason, it matches only phrases that start with the letter s, when it is supposed to match a specific word not surrounded by other word characters, and that is not in an HTML tag. Here is my code:
<!DOCTYPE html>
<html>
<!--
YOUR WINNER REGEX IS...
(?![A-Za-z0-9\-])(?![^<]*>)
Your word before this
-->
<head>
<title>Edititing Tool</title>
<style>
#content {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<h1>EDITING TOOL</h1>
<h3>Paste in text and it SHOULD highlight each word in red</h3>
<div id="content" contenteditable onkeyup="contentchange()"></div>
<script>
var content = document.getElementById("content");//This is what you type into
var words, newText;
function contentchange() {
//Set variables
var contentText = content.innerText.split(/\s/g);//split what's inside the div by all whitespace (tabs, spaces, etc.)
newText = contentText;//make a new variable for that
words = {};
for (var i = 0; i < newText.length; i++) {
//make it all lowercase
newText[i] = newText[i].toLowerCase();
//Remove double-quotes
newText[i] = newText[i].replace('"', "");
//Remove other punctuation except for single quotes (for contractions) and dashes
//The reason this regex is so long is because of google drive and unicode. it really just means /[^\w\s'’-]/g
newText[i] = newText[i].replace(/(?:[\0-\x08\x0E-\x1F!-&\(-,\.\/:-#\[-\^`\{-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2018\u201A-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g,"");
}
//Remove all empty strings
newText = without(newText, "");
//Index everything; Make a variable holding how many times the word is used for every word
for (var i = 0; i < newText.length; i++) {
if (words[newText[i]]) {
words[newText[i]]++;
} else {
words[newText[i]] = 1;
}
}
var contentHTML = decodeHtml(content.innerHTML);//Take away all (because HTML does that)
//Get how many total words you have
var totalWords = 0;
for (var i = 0; i < Object.keys(words).length; i++) {
totalWords += words[Object.keys(words)[i]];
}
for (var i = 0; i < Object.keys(words).length; i++) {
var currentword = Object.keys(words)[i];
contentHTML = contentHTML.replace(new RegExp("(^|\s)("+currentword+")(?![A-Za-z\-])(?![^<]*>)", "ig"), function myFunction(x){return "<span style='color: red'>" + x + "</span>"; console.log("BOOBS LALALALA" + x);});
console.log(currentword);
console.log(words);
console.log(i);
}
content.innerHTML = contentHTML;
}
//Copied from stackoverflow, removes a certain string
function without(array, what) {
return array.filter(function(element) {
return element !== what;
});
}
//Change "September" to "[Ss][Ee][Pp][Tt][Ee][Mm][Bb][Ee][Rr]"
function anycaseRegex(string) {
var returnVal = "";
for (var j = 0; j < string.length; j++) {
returnVal += "[" + string.substring(j, j+1).toUpperCase() + string.substring(j, j+1).toLowerCase() + "]";
}
return returnVal;
}
//Because HTML does that
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
//PHP REGEX: (?<![A-Za-z0-9\-])[Hh][Ee][Ll][Ll][Oo](?![A-Za-z0-9\-])(?![^<]*>)
</script>
</body>
</html>
Here are a couple of regular expressions that I've used:
/[Hh][Ee][Ll][Ll][Oo](?![A-Za-z\-])(?![^<]*>)/g -- matches hello and ahello, when it should only match hello

Randomly change uppercase / lower case in html text

I have a HTML text element ex: an H1 tag called VIDEOS. Is there any way to use JS to randomly manipulate the capitalization of the text? So for instance on one instance it loads the text as viDEoS, on another it loads ViDeos and so on.
Each letter essentially randomly changes between uppercase & lowercase
Possible solution.
var elem = document.getElementById('vid');
elem.textContent = elem.textContent.split('').map((v) =>
Math.round(Math.random()) ? v.toUpperCase() : v.toLowerCase()
).join('');
<h1 id='vid'>videos</h1>
$('.randomize').each(function() {
var _word = $(this).html();
var _arr = _word.split('');
var _store = '';
var _style = '';
$(this).html('');
for (var i = 0, len = _arr.length; i < len; i++) {
if((Math.floor(Math.random() * 2) + 1) === 1) {
_style = 'uppercase';
}
else {
_style = 'lowercase';
}
_store = _store + '<span style="text-transform: '+ _style +' ;">' + _arr[i] + '</span>';
}
$(this).html(_store);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="randomize">Videos</h1>

detect natural line breaks javascript

When I type in a non-resizeable text area something like hello world, this is a demo and the text area is small enough, it will look like this:
hello world,
this is a demo
This is not caused by a \n or something.
How can I detect this natural line break in a text area?
A fiddle can be found here: http://jsfiddle.net/yx6B7/
As you can see, there is a line break, but javascript just says that it's one big line without any line-breaks in it.
Finally I found this script on the internet:
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
}
else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
document.getElementById("pnlPreview").innerHTML = oTextarea.value.replace(new RegExp("\\n", "g"), "<br />");
}
Which is working fine.
This isn't a javascript problem.
Look at the word-wrap, white-space and overflow css properties.

Categories

Resources