HTML Texeare使用left,right,down,up,home和end虚拟按钮控制插入符号

时间:2016-04-07 21:12:42

标签: javascript jquery html css keyboard

我正在尝试将导航控制按钮放在HTML textarea框上。到目前为止,Tab工作正常。 Backapace工作得很好。 End,Home和Space按钮也是如此。每次点击按钮时,LEFT和RIGHT按钮都会跳两个字符。在我决定发布问题之前,我已经敲了两天试图找到解决方案。这是JSFiddle的链接:[](https://jsfiddle.net/ChemistryOfMath/uuchyfg0/8/https://jsfiddle.net/ChemistryOfMath/uuchyfg0/8/
HTML代码如下:

<html>

<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.2.js"></script>
  <title>Test Caret</title>
  <style type="text/css">
    #txtarea {
      display: block;
      padding: 5px;
      width: 200px;
      height: 100px;
      font: 1em, Verdana, Sans-Serif;
      background: #fff;
      border: 1px solid #486787;
      margin-left: 40px;
    }
    #kbdFrame {
      float: left;
    }
    ul li {
      white-space: nowrap;
      overflow: hidden;
      list-style-type: none;
      display: inline-block;
      border: 1px solid #111db3;
      margin: 2px;
      color: #000;
      border-radius: 5px;
      box-sizing: border-box;
      text-align: center;
      overflow: hidden;
      cursor: pointer;
      font-family: arial, sans-serif;
      font-size: 15px;
      width: 45px;
      height: 45px;
      line-height: 45px;
    }
    #left,
    #up,
    #right,
    #down {
      color: red;
    }
  </style>
  <script type="text/javascript">
    $(document).ready(function() {
      var e = document.getElementById('txtarea');
      e.focus();
      var character;
      /**===FUNCTIONs=======================*/
      BACKSPACE = function() {
        character = "";
        var pos = e.selectionStart;
        if (e.selectionStart == e.selectionEnd) {
          e.value = e.value.substr(0, e.selectionStart - 1) + character + e.value.substr(e.selectionEnd, e.value.length);
          e.selectionStart = pos - 1;
          e.selectionEnd = pos - 1;
        } else { // replace selected text
          e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
          e.selectionStart = pos;
          e.selectionEnd = pos;
        }
      }
      TAB = function() {
        var pos = e.selectionEnd
        character = "\t"
        e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        e.selectionStart = pos + 1;
        e.selectionEnd = pos + 1;
      }
      LEFT = function() {
        //character = ""
        e.selectionStart = e.selectionEnd -= 1;
      }
      RIGHT = function() {
        //character = ""
        e.selectionStart = e.selectionEnd += 1;
      }
      DOWN = function() {
        //character = ""
        //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        var pos = e.selectionEnd,
          prevLine = e.value.lastIndexOf('\n', pos),
          nextLine = e.value.indexOf('\n', pos + 1);
        if (nextLine === -1) return;
        pos = pos - prevLine;
        e.selectionStart = e.selectionEnd = nextLine + pos;
      }
      UP = function() {
        //character = ""
        //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        var pos = e.selectionEnd,
          prevLine = e.value.lastIndexOf('\n', pos),
          TwoBLine = e.value.lastIndexOf('\n', prevLine - 1);
        if (prevLine === -1) return;
        pos = pos - prevLine;
        e.selectionStart = e.selectionEnd = TwoBLine + pos;
      }
      HOME = function() {
        //character = ""
        //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        e.selectionEnd =
          e.selectionStart =
          e.value.lastIndexOf(
            '\n',
            e.selectionEnd - 1
          ) + 1;
      }
      END = function() {
        //character = ""
        //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        var pos = e.selectionEnd,
          i = e.value.indexOf('\n', pos);
        if (i === -1) i = e.value.length;
        e.selectionStart = e.selectionEnd = i;
      }
      SPACE = function() {
          var x = e.selectionStart
          character = " "
          character = e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
          e.selectionStart = pos + 1;
          e.selectionEnd = pos + 1;
        }
        /**===Buttons=======================*/
      $(".keyboard").click(function(evt) {
        $("#txtarea").focus();
        var mykeyID = evt.target.id;
        var character = $(evt.target).text();
        switch (mykeyID) {
          case "tab":
            //$("#txtarea").focus();
            TAB();
            break;
          case "space":
            SPACE();
            break;
          case "bkSp":
            BACKSPACE();
            break;
          case "left":
            LEFT();
            //$("#txtarea").focus();
            break;
          case "right":
            RIGHT();
            //$("#txtarea").focus();
            break;
          case "down":
            DOWN();
            //$("#txtarea").focus();
            break;
          case "up":
            UP();
            //$("#txtarea").focus();
            break;
          case "home":
            HOME();
            //$("#txtarea").focus();
            break;
          case "end":
            END();
            //$("#txtarea").focus();
            break;
          default:
            character = e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
            //e.selectionStart = 0;
            //e.selectionEnd = 0;
            $("#txtarea").val(character);
            break;
        }
      });
    });
  </script>
