Forum Moderators: open
var emoji = {
':)' : 'emoji_grin.gif',
':D' : emoji_smile.gif'
};
var array = [];
// using jQuery
$('#str)
.on('keyup', function(e) {
// colon = 186
if (array.length == 0 && e.which == 186) {
array.push(':');
return;
}
// hyphen = 189, 173 in FF
if (array.length == 1 && (e.which == 189 || e.which == 173)) {
return;
}
// so far it looks like an emoji, go ahead and add whatever the next character is
if (array.length == 1 && e.which !== 189 && e.which !== 173) {
array.push(e.which);
return;
}
// enter = 13, whitespace = 32
// replace matching text then empty array
if (array.length == 2 && (e.which == 13 || e.which == 32)) {
str.replace(new RegExp(array.join('') + '\s+$'), emoji{array.join('')});
array = [];
}
// they pressed space or enter with no final character, empty array
elseif (e.which == 13 || e.which == 32)
array = [];
}); I think that would be noticeably slow for people like myself that type fast.
You think, but have you tried? It may not be as slow as you expect.
Alternatively, you could look at the characters preceding the caret position, like so: [stackoverflow.com...] But that still wouldn't account for all the possible ways a user might type out an emoticon, e.g. when one types -D and only later adds the preceding colon. To take all of that into account, you'll need quite a bit of code and I suspect a regex would be far more efficient. But obviously that is something you could benchmark.
You could also put in a brief delay so the regex only runs when the user stops typing. var emoji = {
':)' : 'emoji_grin.gif',
':D' : 'emoji_smile.gif'
};
// look for period of no-typing; 2000 = 2s
var typingDelay = 2000,
array = [],
typingTimer;
// using jQuery
$('#str')
.on('keyup', function(e) {
var x = e.which;
// Change to emoji when they hit space or enter
//
// colon = 186
if (array.length == 0 && x == 186) {
array.push(':');
return;
}
// hyphen = 189, 173 in FF
if (array.length == 1 && (x == 189 || x == 173))
return;
// so far it looks like an emoji, go ahead and add whatever the next character is
if (array.length == 1 && x !== 189 && x !== 173) {
array.push(x);
return;
}
// enter = 13, whitespace = 32
// replace matching text then empty array
if (array.length == 2 && (x == 13 || x == 32)) {
str.replace(
new RegExp(array.join('') + '\s+$'),
emoji[array.join('')]
);
array = [];
}
// they pressed space or enter with no final character, empty array
elseif (x == 13 || x == 32)
array = [];
// Run full regex when they stop typing as a backup
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, typingDelay);
})
// clear the countdown
.on('keydown', function () {
clearTimeout(typingTimer);
});
function doneTyping() {
$('#str').html(function(i, val) {
$.each(Object.keys(emoji), function(i, v) {
// allow for emojis with - since they're not in the main list; eg, :-D
// then escape anything not a letter, number, or ?
var escapedV = v.slice(0, 1) + '-?' + v.slice(1);
escapedV = escapedV.replace(/([^\w?])/g, "\\$1");
// why doesn't it match with an opening \b?
// new RegExp('\\b' + v + '\\b', 'g'),
val = val.replace(
new RegExp(v + '\\b', 'g'),
emoji[v]
);
});
return(val);
});
}
Raise your hand if you remember a time when there were no emojis...
Other option is to paint an insert table of allowed emoticons at point insert (cursor) outside the text area. Keeps code simple, predictable, and easier to sanitize before db insert.
maybe 10 people that still type out ascii emojis like mePlot twist: 9 of those 10 people actually expect to see the ;-P or :-o that they typed, and will be annoyed and disconcerted when it turns into a fancy emoji.