2011-05-26 61 views
64

我想要一個textarea,處理按標籤鍵的情況。如何在textarea中處理<tab>?

默認情況下,如果您按選項卡鍵,則焦點將離開文本區域。但是,當用戶想要在textarea中鍵入選項卡鍵時,情況如何?

我可以捕獲此事件並將焦點返回到textarea並將一個標籤添加到當前光標位置?

+0

這可能與JavaScript。 Ajaxian有一個很好的答案:http://ajaxian.com/archives/handling-tabs-in-textareas – 2011-05-26 14:56:59

+0

可能的重複[使用tab在textarea中縮進](http://stackoverflow.com/questions/6637341/ use-tab-to-indent-in-textarea) – Pere 2017-01-02 16:18:10

回答

122

您可以:http://jsfiddle.net/sdDVf/8/


$("textarea").keydown(function(e) { 
    if(e.keyCode === 9) { // tab was pressed 
     // get caret position/selection 
     var start = this.selectionStart; 
     var end = this.selectionEnd; 

     var $this = $(this); 
     var value = $this.val(); 

     // set textarea value to: text before caret + tab + text after caret 
     $this.val(value.substring(0, start) 
        + "\t" 
        + value.substring(end)); 

     // put caret at right position again (add one for the tab) 
     this.selectionStart = this.selectionEnd = start + 1; 

     // prevent the focus lose 
     e.preventDefault(); 
    } 
}); 
+1

非常感謝! – sergzach 2011-05-26 14:59:06

+2

+1 preventDefault是爲了什麼? – VirtualTroll 2011-05-26 14:59:43

+1

@Amine:防止瀏覽器的默認選項卡功能。我現在看到它沒有必要。我將對此進行搜索。編輯:'返回false'似乎包括'preventDefault':http://stackoverflow.com/questions/1357118/javascript-event-preventdefault-vs-return-false。 – pimvdb 2011-05-26 15:01:25

27

這裏是pimvdb的回答修改後的版本,這並不需要的JQuery:

document.querySelector("textarea").addEventListener('keydown',function(e) { 
    if(e.keyCode === 9) { // tab was pressed 
     // get caret position/selection 
     var start = this.selectionStart; 
     var end = this.selectionEnd; 

     var target = e.target; 
     var value = target.value; 

     // set textarea value to: text before caret + tab + text after caret 
     target.value = value.substring(0, start) 
        + "\t" 
        + value.substring(end); 

     // put caret at right position again (add one for the tab) 
     this.selectionStart = this.selectionEnd = start + 1; 

     // prevent the focus lose 
     e.preventDefault(); 
    } 
},false); 

我測試了它在Firefox 21.0和Chrome 27,不知道它是否工作在任何地方其他。

+1

要將此應用於所有textarea,請使用querySelectorAll,枚舉返回的列表,並將事件偵聽器添加到每個元素。 – 2014-09-17 20:02:51

+0

要使這種方法奏效,您需要將__eventListener__附加到**個別** DOM元素。要做到這一點:1)獲取所有元素'document.querySelectorAll(「textarea」)'2)通過數組循環來將事件偵聽器附加到每個元素。然後它應該工作 – Amjad 2018-02-20 11:48:01

11

好神,所有以前的答案都沒有提供一般體面的(即程序員)選項卡控件。

也就是說,打在行將縮進這些行的選擇TAB,並SHIFTTAB將取消縮進他們。

_edited(2016年11月):keyCode替換爲charCode ||鍵代碼,每KeyboardEvent.charCode - Web APIs | MDN