</head>

<body>
  <textarea type="text" name="txtarea" id="txtarea">Testing the right and left buttons. Please help.</textarea>
  <div class="" id="kbdFrame">
    <ul class="keyboard" id="">
      <ul id="rOne">
        <li class="key" id="tab">Tab</li>
        <li class="key" id="up">Up</li>
        <li class="key" id="bkSp">&larr;</li>
      </ul>
      <ul class="keyboard" id="rSix">
        <li class="key" id="left">Left</li>
        <li class="key" id="home">Home</li>
        <li class="key" id="right">Right</li>
      </ul>
      <ul class="keyboard kbdR7" id="rSeven">
        <li class="key" id="space">Space</li>
        <li class="key" id="down">Down</li>
        <li class="key" id="end">End</li>
      </ul>
    </ul>
  </div>
</body>

</html>
          

2 个答案:

答案 0 :(得分:2)

(".keyboard").click()被触发2次。为什么?因为这些按钮位于ulkeyboard类,其本身位于ul类,keyboard类。

<ul class="keyboard" id="">

  [...]

  <ul class="keyboard" id="rSix">
    <li class="key" id="left">Left</li>
    <li class="key" id="home">Home</li>
    <li class="key" id="right">Right</li>
  </ul>

  [...]

</ul>

因此触发器执行2次。删除第一个键盘类:JSFiddle

答案 1 :(得分:0)

您的问题是事件委托。有关详细信息,请查看event-delegation

此问题取决于事件处理:

