用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(/&nbsp;/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(/&nbsp;/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;