【问题标题】:How to move cursor up, down, left, right in textarea on button press using jQuery?如何使用jQuery在按钮按下时在textarea中向上、向下、向左、向右移动光标?
【发布时间】:2020-03-07 00:05:02
【问题描述】:

如何使用 jQuery 制作按钮在文本区域中向上、向下、向左或向右移动光标?

$(document).ready(function() {
  var clpBrd;
  $("textarea")[0].focus(); /*To show to cursor at the end of text*/
  
  $("#cpBtn").click(function(){
    clpBrd = $("txtOutput").text();
    console.log("COPIED: "+clpBrd);
  });
  
  $("#ltBtn").click(function(){
    var txtVal = $("textarea").val();
    var txtLen = txtVal.length;
    $("textarea")[0].focus(txtLen - 1);
  });
  
  $("#rtBtn").click(function(){
    var txtVal = $("textarea").val();
    var txtLen = txtVal.length;
    $("textarea")[0].focus(txtLen + 1);
  });
  
  $("#upBtn").click(function(){
    var txtVal = $("textarea").val();
    var txtLen = txtVal.length;
    $("textarea")[0].focus( /*??*/ );
  });
  
  $("#dnBtn").click(function(){
    var txtVal = $("textarea").val();
    var txtLen = txtVal.length;
    $("textarea")[0].focus(/*??*/);
  });
  
  var selPressed = false;
  $("#selBtn").click(function(){
    selPressed = !selPressed;
  });
  
});
* {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh
}

textarea,
#btnWrap button {
  display: flex;
  flex-grow: 1;
}

textarea::selection{
    color:white; background: black
}

#btnWrap {
  height: 50px;
  display: flex;
  flex-direction: row;
}

#btnWrap button {
  align-items: center;
  justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="txtOutput">
  Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</textarea>
<div id="btnWrap">
  <button id="slBtn">Select</button>
  <button id="upBtn">▲</button>
  <button id="ltBtn">◀</button>
  <button id="rtBtn">▶</button>
  <button id="dnBtn">▼</button>
  <button id="ctBtn">Cut</button>
  <button id="psBtn">Paste</button>
  <button id="cpBtn">Copy</button>
</div>

另外,我们如何使用向上/向下按钮选择文本?

如果selPressed 为真,则移动光标将选择文本。否则它只是移动光标。

我认为使用数组进行剪切/复制/粘贴会很困难。

我是否必须使用像 clipboard.js 这样的外部库,或者没有它可以做到这一点吗?

【问题讨论】:

标签: javascript jquery button custom-keyboard textselection


【解决方案1】:

您需要首先获取当前光标位置,就像我在函数 getInputSelection() 中所做的那样

我对在文本区域内移动光标位置进行了一些研究,感谢css tricks,我找到了一种将其移动到文本区域末尾的方法。我根据您的需要调整了此功能。奇迹发生在moveCursor = function(pos)。您可以将所需的光标位置传递给 fct。左右工作完全正常。 上下是棘手的,因为每行中的字符数量会因行而异。

我决定设置 100 个字符的静态值。光标向上或向下移动,但位置不是 100 % 在点上。

我很确定通过一些研究,您可以找到一种计算每行字符数并优化此功能的方法。

$(document).ready(function() {
  var clpBrd;
  $("textarea")[0].focus(); /*To show to cursor at the end of text*/
  
  $("#cpBtn").click(function(){
    clpBrd = $("txtOutput").text();
    console.log("COPIED: "+clpBrd);
  });
  
  $("#ltBtn").click(function(){
     var sel = getInputSelection($("textarea"));
     $("textarea").moveCursor(sel-1);
  });
  
  $("#rtBtn").click(function(){
     var sel = getInputSelection($("textarea"));
     $("textarea").moveCursor(sel+1);
  });
  
  $("#upBtn").click(function(){
     var sel = getInputSelection($("textarea"));
     $("textarea").moveCursor(sel-100);
  });
  
  $("#dnBtn").click(function(){
     var sel = getInputSelection($("textarea"));
     $("textarea").moveCursor(sel+100);
  });
  
  var selPressed = false;
  $("#selBtn").click(function(){
    selPressed = !selPressed;
  });

  
});

jQuery.fn.moveCursor = function(pos) {

  return this.each(function() {
    
    // Cache references
    var $el = $(this),
        el = this;

    // Only focus if input isn't already
    if (!$el.is(":focus")) {
     $el.focus();
    }

    // If this function exists... (IE 9+)
    if (el.setSelectionRange) {

      // Timeout seems to be required for Blink
      setTimeout(function() {
        el.setSelectionRange(pos, pos);
      }, 1);
    
    } else {
      
      // As a fallback, replace the contents with itself
      // Doesn't work in Chrome, but Chrome supports setSelectionRange
      $el.val(pos);
      
    }

    // Scroll to the bottom, in case we're in a tall textarea
    // (Necessary for Firefox and Chrome)
    this.scrollTop = 999999;

  });

};

