gpt4 book ai didi

javascript - 带有 contenteditable 的真实计数器

转载 作者:行者123 更新时间:2023-11-27 23:22:42 26 4
gpt4 key购买 nike

几天来我一直在寻找解决方案,以添加与我的指令 contenteditable 关联的字符计数器。

很遗憾,我找不到解决方案。

为了突出这个问题,不同的浏览器对 contenteditable 有不同的行为。

这是我正在使用的指令:

var app = angular.module("App", []);
app.directive("contenteditable", function($timeout) {
return {
restrict: 'A',
require : ['^?ngModel'],
link : function(scope, element, attrs, args){
var ngModel = args[0];
if (ngModel === null) {
return null;
}

var modelKey = getModelKey();
opts = {
onlyText: false,
convertNewLines: false,
noLf: false,
};
angular.forEach(['onlyText', 'convertNewLines', 'noLf'], function (opt) {
if (attrs.hasOwnProperty(opt) && attrs[opt] && attrs[opt] !== 'false') {
opts[opt] = true;
}
});

$timeout(function () {
return (opts.onlyText && opts.noLf) ? element.text(ngModel.$modelValue) : element.html(ngModel.$modelValue);
});

var validate = function (content) {
var length = content.length;
refreshFn = function(content) {
if (content == undefined || content == null) {
content = '';
}
scope.maxCharacter= attrs.ngMaxlength;
scope.remaining = (length);
};
scope.$watch('ngModel', function(content){
refreshFn(content);
}, true);

if (length > attrs.ngMaxlength) {
ngModel.$setValidity(modelKey, false);
return element.addClass('-error');
}

if (element.hasClass('-error')) {
ngModel.$setValidity(modelKey, true);
return element.removeClass('-error');
}
};

var read = function () {
var content = '';
if ((opts.onlyText && opts.noLf)) {
content = element.text();
} else {
content = element.html();
if (content) {
content = parseHtml(content);
}
}

if (content !== '') {
content = content.replace(/ /g, '');
content = content.trim();
}
ngModel.$setViewValue(content);
validate(content);
};

ngModel.$render = function () {
if ((opts.onlyText && opts.noLf)) {
element.text(ngModel.$viewValue || '');
} else {
element.html(ngModel.$viewValue || '');
}
};

element.bind('blur keyup change focus', function (event) {
scope.$apply(read);
scope.displayCount = true;
if (event.type === 'blur') {
scope.$apply(ngModel.$render);
}
});

function getModelKey() {
if (typeof attrs.ngModel === 'undefined') {
return null;
}
var split = attrs.ngModel.split('.');
return split[split.length-1];
}

function parseHtml(html) {
html = html.replace(/ /g, '');
if (opts.convertNewLines || opts.noLf) {
var lf = '\r\n',
rxl = /\r\n$/;

if (opts.noLf) {
lf = ' ';
rxl = / $/;
}

html = html.replace(/<br(\s*)\/*>/ig, ''); // replace br for newlines
html = html.replace(/<[div>]+>/ig, lf); // replace div for newlines
html = html.replace(/<\/[div>]+>/gm, ''); // remove remaining divs
html = html.replace(/&nbsp;/g, '');
html = html.replace(/<[p>]+>/ig, lf); // replace p for newlines
html = html.replace(/<\/[p>]+>/gm, ''); // remove remaining p
html = html.replace(/<[span>]+>/ig, lf); // replace p for newlines
html = html.replace(/<\/[span>]+>/gm, ''); // remove remaining p
html = html.replace(rxl, ''); // remove last newline
html = _.unescape(html); // replaces &amp;, &lt;, &gt;, &quot;, &#96; and &#x27; with their unescaped counterparts.
}
if (opts.onlyText) {
html = html.replace(/<\S[^><]*>/g, '');
}

return html;
}
}
};
});

和 html 文件:

     <div class="content-editable" contenteditable="true"                                        
ng-model="line.value"
ng-maxlength=255
only-text="true"
convert-new-lines="true"
no-lf="false">
</div>
<div ng-if="displayCount" class="ctn" ng-if="countChar">
<span class="numberChar">
<span class="italic" style="margin-right:5px;">
<span ng-class="remaining>=maxCharacter ? 'errorMsg': ''">
{{remaining}}
</span> / {{maxCharacter}}
</span>
<span class="errorMsg error" ng-if="remaining>=maxCharacter"></span>
</span>
</div>
</div>

codepen 上的示例:https://codepen.io/gregand/pen/yLBjWYW

在 Chrome 和 Firefox 上,当我输入 6 个字符(包括换行符)时,计数器计数为 9 个字符

enter image description here

在 Edge 上,计数器很好

enter image description here

我尝试将 display: block 的 contenteditable css 更改为 inline-block,它纠正了 Chrome 上的问题,但在 Edge 上存在问题。

我试过

document.execCommand('defaultParagraphSeparator', false, 'p');

但没有成功。

如果有人知道适用于所有浏览器的解决方案,我会很感兴趣

最佳答案

我找到了解决方案,实际上问题来自下一行:

var lf = '\r\n'

我要求每个标签的替换为变量lf

html = html.replace(/<[div>]+>/ig, lf);

'\r\n'统计两个字符,一个为'\r',另一个为'\n'

而换行符应该只有一个字符。

因此,对于解决方案,我替换了变量 lf

 var lf = '\n'

它适用于多种浏览器

https://codepen.io/gregand/pen/yLBjWYW

关于javascript - 带有 contenteditable 的真实计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57926374/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com