对 textarea 或 contenteditable 的表情符号支持 div

Emoticons support for textarea or contenteditable div

正在尝试实现一个 textarea 带有表情符号支持的组件 同时 写作。

我希望能够在呈现 filtered/generated html 结果(使用 angular 表情过滤器) 在 div.

我最初的解决方案是

<textarea ng-model="text" ng-change="..." ng-focus="..."></textarea>
<div ng-bind-html="text | myEmoticonsFilter"></div>

但是我在使用隐藏文本区域时遇到了问题。另外,有了这个,我将无法安全地鼠标select文本和删除或copy/paste。

我也想过使用<div contenteditable="true">,但是ng-focusng-change不会被处理。

有人对如何继续这个有任何建议吗?

编辑 1:这是一个 jsfiddle 尝试我正在做的事情。到目前为止,能够替换第一次出现的情况,但此后行为仍然不稳定。我正在使用 contenteditable 指令进行双向数据绑定并过滤表情符号模式。

编辑 2:关于我说 ng-focusng-change 不会被处理的声明,那是不正确的 - ng-focus只要使用 ngModel 声明指令并设置适当的 $modelValue$viewValue(提供了一个示例),<div contenteditable="true">ng-change 将在本地工作在 jsfiddle 编辑 1).

以一致的跨浏览器方式执行此操作的唯一方法是使用将表情符号转换为图像的所见即所得字段。

有一个 jQuery 插件 jquery-emojiarea 可以满足您的需求,因此您只需要创建一个包装此插件的指令即可开始比赛。由于它输入到带有表情符号语法的隐藏文本区域 :smile: angular 应该没有困难绑定。

这是我整理的工作指令。 http://jsfiddle.net/dboskovic/g8x8xs2t/

var app = angular.module('app', []);
app.controller('BaseController', function ($scope) {
    $scope.text = 'This is pretty awesome. :smile: :laughing:';
});
app.directive('emojiInput', function ($timeout) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function ($scope, $el, $attr, ngModel) {
            $.emojiarea.path = 'https://s3-us-west-1.amazonaws.com/dboskovic/jquery-emojiarea-master/packs/basic';
            $.emojiarea.icons = {
                ':smile:': 'smile.png',
                ':angry:': 'angry.png',
                ':flushed:': 'flushed.png',
                ':neckbeard:': 'neckbeard.png',
                 ':laughing:': 'laughing.png'
            };
            var options = $scope.$eval($attr.emojiInput);
            var $wysiwyg = $($el[0]).emojiarea(options);
            $wysiwyg.on('change', function () {
                ngModel.$setViewValue($wysiwyg.val());
                $scope.$apply();
            });
            ngModel.$formatters.push(function (data) {
                // emojiarea doesn't have a proper destroy :( so we have to remove and rebuild
                $wysiwyg.siblings('.emoji-wysiwyg-editor, .emoji-button').remove();
                $timeout(function () {
                    $wysiwyg.emojiarea(options);
                }, 0);
                return data;
            });
        }
    };
});

和用法:

<textarea ng-model="text" emoji-input="{buttonLabel:'Insert Emoji',wysiwyg:true}"></textarea>

If you want the editable field to convert text like :( as you type you'll need to fork that jquery plugin and modify it slightly to parse input text on change as well as on init. (like, a couple lines of code)