$(".keyboard").click(function(evt) {

和html来源:

<ul class="keyboard" id="">

在另一个里面:

<ul class="keyboard" id="rSix">

这意味着: 每当你点击“.keyboard”时,就会出现以下处理程序:

$(".keyboard").click(function(evt) {

接收两个事件,一个针对以下两个元素中的每一个(按顺序):

<ul class="keyboard" id="rSix">

并且在此之后立即:

<ul class="keyboard" id="">

避免此问题的可能解决方案是停止调用以下代码行的事件:

evt.stopPropagation();

作为点击处理程序的第一行。

另一种解决方案是使用不同的事件委派:

$(".keyboard li").click(function(evt) {

在以下代码段中输入正确的代码:

$(function () {
  var e = document.getElementById('txtarea');
  e.focus();
  var character;
  /**===FUNCTIONs=======================*/
  BACKSPACE = function() {
    character = "";
    var pos = e.selectionStart;
    if (e.selectionStart == e.selectionEnd) {
      e.value = e.value.substr(0, e.selectionStart - 1) + character + e.value.substr(e.selectionEnd, e.value.length);
      e.selectionStart = pos - 1;
      e.selectionEnd = pos - 1;
    } else { // replace selected text
      e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
      e.selectionStart = pos;
      e.selectionEnd = pos;
    }
  }
  TAB = function() {
    var pos = e.selectionEnd
    character = "\t"
    e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    e.selectionStart = pos + 1;
    e.selectionEnd = pos + 1;
  }
  LEFT = function() {
    //character = ""
    e.selectionStart = e.selectionEnd -= 1;
  }
  RIGHT = function() {
    //character = ""
    e.selectionStart = e.selectionEnd += 1;
  }
  DOWN = function() {
    //character = ""
    //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    var pos = e.selectionEnd,
        prevLine = e.value.lastIndexOf('\n', pos),
        nextLine = e.value.indexOf('\n', pos + 1);
    if (nextLine === -1) return;
    pos = pos - prevLine;
    e.selectionStart = e.selectionEnd = nextLine + pos;
  }
  UP = function() {
    //character = ""
    //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    var pos = e.selectionEnd,
        prevLine = e.value.lastIndexOf('\n', pos),
        TwoBLine = e.value.lastIndexOf('\n', prevLine - 1);
    if (prevLine === -1) return;
    pos = pos - prevLine;
    e.selectionStart = e.selectionEnd = TwoBLine + pos;
  }
  HOME = function() {
    //character = ""
    //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    e.selectionEnd =
      e.selectionStart =
      e.value.lastIndexOf(
      '\n',
      e.selectionEnd - 1
    ) + 1;
  }
  END = function() {
    //character = ""
    //e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    var pos = e.selectionEnd,
        i = e.value.indexOf('\n', pos);
    if (i === -1) i = e.value.length;
    e.selectionStart = e.selectionEnd = i;
  }
  SPACE = function() {
    var x = e.selectionStart
    character = " "
    character = e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
    e.selectionStart = pos + 1;
    e.selectionEnd = pos + 1;
  }
  /**===Buttons=======================*/
  $(".keyboard").click(function(evt) {

    // FIX
    evt.stopPropagation();


    $("#txtarea").focus();
    var mykeyID = evt.target.id;
    var character = $(evt.target).text();
    switch (mykeyID) {
      case "tab":
        //$("#txtarea").focus();
        TAB();
        break;
      case "space":
        SPACE();
        break;
      case "bkSp":
        BACKSPACE();
        break;
      case "left":
        LEFT();
        //$("#txtarea").focus();
        break;
      case "right":
        RIGHT();
        //$("#txtarea").focus();
        break;
      case "down":
        DOWN();
        //$("#txtarea").focus();
        break;
      case "up":
        UP();
        //$("#txtarea").focus();
        break;
      case "home":
        HOME();
        //$("#txtarea").focus();
        break;
      case "end":
        END();
        //$("#txtarea").focus();
        break;
      default:
        character = e.value = e.value.substr(0, e.selectionStart) + character + e.value.substr(e.selectionEnd, e.value.length);
        //e.selectionStart = 0;
        //e.selectionEnd = 0;
        $("#txtarea").val(character);
        break;
    }
  });
});
#txtarea {
  display: block;
  padding: 5px;
  width: 200px;
  height: 100px;
  font: 1em, Verdana, Sans-Serif;
  background: #fff;
  border: 1px solid #486787;
  margin-left: 40px;
}

#kbdFrame {
  float: left;
}

ul li {
  white-space: nowrap;
  overflow: hidden;
  list-style-type: none;
  display: inline-block;
  border: 1px solid #111db3;
  margin: 2px;
  color: #000;
  border-radius: 5px;
  box-sizing: border-box;
  text-align: center;
  overflow: hidden;
  cursor: pointer;
  font-family: arial, sans-serif;
  font-size: 15px;
  width: 45px;
  height: 45px;
  line-height: 45px;
}

#left,
#up,
#right,
#down {
  color: red;
}
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>

<textarea type="text" name="txtarea" id="txtarea">Tab works fine. The backapace works fine. So do the end, home and space buttons. the LEFT and RIGHT buttons keep jumping TWO characters. Please help.</textarea>
<div class="" id="kbdFrame">
    <ul class="keyboard" id="">
        <ul id="rOne">
            <li class="key" id="tab">Tab</li>
            <li class="key" id="up">Up</li>
            <li class="key" id="bkSp">&larr;</li>
        </ul>
        <ul class="keyboard" id="rSix">
            <li class="key" id="left">Left</li>
            <li class="key" id="home">Home</li>
            <li class="key" id="right">Right</li>
        </ul>
        <ul class="keyboard kbdR7" id="rSeven">
            <li class="key" id="space">Space</li>
            <li class="key" id="down">Down</li>
            <li class="key" id="end">End</li>
        </ul>
    </ul>
</div>