Reputation: 967
I am attempting to move span
tags and their contents to the left or right by one position when the cursor is inside of them and Ctrl Right or Control Left is pressed. The span tags are inside of a contenteditable
paragraph. I am not even having any luck getting a test message to log to the console to indicate that the cursor is even inside of the span tag. Here is the 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();
});
Sample 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>
Upvotes: 0
Views: 403
Reputation: 3331
Your code fails because (unfortunately) span
elements do not fire keydown
/keyup
/keypress
events - no, not even when they are part of a contenteditable
.
Therefore, you need to catch the event on the contenteditable
element itself.
Handling TextNode
s in jQuery is as complicated (or more complicated) as doing it in native JS
Relevant properties & methods of the standard Node
class:
Node.prototype.data
- content of the (text) nodeNode.prototype.length
- length of the contentText.prototype.insertContent(position, content)
- insert textText.prototype.appendConent(content)
- append textText.prototype.deleteContent(position, length)
- delete part of the contentThat being said, this should provide the Ctrl+left/right-moving you expect: (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);
}
}
Note: Only works on IE9+, the selection API on IE8- is non-standard.
Upvotes: 2