(function($) { 
 
    $.fn.enableSmartTab = function() { 
 
    var $this; 
 
    $this = $(this); 
 
    $this.keydown(function(e) { 
 
     var after, before, end, lastNewLine, changeLength, re, replace, selection, start, val; 
 
     if ((e.charCode === 9 || e.keyCode === 9) && !e.altKey && !e.ctrlKey && !e.metaKey) { 
 
     e.preventDefault(); 
 
     start = this.selectionStart; 
 
     end = this.selectionEnd; 
 
     val = $this.val(); 
 
     before = val.substring(0, start); 
 
     after = val.substring(end); 
 
     replace = true; 
 
     if (start !== end) { 
 
      selection = val.substring(start, end); 
 
      if (~selection.indexOf('\n')) { 
 
      replace = false; 
 
      changeLength = 0; 
 
      lastNewLine = before.lastIndexOf('\n'); 
 
      if (!~lastNewLine) { 
 
       selection = before + selection; 
 
       changeLength = before.length; 
 
       before = ''; 
 
      } else { 
 
       selection = before.substring(lastNewLine) + selection; 
 
       changeLength = before.length - lastNewLine; 
 
       before = before.substring(0, lastNewLine); 
 
      } 
 
      if (e.shiftKey) { 
 
       re = /(\n|^)(\t|[ ]{1,8})/g; 
 
       if (selection.match(re)) { 
 
       start--; 
 
       changeLength--; 
 
       } 
 
       selection = selection.replace(re, '$1'); 
 
      } else { 
 
       selection = selection.replace(/(\n|^)/g, '$1\t'); 
 
       start++; 
 
       changeLength++; 
 
      } 
 
      $this.val(before + selection + after); 
 
      this.selectionStart = start; 
 
      this.selectionEnd = start + selection.length - changeLength; 
 
      } 
 
     } 
 
     if (replace && !e.shiftKey) { 
 
      $this.val(before + '\t' + after); 
 
      this.selectionStart = this.selectionEnd = start + 1; 
 
     } 
 
     } 
 
    }); 
 
    }; 
 
})(jQuery); 
 

 
$(function() { 
 
    $("textarea").enableSmartTab(); 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<textarea rows="10" cols="80"> 
 
/* Just some code to edit with our new superTab */ 
 
(function($) { 
 
    $.fn.enableSmartTab = function() { 
 
     $this = $(this); 
 
     $this.keydown(function(e) { 
 
      if ((e.charCode === 9 || e.keyCode === 9) && !e.metaKey && !e.ctrlKey && !e.altKey) { 
 
       e.preventDefault(); 
 
      } 
 
     } 
 
    } 
 
} 
 
</textarea>

+1

我剛剛寫[我的代碼](https://github.com/wlzla000/enableTabIndentation/blob/master/enableTabIndentation.js)來實現此功能。 **在不能使用jQuery **的情況下,請考慮使用我的代碼。 – 2016-11-19 09:18:00

+1

@ K._不錯的代碼,但我會建議通過babel或谷歌關閉運行它來刪除ES6組件。 ES6很棒,但是有太多的用戶沒有使用ES6兼容的瀏覽器。另外'event.key'在瀏覽器中不是(IIRC)一致的,在不同的瀏覽器中鍵可能被稱爲不同的東西,並且Safari根本不支持該屬性。 這是**其他**原因人們使用jQuery,雖然經常被遺忘,但它是爲了保證跨瀏覽器的兼容性。我不是在批評你的努力,我認爲你做了很棒的工作,但是如果你看看我寫的代碼,它必須跨瀏覽器 – Orwellophile 2016-11-20 02:58:38

+0

@ K._,實際上並沒有太多的jQuery。排除監聽器的添加,jQuery的唯一實際使用是'$ .fn.val'。處理程序本身已經使用本地事件屬性。 – Orwellophile 2016-11-20 03:15:05

4

在香草(默認)JS這將是:

var textareas = document.getElementsByTagName('textarea'); 
if (textareas) { 
    for (var i = 0; i < textareas.length; i++) { 
     textareas[i].addEventListener('keydown', function (e) { 
      if (e.which != 9) return; 

      var start   = this.selectionStart; 
      var end    = this.selectionEnd; 

      this.value   = this.value.substr(0, start) + "\t" + this.value.substr(end); 
      this.selectionStart = this.selectionEnd = start + 1; 

      e.preventDefault(); 
      return false; 
     }); 
    } 
} 
+0

謝謝,夥計。 人們並沒有意識到並非所有人都在使用jQuery。 – nbrogi 2017-08-25 21:40:16

0

實測值這一點的同時搜索谷歌。我做了一個非常短的一個還可以縮進和反向文本縮進選擇:

jQ(document).on('keydown', 'textarea', function(e) { 
     if (e.keyCode !== 9) return; 
     var Z; 
     var S = this.selectionStart; 
     var E = Z = this.selectionEnd; 
     var A = this.value.slice(S, E); 
     A = A.split('\n'); 
     if (!e.shiftKey) 
      for (var x in A) { 
       A[x] = '\t' + A[x]; 
       Z++; 
      } 
     else 
      for (var x in A) { 
       if (A[x][0] == '\t') 
        A[x] = A[x].substr(1); 
       Z--; 
      } 
     A = A.join('\n'); 
     this.value = this.value.slice(0, S) + A + this.value.slice(E); 
     this.selectionStart = S != E ? S : Z;; 
     this.selectionEnd = Z; 
     e.preventDefault(); 
    }); 
0

啓用跳格內(多)textarea元素

糾正@alexwells回答,使現場演示

var textAreaArray = document.querySelectorAll("textarea"); 
 
    for (var i = textAreaArray.length-1; i >=0;i--){ 
 
     textAreaArray[i].addEventListener('keydown',function(e) { 
 
      if(e.keyCode === 9) { // tab was pressed 
 
       // get caret position/selection 
 
       var start = this.selectionStart; 
 
       var end = this.selectionEnd; 
 

 
       var target = e.target; 
 
       var value = target.value; 
 

 
       // set textarea value to: text before caret + tab + text after caret 
 
       target.value = value.substring(0, start) 
 
          + "\t" 
 
          + value.substring(end); 
 

 
       // put caret at right position again (add one for the tab) 
 
       this.selectionStart = this.selectionEnd = start + 1; 
 

 
       // prevent the focus lose 
 
       e.preventDefault(); 
 
      } 
 
     },false); 
 
    }
<textarea rows="10" cols="80"></textarea> 
 
    <textarea rows="10" cols="80"></textarea>

+0

使用香草javascript在textarea元素內啓用製表符 – Amjad 2018-02-20 14:57:09

相關問題