Javascript 使用箭头键移动整个跨度

标签 javascript jquery html

当光标位于标签内部并按下 Ctrl Right 或 Control Left 时,我尝试将 span 标签及其内容向左或向右移动一个位置。 span 标签位于 contenteditable 段落内。我什至没有运气得到一条测试消息来记录到控制台以表明光标甚至位于 span 标记内部。这是 fiddle :

https://jsfiddle.net/scooke/5tp5oe7z/

Javascript/Jquery

$(document).on('keyup','.move',function(e){ 
  if (e.ctrlKey && (e.which === 37 || e.which === 39)){
    //move character at right or left of span to the other side
    //to simulate the whole span moved  
  }    
  e.stopPropagation();   
 });

示例 Html

<p class="parent" contenteditable="true">Bacon ipsum dolor amet jowl chicken    pork loin <span class="move">[move text]</span>tail. Short ribs meatball
<br>bresaola beef boudin hamburger, cow rump swine. Pork belly ribeye leberkas venison
<br>ground <span class="move">[move text]</span>round</p>

最佳答案

  1. 您的代码失败,因为(不幸的是)span 元素未触发 keydown/keyup/keypress 事件 - 不,即使它们是 contenteditable 的一部分。

    因此,您需要捕获 contenteditable 元素本身的事件。

  2. 在 jQuery 中处理 TextNode 与在原生 JS 中处理一样复杂(或更复杂)

    标准Node类的相关属性和方法:

    • Node.prototype.data - (文本)节点的内容
    • Node.prototype.length - 内容的长度
    • Text.prototype.insertContent(position, content) - 插入文本
    • Text.prototype.appendConent(content) - 附加文本
    • Text.prototype.deleteContent(position, length) - 删除部分内容

话虽这么说,这应该提供您期望的 Ctrl+左/右移动:(JSFiddle)

$('p[contenteditable]').on('keydown', function (e) { 
    // Only handle event if ctrl+left / ctrl+right
    if (!e.ctrlKey || (e.which != 37 && e.which != 39)) return;
    // and selection is in a span.move
    var sel = document.getSelection();
    var node = sel.anchorNode;
    if (!node || node != sel.focusNode) return;
    // Text "[move text]" is in selection, get <span> parent
    if (node.nodeType == Node.TEXT_NODE) {
        node = node.parentNode;
    }
    if (!node || node.nodeName != 'SPAN' || node.className != 'move') return;

    // Do the magic
    moveSpan(node, e.which == 37); // 37: left, 39: right
    e.preventDefault();
    e.stopPropagation();
});

function moveSpan (span, toLeft) {
    var left = span.previousSibling;
    var right = span.nextSibling;

    if (!left || left.nodeType != Node.TEXT_NODE || !right || right.nodeType != Node.TEXT_NODE) return;
    if (toLeft && !left.length) return;
    if (!toLeft && !right.length) return;

    if (toLeft) {
        right.insertData(0, left.data[left.length - 1]);
        left.deleteData(left.length - 1, 1);
    } else {
        left.appendData(right.data[0]);
        right.deleteData(0, 1);
    }
}
<小时/>

注意:仅适用于 IE9+,IE8- 上的选择 API 是非标准的。

关于Javascript 使用箭头键移动整个跨度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33879103/

相关文章:

javascript - 如何使两行的高度为100%?

javascript - 当用户禁用 cookie 时跟踪用户?

javascript - axios 获取参数数组

javascript - 垄断选择随机卡和流行阵列

html - 为什么 `position:absolute;` 销毁 ` vertical-align:middle` ?

html - 有没有办法在所有子页面中显示一些 DIV?

html - 如何在没有水平滚动条的情况下制作 bootstrap 3 流体布局

javascript - 何时/为何使用 map/reduce over for 循环

jquery - 如何使用 jquery 操作 html 列表

javascript - 什么是 .previous 方法?它是 jQuery 还是 core JS 还是其他库?