前言
在项目中遇到需要使用标签属性contenteditable
来替代<textarea>
,实现输入内容的自动高度,但是<div>
或者<p>
标签并不是一个输入控件,不能直接被 ngModel 绑定,这个时候就需要把 contenteditable 做成一个 directive 来实现双向绑定:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| app.directive("contenteditable", function () { return { require: "ngModel", link: function (scope, element, attrs, ctrl) { function deleteBr(sHtml) { return sHtml.replace(/<br>/g, ""); } element.bind("input", function () { scope.$apply(function () { element.html(deleteBr(element.html())); ctrl.$setViewValue(element.html()); }); });
ctrl.$render = function () { element.html(ctrl.$viewValue); };
ctrl.$render(); }, }; });
|
注意
- 在 div 中输入回车是会被转义成
<br>
,而在实际使用中可能需要禁止回车,所以在 directive 中需要把回车产生的<br>
过滤掉;
- 在 html 中需要设置
contenteditable="plaintext-only"
控制输入的内容为纯文本,因为复制过来的一些内容可能会被带上一些文字样式;
- 在 model 中输入<> 会被转义,解决办法是在 controller 里面先过滤一遍数据(输出的时候也需要过滤一次)
1 2 3 4 5 6
| function html2Escape(sHtml) { return sHtml.replace(/[<>&"]/g, function (c) { return { "<": "<", ">": ">", "&": "&", '"': """ }[c]; }); } $scope.text = html2Escape($scope.text);
|