Last time, I covered Using string's replaceAll function to convert emoticons into emojis and hope you enjoy. This time, we improve the functionality with live typing emoticons upon <input/>
or <textarea/>
will result in emojis. As you can see, in many situations, this live typing is much more pleasant then having to convert the whole text to emojis so here we go.
The code
The UI
Copy the code here to your main html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Emoticons to Emojis</title>
<script src="regex.js"></script>
<script src="run.js"></script>
</head>
<body>
<h1>Emoticons to Emojis live typing
</h1>
<p>Type emoticons in the textarea below to see emojis :D</p>
<div>
<textarea id="live" rows="10" cols="80"></textarea>
</div>
</body>
</html>
Get the helper library
My script I write use a regex builder from https://github.com/wyantb/js-regex so grab the script file at https://github.com/wyantb/js-regex/raw/master/regex.js and put it into directory. Its name is regex.js as referenced by the html.
Create the main script file
Create a run.js
file and copy the following code to it
let emoticons = {
"(:": "🙃",
":)": "🙂",
":')": "🥲",
":))": "😂",
"=))": "🤣",
";)": "😉",
":D": "😀",
":P": "😋",
"B)": "😎",
":*": "😗",
":(": "🙁",
":'(": "😥",
":((": "😭",
":o": "😮",
">:(": "😠",
">:-(": "😡",
}
const pattern = (function () {
let r = regex.create().either();
let cmp = function (a, b) {
let d = a.length - b.length;
if (d)
return -d;
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
}
for (let key of Object.keys(emoticons).sort(cmp))
r.literals(key)
return new RegExp(r.endEither().peek(), "gu");
})();
const mlength = (function () {
let m = 0;
for (let key of Object.keys(emoticons))
if (key.length > m)
m = key.length;
return ++m;
})();
function getEmoji(emoticon) {
if (emoticon in emoticons)
return emoticons[emoticon];
return "";
}
function cvE2E(str) {
return str.replaceAll(pattern, getEmoji)
}
function handleInput(e) {
if (e.type == "input" && e.inputType == "insertText" && e.data == " ") {
let input = e.target;
let start = Math.max(input.selectionEnd - mlength, 0) | 0;
input.setSelectionRange(start, input.selectionEnd);
let replaced = cvE2E(input.value.substring(start, input.selectionEnd));
input.setRangeText(replaced, start, input.selectionEnd, 'end');
}
}
function install(input) {
input.addEventListener('input', handleInput);
}
document.addEventListener('DOMContentLoaded', function () {
install(document.getElementById('live'));
});
Understand how it works
To do live typing emoticons to emojis, we will have to attach a listener to the input
event of the input
or textarea
, thus the install
and handleInput
functions. Every time user inputs a blank space, we will extract the text, convert any emoticons found to emojis and put it back into the element. About the replacing, you can read my previous article (link above) to grab the main idea. This time, the idea is basically the same but we have to do a little trick to improve the performance. Rather than extract the whole text, we will extract a short sub string from input position indicated by the selectionEnd
property. To know the length, we will have to iterate through the emoticons
object's keys to find the max length of the emoticons (remember to increase it to 1 to also count the blank space inserted) and store it to the mlength
constant. So now, when user insert a blank space, just extract the sub string with mlength
characters from the inserted position backward and do the replacement. After that, just put the text back and you have the live typing result.
Again, hope you enjoy the article and have fun typing emoticons^^
Top comments (0)