在做問答的時候,遇到一個需求,用戶的問題需要限制字數,不僅顯示計算的超出字數,還需在超出的內容上加一些提醒的效果,例如豆瓣首頁的話題輸入框,抽時間研究了下,需要考慮下面幾個問題:
1、輸入框的高度是固定的,如果超出高度需要滾動顯示(可上下鍵移動顯示)
2、隨時計算輸入的字數,并顯示在下方
3、根據計算結果將多出的部分加背景顯示(textarea里是不可以加背景的 :< )
4、根據3分析,需要加個hack實現(加個highlight的div),如果超出此div需要根據teatarea的scrollTop添加移動的距離
5、考慮輸入的各種內容及粘貼的情況
下面就一步一步來實現這種效果,先貼個圖看看效果:
html代碼如下:
<div id="container"><div class="text-wrap"><div class="highlight"></div></div><textarea autocomplete="false"></textarea><p class="count">140</p> </div>
?
因為要考慮到textarea的文字與highlight的代碼完全重合,那么定義的樣式需要完全相同,且因輸入的文字有限制,所以考慮去掉輸入框的滾動條:
textarea::-webkit-scrollbar {display:none}
完整的css如下:


#container {position: relative;}.text-wrap {height: 200px;width: 500px;padding: 5px 5px 5px 5px;overflow: hidden;position: absolute;top: 0;left: 0;z-index: 9;}textarea, .highlight {width: 500px;font-family: arial,sans-serif;font-size: 14px;}textarea {min-height: 200px;border: 1px solid #ccc;padding: 5px 5px 5px 5px;position: relative;background: none;resize: none;z-index: 10;}textarea::-webkit-scrollbar {display:none}.highlight {min-height: 200px;white-space: pre-wrap;word-wrap: break-word;color: transparent;}.highlight span {background: #fcc;}.error {color: red;}
?
除了html、css外,最最重要的就是js了,只有她才可以帶來神奇的效果,她是不可替代的唯一,她是實現你與機器之間的紐帶,有了她,不困了、不累了、不餓了,O(∩_∩)O~~
既然考慮到每次輸入的時候去查字數,那么就涉及到了事件,keyup和input,所以在textarea上添加這兩個事件,只有觸發這兩個事件時才執行下面的一系列操作。
查字:首先計算是否超出字數,這是常見的限定字數輸入框,各種微博、評論基本上都用到這個,定義兩個變量,考慮會粘貼或輸入代碼,所以替換了'<' 和 '>',len等于文字的長度,
如果len大于設定的最大值需要處理兩步:
1、顯示當前字數為醒目的紅色,提醒用戶超出字數限定范圍
2、給超出的字數加背景
text = $.trim($this.val().replace(/</g, '>').replace(/>/g, '<')) len = text.length
全部js代碼如下,注釋非常清楚的說明了各部分的內容


var MAX = 140,$text = $('textarea'),$highlight = $('div.highlight');$text.on('keyup input', function() {var $this = $(this),text = $.trim($this.val().replace(/</g, '>').replace(/>/g, '<')),len = text.length,count = Math.floor(MAX-len);if(count < 0) {$('p.count').addClass('error')}else{$('p.count').removeClass('error')}// 顯示當前字數$('p.count').text(count)// 將文字分成兩部分,超出的內容用span包起來,css加紅色背景樣式$highlight.html(text.slice(0, MAX) + '<span>' + text.slice(MAX) + '</span>')// 考慮粘貼時,內容超出,高亮部分需要重置位置 resetMask()}).on('scroll', function() {// textarea滾動時,重置高亮部分的位置 resetMask()})// 高亮內容位置隨文本框內容的位置重置function resetMask() {var textScrollTop = $text.scrollTop();if(textScrollTop > 0) {$highlight.css('margin-top', -textScrollTop);return}$highlight.css('margin-top', 0)}
最終效果地址:https://codepen.io/mengyun/pen/eEbryJ
?