function getInputSelection(elem){
 if(typeof elem != "undefined"){
  var s=elem[0].selectionStart;
  return s;
 }else{
  return '';
 }
}
* {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh
}

textarea,
#btnWrap button {
  display: flex;
  flex-grow: 1;
}

textarea::selection{
    color:white; background: black
}

#btnWrap {
  height: 50px;
  display: flex;
  flex-direction: row;
}

#btnWrap button {
  align-items: center;
  justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="txtOutput">
  Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</textarea>
<div id="btnWrap">
  <button id="slBtn">Select</button>
  <button id="upBtn">▲</button>
  <button id="ltBtn">◀</button>
  <button id="rtBtn">▶</button>
  <button id="dnBtn">▼</button>
  <button id="ctBtn">Cut</button>
  <button id="psBtn">Paste</button>
  <button id="cpBtn">Copy</button>
</div>

【讨论】:

【解决方案2】:

请参考我的代码,现场演示https://codepen.io/libin-prasanth/pen/dyyjJbG

window.onload = function() {
  var selPressed = false;
  var length = 0;
  var sStart = 0;
  var target = document.getElementById('txtOutput');
  var clipBoard = '';
  // Select click event  
  document.getElementById('selBtn').addEventListener('click', function(e) {
    length = target.selectionStart;
    sStart = target.selectionStart;
    target.focus();
    selPressed = true;
  });

  // right button
  document.getElementById('rtBtn').addEventListener('click', function(e) {
    var textLength = target.value.length;
    if (!selPressed) return;
    length++;
    length = (length <= textLength) ? length : textLength;
    target.focus();
    target.setSelectionRange(sStart, length);
  });
  // left button 
  document.getElementById('ltBtn').addEventListener('click', function(e) {
    var textLength = target.value.length;
    if (!selPressed) return;
    length--;
    length = (length >= 0) ? length : 0;
    target.focus();
    target.setSelectionRange(sStart, length);
  });

  // down button 
  document.getElementById('dnBtn').addEventListener('click', function(e) {
    var textLength = target.value.length;
    if (!selPressed) return;
    target.focus();
    length = length + getCharacterPerLine(target);
    length = (length > textLength) ? textLength : length;
    target.setSelectionRange(sStart, length);
  });

  // up button
  document.getElementById('upBtn').addEventListener('click', function(e) {
    if (!selPressed) return;
    target.focus();
    length = length - getCharacterPerLine(target);
    length = (length <= 0) ? 0 : length;
    target.setSelectionRange(sStart, length);
  });

  // copy event 
  document.getElementById('cpBtn').addEventListener('click', function(e) {
    var text = target.value
    if (!selPressed) return;
    target.focus();
    target.setSelectionRange(sStart, length);
    document.execCommand("copy");
    clipBoard = target.value.substr(sStart, length);
    length = 0;
    sStart = 0;
  });

  // copy cut 
  document.getElementById('ctBtn').addEventListener('click', function(e) {
    var text = target.value
    if (!selPressed) return;
    target.focus();
    target.setSelectionRange(sStart, length);
    clipBoard = target.value.substr(sStart, length);
    document.execCommand("cut");
    length = 0;
    sStart = 0;
  });
  // paste cut 
  document.getElementById('psBtn').addEventListener('click', function(e) {
    if (!selPressed) return;
    insertAtCursor(target, clipBoard);
    length = 0;
    sStart = 0;
  });

  function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
      myField.focus();
      sel = document.selection.createRange();
      sel.text = myValue;
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
      var startPos = myField.selectionStart;
      var endPos = myField.selectionEnd;
      myField.value = myField.value.substring(0, startPos) +
        myValue +
        myField.value.substring(endPos, myField.value.length);
    } else {
      myField.value += myValue;
    }
    myField.focus();
  }

  function getCharacterPerLine(target) {
    var w = target.clientWidth;
    var fSize = window.getComputedStyle(target, null).getPropertyValue('font-size');
    fSize = parseFloat(fSize);
    return (w / fSize) * 2;
  }

}
* {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
}

textarea,
#btnWrap button {
  display: flex;
  flex-grow: 1;
}

textarea::selection {
  color: white;
  background: black;
}

#btnWrap {
  height: 50px;
  display: flex;
  flex-direction: row;
}

#btnWrap button {
  align-items: center;
  justify-content: center;
}
<textarea id="txtOutput">
Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</textarea>
<div id="btnWrap">
  <button id="selBtn">Select</button>
  <button id="upBtn">▲</button>
  <button id="ltBtn">◀</button>
  <button id="rtBtn">▶</button>
  <button id="dnBtn">▼</button>
  <button id="ctBtn">Cut</button>
  <button id="psBtn">Paste</button>
  <button id="cpBtn">Copy</button>
</div>

【讨论】:

  • +1 似乎无法从光标的当前位置开始选择。每次选择总是从第一个单词开始...
  • 唯一剩下的就是向后选择...即,向左或向上。但到目前为止也没关系。尽管如此... ? 谢谢
猜你喜欢
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多