简体   繁体   English

从字符串中删除字符,忽略html标签

[英]strip characters from string ignoring html tags

I am using tinyMCE wysiwyg editor for textareas in one of my projects. 我在我的一个项目中将tinyMCE所见即所得编辑器用于textareas。 I have been looking for a way to limit the characters entered by a user. 我一直在寻找一种方法来限制用户输入的字符。

My requirements are: 我的要求是:

  • Do not let a user enter more than specified character limit. 用户输入的字符数不能超过限制。 (so the method should be bound to keyDown / keyUp event). (因此该方法应绑定到keyDown / keyUp事件)。
  • Make sure this works with copy / paste too (ie ctrl+v and right mouse click and paste ). 确保这也适用于复制/粘贴(即ctrl+v和鼠标右键单击并paste )。
  • On copy / paste the behavior should be --> strip the excess characters from the innerText and set the content to the stripped text but still keep the styles that were applied to the original content. 在复制/粘贴时,行为应为->从innerText删除多余的字符,然后将内容设置为被剥离的文本,但仍保留应用于原始内容的styles

I have had a look at the maxchars plugin but it just does not serve the purpose especially when it comes to the copy / paste functionality. maxchars插件,但它并没有达到目的,尤其是在copy / paste功能方面。 I tried implementing custom methods to achieve the above mentioned requirements. 我尝试实现自定义方法来实现上述要求。

What I have already achieved is as follows: 我已经实现的目标如下:


Prevent users from entering anymore characters once the character limit is reached. 一旦达到字符数限制,防止用户再输入字符。

function preventExcessChars(editor, event) {
    var body = editor.getBody(),
        limit = editor.settings.charLimit,
        text = body.innerText || body.textContent,
        length = text.length;

    if (length >= limit && isCharacterKeyPress(event)) {
        event.preventDefault();
        event.stopImmediatePropagation();
        return false;
    }   
}

Once bound to the keyDown or keyUp event this works fine and does not allow a user to enter anymore characters once the character limit is reached. 一旦绑定到keyDownkeyUp事件,此方法就可以正常工作,并且一旦达到字符数限制,就不允许用户再输入任何字符。 The problem with this is that it does not support copy / paste so a user can paste as many chars as he wants. 问题是它不支持copy / paste因此用户可以粘贴任意数量的字符。

Take care of copy / paste . 注意copy / paste

In order to implement the copy /paste functionality I thought it would be good to use the tinyMCE 's setContent method to update the content. 为了实现copy /paste功能,我认为最好使用tinyMCEsetContent方法更新内容。 so i updated the above to: 所以我将以上内容更新为:

function preventExcessChars(editor, event) {
    var body = editor.getBody(),
        limit = editor.settings.charLimit,
        text = body.innerText || body.textContent,
        length = text.length;

    if (length >= limit && isCharacterKeyPress(event)) {
        // update the content and use setContent to update the text area
        var new_content = text.substr(0, limit);
        editor.setContent(new_content);
        event.preventDefault();
        event.stopImmediatePropagation();
        return false;
    }   
}

This works pretty well. 效果很好。 The problem with this is that it does not apply the styles from the original content to the new content as new content is innerText object. 这样做的问题是,由于新内容是innerText对象,因此它不会将样式从原始内容应用于新内容。


Is there a way I can strip out characters from the innerHTML instead of innerText and avoid stripping any HTML tags included in the string ?? 有没有一种方法可以从innerHTML而不是innerText剥离字符,并避免剥离字符串中包含的任何HTML标记?

So for example say I have the following string: 举例来说,我有以下字符串:

 "<p>This is a <b>test</b>.</p><p>I have been <i>testing</i> this since morning.</p>";

the length of the innerText for the above string is 55 characters and say the limit is 50 chars. 上述字符串的innerText的长度为55字符,并且限制为50字符。 I want to strip out the last 5 characters from the above string so that the result is: 我想从上面的字符串中删除最后5字符,以便结果是:

 "<p>This is a <b>test</b>.</p><p>I have been <i>testing</i> this since mor</p>"

If I do this using the above code (ie using innerText ) the result I get is This is a test. I have been testing this since mor 如果使用上面的代码(即使用innerText )执行This is a test. I have been testing this since mor得到的结果是This is a test. I have been testing this since mor This is a test. I have been testing this since mor . This is a test. I have been testing this since mor How can I get the above result that includes the html tags ? 如何获得包含html标签的上述结果?

You can use this function: 您可以使用此功能:

function maxChars(str, max) {
  var tags = 0,
      sQuotes = 0,
      dQuotes = 0,
      char,
      count = 0,
      result = [];
  for (var i = 0, len = str.length; i < len; ++i) {
    char = str.charAt(i);
    switch(char) {
      case '<':
        if (!sQuotes && !dQuotes) {
          ++tags;
          result.push(char);
          continue;
        }
        break;
      case '>':
        if (!sQuotes && !dQuotes) {
          --tags;
          result.push(char);
          continue;
        }
        break;
      case "'":
        if (tags && !dQuotes)
          sQuotes = !sQuotes;
        break;
      case '"':
        if (tags && !sQuotes)
          dQuotes = !dQuotes;
        break;
    }
    if (tags) {
      result.push(char);
    } else {
      if (++count < max)
        result.push(char);
    }
  }
  return result.join('');
};

// Example
var text = "<p>This is a <b>test</b>.</p><p>I have been <i>testing</i> this since morning.</p>";
maxChars(text, 50);
// "<p>This is a <b>test</b>.</p><p>I have been <i>testing</i> this since mor</p>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM