用contenteditable计算字符数
Calculate the number of characters with contenteditable
我使用以下指令在标签上输入可编辑的内容
我修改了它以添加一个字符计数器。
但是当我换行时,它会计算更多字符。
在图像中,计数器显示 4 个字符,而在视觉上只有两个。
这里的<
变成了4个字符而不是一个字符,而不是直接“>”
如何实际计算字符数
这里是使用的指令
directives.directive('contenteditable', ['$timeout', function($timeout) {
return {
restrict: 'A',
require: ['^?ngModel'],
link: function(scope, element, attrs, args) {
var ngModel = args[0];
if (ngModel === null) {
return null;
}
// console.log(element);
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', function(event) {
scope.$apply(read);
scope.displayCount = true;
if (element.text().length >= attrs.ngMaxlength) {
event.preventDefault();
return false;
}
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(/<[p>]+>/ig, lf); // replace p for newlines
html = html.replace(/<\/[p>]+>/gm, ''); // remove remaining p
html = html.replace(rxl, ''); // remove last newline
}
if (opts.onlyText) {
html = html.replace(/<\S[^><]*>/g, '');
}
return html;
}
}
};
}]);
因为换行在Windows中有2个字符,在Linux中有1个字符。同样,space 是一个字符,虽然在视觉上不是一个字符,而是一个空的 space,换行符是另一个字符。
"Visually there are only two" 是错误的,因为您可以看到一个换行符,这是一个视觉修改(与 space 相同的方式,我重复)。
如果您不想计算换行数,只需在获取 length
之前将其删除即可。换行有两个字符:\r
和\n
,所以:
var length = content.replace(/\r|\n/g, "").length;
如果您想删除所有换行符、spaces 等以仅计算 视觉字符,那么您只需:
var length = content.replace(/\s+/g, "").length;
我使用以下指令在标签上输入可编辑的内容
我修改了它以添加一个字符计数器。
但是当我换行时,它会计算更多字符。
在图像中,计数器显示 4 个字符,而在视觉上只有两个。
这里的<
变成了4个字符而不是一个字符,而不是直接“>”
如何实际计算字符数
这里是使用的指令
directives.directive('contenteditable', ['$timeout', function($timeout) {
return {
restrict: 'A',
require: ['^?ngModel'],
link: function(scope, element, attrs, args) {
var ngModel = args[0];
if (ngModel === null) {
return null;
}
// console.log(element);
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', function(event) {
scope.$apply(read);
scope.displayCount = true;
if (element.text().length >= attrs.ngMaxlength) {
event.preventDefault();
return false;
}
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(/<[p>]+>/ig, lf); // replace p for newlines
html = html.replace(/<\/[p>]+>/gm, ''); // remove remaining p
html = html.replace(rxl, ''); // remove last newline
}
if (opts.onlyText) {
html = html.replace(/<\S[^><]*>/g, '');
}
return html;
}
}
};
}]);
因为换行在Windows中有2个字符,在Linux中有1个字符。同样,space 是一个字符,虽然在视觉上不是一个字符,而是一个空的 space,换行符是另一个字符。
"Visually there are only two" 是错误的,因为您可以看到一个换行符,这是一个视觉修改(与 space 相同的方式,我重复)。
如果您不想计算换行数,只需在获取 length
之前将其删除即可。换行有两个字符:\r
和\n
,所以:
var length = content.replace(/\r|\n/g, "").length;
如果您想删除所有换行符、spaces 等以仅计算 视觉字符,那么您只需:
var length = content.replace(/\s+/g, "").length;