3

我知道 HTML 有一个maxlength属性,但我想限制输入的字数而不是字符数。

10 个单词后,用户应该能够向左移动光标并编辑文本,但不能再添加任何单词。

那么如何停止光标呢?

有什么建议么?

请只使用javascript。

4

5 回答 5

0

(这个问题并不完全清楚......我假设它的意思是“我如何防止用户在文本区域中输入超过十个单词?”)

我认为您将很难实现这一目标。例如,Paste 怎么样?

这是一个替代建议,它可能适合您正在做的事情:现代 UI(例如 Twitter)处理此问题的一种方式是设置字母计数或字数计数,一旦您过去,它就会变成红色极限。如果您尝试提交表单,则会收到错误消息。这比试图阻止用户首先输入十多个单词要容易得多。

于 2013-06-05T20:41:16.487 回答
0

像@sgroves 一样,这个答案只是为了好玩:)

$(document).ready(function(){

  $('textarea').on('keydown', function(e){
    // ignore backspaces
    if(e.keyCode == 8)
      return;

    var that = $(this);
    // we only need to check total words on spacebar (i.e the end of a word)
    if(e.keyCode == 32){
      setTimeout(function(){ // timeout so we get textarea value on keydown
        var string = that.val();
        // remove multiple spaces and trailing space
        string = string.replace(/ +(?= )| $/g,'');
        var words = string.split(' ');
        if(words.length == 10){
          that.val(words.join(' '));
        }
      }, 1);
    }
  });
});
于 2013-06-05T22:07:26.087 回答
0

这并不涵盖所有可能的用户操作,但我很无聊,也许你会学到一些东西:

HTML:

<textarea id="input_box"></textarea>

JavaScript:

function check_words(e) {
    var BACKSPACE  = 8;
    var DELETE     = 46;
    var MAX_WORDS  = 10;
    var valid_keys = [BACKSPACE, DELETE];
    var words      = this.value.split(' ');

    if (words.length >= MAX_WORDS && valid_keys.indexOf(e.keyCode) == -1) {
        e.preventDefault();
        words.length = MAX_WORDS;
        this.value = words.join(' ');
    }
}

var textarea = document.getElementById('input_box');
textarea.addEventListener('keydown', check_words);
textarea.addEventListener('keyup', check_words);

在 JS Bin 上试用:http: //jsbin.com/isikim/2/edit

  • 如果有 10 个单词textarea并且用户按下一个键,则不会发生任何事情。
  • 如果用户试图复制和粘贴一大段文本,文本的内容textarea将立即被精简到只有 10 个单词。

实际上,我不确定这并不完美。由于 JavaScript 在客户端上运行,因此您只需要适用于普通用户的东西。恶意用户总能搞砸你的 JavaScript;没办法。只要您在服务器上进行真正的卫生处理,就应该没有问题。

于 2013-06-05T20:58:08.587 回答
0

HTML5 验证适用于以下任务:

<input 
  pattern="([\w]+\s?){0,5}" 
  onkeypress="if(!this.validity.valid){this.value=this.value.slice(0,-1);return false;}"/>

如果要提交,您可以省略 onkeypress 处理程序,因为如果某些内容无效,表单将不会提交。

可以使用 poly-fills 来支持具有这种语法的旧浏览器。

于 2013-06-05T21:11:43.150 回答
0

最近遇到了类似的问题......这是我的看法

请参阅下面和codepen.io上的演示:

'use strict';

let WordLimiter = function(el){

  el.constraints = {

    /**
     * Events to listen to
     */
    eventListeners: [
        'keyup',
        'input'
    ],

    events: {
      onWordLimiterCount: new CustomEvent('onWordLimiterCount',{
        detail: {
           value: 0,
           words: []
        }
      })
    },

    limit: null,
    validValue: '',

    /**
     * Checks if the
     * @returns {boolean}
     */
    passed: function(){
      return this.wordCount() <= this.getLimit();
    },

    /**
     * Check if the element has a valid limit
     * @returns {boolean}
     */
    hasLimit: function(){
      return false !== this.getLimit();
    },

    getLimit: function(){
      this.limit = parseInt( this.element.dataset.wordLimit );
      this.limit = isNaN( this.limit ) || this.limit <= 0 ? false : this.limit;
      return this.limit;
    },

    getWords: function(){
      this.words = this.element.value.split(' ');

      /**
       * Removes words that are just empty strings
       */
      this.words = this.words.filter(function (el) {
        return el !== null && el.trim() !== '';
      });
      return this.words;
    },

    /**
     * Gets the word count
     * Also triggers an event that you can hook into
     * @returns {number}
     */
    wordCount: function(){
      this.events.onWordLimiterCount.detail.words = this.getWords();
      this.events.onWordLimiterCount.detail.value = this.getWords().length;
      document.dispatchEvent(this.events.onWordLimiterCount );
      return this.events.onWordLimiterCount.detail.value;
    },

    /**
     * Checks constraints
     * @returns {boolean}
     */
    verify: function(){
      console.clear();

      if( !this.constraints.passed() ){
        console.info( 'FAILED' );

        /**
         * Prevent any further input
         */
        event.preventDefault();
        event.stopPropagation();

        /**
         * Revert back to the last valid input
         * @type {string}
         */
        this.value = this.constraints.validValue;
        return false;
      }

      console.info( 'PASS' );
      this.constraints.validValue = this.value;
      return true;
    },

    /**
     * Scope purposes
     */
    element: el,
  };


  if( !el.constraints.hasLimit() ){
    console.groupCollapsed( 'TextArea does not have a valid limit' );
    console.info( el );
    console.groupEnd();
    return;
  }

  el.constraints.eventListeners.forEach(function(e){
    el.addEventListener(e, el.constraints.verify );
  });

};

/**
 * Looks for all textarea elements with the data-word-limit attribute
 */
document.addEventListener("DOMContentLoaded", function(){
  let textAreas = document.querySelectorAll("textarea[data-word-limit]");

  textAreas.forEach(function(i){
    new WordLimiter(i);
  });

}, true );

let CodePenDemo = {

  init: function(){
    document.addEventListener( 'onWordLimiterCount', function(e){
      document.getElementById('counter').value = e.detail.value;
    })
  },

  setWordLimit: function(){
    document.getElementById('textarea-limited').setAttribute( 'data-word-limit', event.srcElement.value );
  }
};

CodePenDemo.init();
<html>
<head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
	<script src="index.js"></script>
</head>
<body class="bg-light">
    <div class="container my-3">
        <h2>TextArea with Word Limit</h2>

        <div class="form-group">
            <label for="word-limit">Word Limit</label>
            <input id="word-limit" type="number" min="1" class="form-control" value="50" onchange="CodePenDemo.setWordLimit();"/>
        </div>
        
        <div class="form-group">
            <label for="textarea-limited">TextArea</label>
            <textarea id="textarea-limited" class="form-control" data-word-limit="50" rows="10" cols="20"></textarea>
        </div>
        
        <div class="form-group">
            <label for="counter">Words Count</label>
            <input type="number" id="counter" class="form-control" />
        </div>
    </div>
</body>
</html>

于 2018-11-13T10:23:47.643 回答