模拟JS退格键

6
我希望创建一个自定义的“退格”按钮,其逻辑与键盘上的“退格”按钮相同。我使用以下代码:

function backSpace()
{
    var e = jQuery.Event("keyup");
    e.which = 8; // # Some key code value
    e.keyCode = 8;
    $("mainDiv").trigger(e);
}
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="styles.css" type="text/css" media="screen" />
        <script src="formulas.js"></script>
        <script src="http://code.jquery.com/jquery-1.11.3.js"></script>
        <meta name="viewport" content="width=device-width initial-scale=1.0 maximum-scale=1.0 user-scalable=no"/>
    </head>

    <button onclick="backSpace()">backSpace</button>
    <body id="main" spellcheck="false">
        <div id = "mainDiv" contenteditable="true"></div>
    </body>
</html>

但它并没有起作用。我不明白我做错了什么。我为这个问题花费了很多时间,但是我还没有解决它。请帮帮我。


2
当点击此按钮时,您希望它执行什么操作? - jacksbox
@jackbox 我想要与键盘退格按钮相同的逻辑。 - Nikita Ermolenko
"mainDiv" 不是任何标签名称,并且您没有使用任何选择器符号(.#等)与之配合。这可能是您的问题所在。 - Ashraf Purno
@CosLu 我想删除字母。 - Nikita Ermolenko
1
使用jQuery时要小心。要引用id,应该使用“#id”而不是仅仅的“id”。 - nowhere
显示剩余5条评论
7个回答

5

这段代码对我来说运行正常。 您可以在插入符号位置逐个清除字母,或者清除所选内容。

var textbox = document.getElementById('textbox');

function backspace()
{
var ss = textbox.selectionStart;
var se = textbox.selectionEnd;
var ln  = textbox.value.length;

var textbefore = textbox.value.substring( 0, ss );    //text in front of selected text
var textselected = textbox.value.substring( ss, se ); //selected text
var textafter = textbox.value.substring( se, ln );    //text following selected text

if(ss==se) // if no text is selected
{
textbox.value = textbox.value.substring(0, ss-1 ) + textbox.value.substring(se, ln );
textbox.focus();
textbox.selectionStart = ss-1;
textbox.selectionEnd = ss-1;
}
else // if some text is selected
{
textbox.value = textbefore + textafter ;
textbox.focus();
textbox.selectionStart = ss;
textbox.selectionEnd = ss;
}

}
<textarea id="textbox"></textarea>
<div class="button" onclick="backspace()" > BACKSPACE_BUTTON </div>

希望对您有所帮助!

3

输入解决方案.

backSpace = function ()
{
    var str= $("#text_input").val();
    var position = document.getElementById('text_input').selectionStart-1;

    str = str.substr(0, position) + '' + str.substr(position + 1);
    $("#text_input").val(str);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="backSpace()">backSpace</button>
<input type='text' id='text_input' value='123456789'/>

希望这可以帮助到您。

1
谢谢!但是我需要div标签的解决方案 :( - Nikita Ermolenko

3
除了@CosLu的回答之外,还有以下补充:

这里也有JSBin

function backSpace() {
  p = document.getElementById("mainDiv");
  c = getCaretPosition(p);
  console.log(getCaretPosition(p));
  str = $("#mainDiv").html();
  if (c > 0 && c <= str.length) {
    $("#mainDiv").focus().html(str.substring(0, c - 1) + str.substring(c, str.length));

    p.focus();
    var textNode = p.firstChild;
    var caret = c - 1; 
    var range = document.createRange();
    range.setStart(textNode, caret);
    range.setEnd(textNode, caret);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
  }
}

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

function getCaretPosition(editableDiv) {
  var caretPos = 0,
    sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      if (range.commonAncestorContainer.parentNode == editableDiv) {
        caretPos = range.endOffset;
      }
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    if (range.parentElement() == editableDiv) {
      var tempEl = document.createElement("span");
      editableDiv.insertBefore(tempEl, editableDiv.firstChild);
      var tempRange = range.duplicate();
      tempRange.moveToElementText(tempEl);
      tempRange.setEndPoint("EndToEnd", range);
      caretPos = tempRange.text.length;
    }
  }
  return caretPos;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script src="http://code.jquery.com/jquery-1.11.3.js"></script>
</head>

<body>
  <button onclick="backSpace()">backSpace</button>
  <div id="mainDiv" contenteditable="true">aahahtext</div>
</body>

</html>


再次感谢!但是我遇到了问题,当插入特殊符号时。当我插入“sigma”然后点击“backSpace”按钮时,我看到错误的逻辑(函数删除错误的字符)。为了正确的逻辑,我必须手动设置插入符位置,然后点击“backSpace”。请参见附件。http://jsbin.com/kefutuvuci/edit?html,js,output - Nikita Ermolenko
这是因为当您插入sigma时,backspace()中的插入符位置会重置为1。 - shyammakwana.me
@shyammakwana.me:虽然它适用于可编辑内容,但对于例如<b>标签无效 :( - Shashank Vivek

1
这将是一个解决方案:

http://jsfiddle.net/nezkbws7/2/

function backSpace()
{
  var txt = $("#mainDiv").text();
  txt = txt.substr(0,txt.length-1)
  $("#mainDiv").text(txt);
}

我手动创建了退格功能,而不是复制事件。


1
需要仅从光标位置删除左侧元素。 - Nikita Ermolenko

1

只需更新你的 js 代码就可以使它工作。我在这里找到了一个查找光标位置的代码片段:获取 contentEditable div 中光标的位置

请注意,以下代码假定:

  • 可编辑区域内始终只有一个文本节点,没有其他节点

  • 可编辑区域没有设置 CSS white-space 属性为 pre

function backSpace()
{
    p = document.getElementById ("mainDiv");
    c = getCaretPosition(p);
    str= $("#mainDiv").html();
    if(c>0 && c<=str.length){
      $("#mainDiv").html(str.substring(0,c-1)+ str.substring(c,str.length));
    }
}

function getCaretPosition(editableDiv) {
  var caretPos = 0,
sel, range;
  if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
  range = sel.getRangeAt(0);
  if (range.commonAncestorContainer.parentNode == editableDiv) {
    caretPos = range.endOffset;
  }
}
  } else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
if (range.parentElement() == editableDiv) {
  var tempEl = document.createElement("span");
  editableDiv.insertBefore(tempEl, editableDiv.firstChild);
  var tempRange = range.duplicate();
  tempRange.moveToElementText(tempEl);
  tempRange.setEndPoint("EndToEnd", range);
  caretPos = tempRange.text.length;
}
  }
  return caretPos;
}
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="styles.css" type="text/css" media="screen" />
        <script src="formulas.js"></script>
        <script src="http://code.jquery.com/jquery-1.11.3.js"></script>
        <meta name="viewport" content="width=device-width initial-scale=1.0 maximum-scale=1.0 user-scalable=no"/>
    </head>

    
    <body id="main" spellcheck="false">
        <button onclick="backSpace()">backSpace</button>
        <div id = "mainDiv" contenteditable="true">aahahtext</div>
    </body>
</html>


光标位置怎么办?我的意思是,OP似乎只是提供了一个按钮作为示例。 - A. Wolff
谢谢您的回答,但我需要删除光标位置右侧的字符,而不是 div 标签中的最后一个字符。 - Nikita Ermolenko
是的,我的错。现在好了吗? - nowhere
@CosLu 对不起,我错了。我想从光标位置删除一个左侧元素(而不是右侧)。对我的英语表示歉意。 - Nikita Ermolenko
1
@NikitaErmolenko 是的,应该使用c<=str.length而不是c<str.length。恐怕你需要另一段代码来重新设置插入符号的位置:(在这里检查https://dev59.com/CXE85IYBdhLWcg3wPBF8#2948573) - nowhere
显示剩余6条评论

1

使用document.execCommand('delete')发送一个删除信号:

document.querySelector('#whatever-element').focus(); // focus if needed
document.execCommand('delete');

0
$("#sup").on("keydown", function (e) {
if (e.which == 8 || e.keyCode === 8) {
selection = window.getSelection();
selection.modify("extend", "backward", "character");
selection.deleteFromDocument();
  }
});

光标需要存在于文本区域内才能正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接