2015-11-23 63 views
0

當光標在它們的內部並且按下Ctrl右或Control Left時,我試圖將span標籤及其內容向左或向右移動一個位置。 span標籤位於contenteditable段落內。我甚至沒有任何運氣獲得測試消息登錄到控制檯,以指示光標甚至位於span標籤內。這裏是小提琴:Javascript使用箭頭鍵移動整個範圍

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> 
+4

而不是試圖欺騙系統,並避免在鏈接到jsFiddle時在您的問題中發佈代碼的規則,爲什麼不按照您的要求去做?如果jsFiddle永遠消失或無法訪問,您的問題將失去所有價值給未來的訪問者,而您的代碼不在其中 – j08691

+0

這可能會幫助您:http://stackoverflow.com/questions/18771651/detect-keyup-event-of-contenteditable-孩子,他的父母是一個contenteditable迪 – technophobia

+2

我繼續前進,並添加了代碼。我不知道它有所作爲,並不意味着試圖繞過任何規則。 –

回答

2
  1. 你的代碼失敗,因爲(unfortunat ely)span元素不會觸發​​/keyup/keypress事件 - 不,即使它們是contenteditable的一部分。

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

  2. jQuery中處理TextNode s的那樣複雜(或更復雜的)如在天然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是非標準的。

+0

也許是我聽過的最好的解釋之一。而且,一個可以解決另外3個SO帖子試圖做同樣的事情,我無法從中收集任何東西。非常感謝您花時間做到這一點。 –

+0

感謝您的讚賞,激勵我們再次花時間;-) –

+0

除了ctrl箭頭鍵外,是否有任何方法可以爲_l_和_r_鍵工作?這樣移動用戶就可以使用它。僅供參考:括號內將不會有_l_或_r_,因爲括號中包含吉他和絃,因此不需要修飾鍵。再次感謝Leon –