Emotions.js



The article describes the experience of creating a text field with the ability to insert smiles, the problems that I encountered and their solutions, as well as a link to the repository with a ready-made jQuery plugin. If you are interested, please, under cat.

During the development of my first project, I was given the task of creating a chat with emoticons. The main chat functionality was ready, but when I started emoticons, I had a problem, I couldn’t insert the emoticon at the current cursor position, it turned out only at the beginning or end of the text field. I had zero experience, both in programming and in the search for the necessary information, so I could not find anything "workable" and even more ready-made solutions. After two or three weeks of torment, I gave up and had to say the words “I can’t realize this” that I hate.

About three years have passed and recently my colleague faced the same task, he asked me how to do this. Memories of failure suddenly surged and I wanted to solve my long-standing impossible task.

The search for a ready-made solution again ended to no avail, but the documentation was already much better, learning about document.getSelection (), I immediately rushed to write the code and of course I met a few more problems and, as always, it took the most time.

I found something like this
if (window.getSelection) {
    var sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
        var range = window.getSelection().getRangeAt(0);
        range.insertNode(document.createTextNode(text));
    }
}

What was obvious, when you clicked on the smiley, the focus moved to it and the content we needed was inserted into it, and not into our text field. The decision was simple, to prohibit focusing on a block with emotions.
$emojiContainer.attr({
  unselectable: 'on',
       onselectstart: 'return false;',
       onmousedown: 'return false;'
});


The second problem turned out to be more difficult for me, the smile was inserted after the cursor, but the cursor itself did not move forward, and therefore each subsequent emotion was ahead of the previous one.

After reading a great article from bur, things got a little clearer.
I wrote a function that inserts the cursor after the element, the solution turned out to be simple.

function SetCursorAfterElement(element)
{
    var selection = window.getSelection();
    selection.removeAllRanges();
    var range = document.createRange();
    range.setStartAfter(element);
    selection.addRange(range);
}


This is currently a jQuery plugin and is supported by IE9 + browsers. The immediate plans are to rewrite the code without using jQuery and with support for older browsers, and the code is not thought out well, without much flexibility. I would be glad if someone saved time.

KEmoji.js
Demo

Update
The code is copied to native js, the script is optimized, emoticons are moved to one image + the emoticon map generator (in php) is added, which from the folder with emoticons makes one image with a css file

Also popular now: