astx123
astx123

Reputation: 85

Stop unwanted scrolling when moving caret with arrow keys in contenteditable div

Keydown works perfectly when I select document, *, body or any particular element.

But when I add .not('.some-class'), keydown works like this .not() doesn't even exist. Maybe because of the way keydown affects children elements, but I'm not sure:

$('*').not('.some-class').on('keydown',function(e){ 
    var key = e.charCode || e.keyCode;
    if(key == 33 || key == 34 || key == 35 || key == 36 || key == 37 || key == 38 || key == 39 || key == 40 ) {
        e.preventDefault();
    } else {}
});

How to disable these keys for the whole document except for 1 child class?

edit: http://jsfiddle.net/umL139xw/2/

How to stop this unwanted scrolling while keeping ability to move caret with arrows?

edit2: complete solution thanks to Jason P and Kaiido

http://jsfiddle.net/umL139xw/5/

Upvotes: 1

Views: 1368

Answers (2)

Kaiido
Kaiido

Reputation: 136796

You could use the cursor's position detector from this answer and then preventDefault() only when you're at the end.

$(document).on('keydown',function(e){
    console.log(this, e.target);
    var key = e.charCode || e.keyCode;
    if(key == 16 || key == 32 || key == 33 || key == 34 || key == 35 || key == 36 || key == 37 || key == 38 || key == 39 || key == 40 ) {
        e.preventDefault();
    } else {}
});
$('.b').on('keydown', function(e) {
  e.stopPropagation(); 
  var key = e.charCode || e.keyCode;
   //Above part comes from https://stackoverflow.com/questions/7451468/contenteditable-div-how-can-i-determine-if-the-cursor-is-at-the-start-or-end-o/7478420#7478420
    range = window.getSelection().getRangeAt(0)
    post_range = document.createRange();
    post_range.selectNodeContents(this);
    post_range.setStart(range.endContainer, range.endOffset);
    next_text = post_range.cloneContents();

    if( next_text.textContent.length === 0 && key == 39 ){
        e.preventDefault();
    }
});

Working fiddle

Upvotes: 1

Jason P
Jason P

Reputation: 27012

Events bubble (well, a good number of them do). That means they fire on the target of the event, then on every element up the DOM tree, so even if you don't bind the handler to .some-class, it will fire for that element's ancestors. Also, binding an event handler to * is generally not a good idea. Maybe something like this would work for you?

http://jsfiddle.net/j3wqpdow/

$(document).on('keydown',function(e){ 
    console.log(this, e.target);
});

$('.some-class').on('keydown', function(e) {
   e.stopPropagation(); 
});

Upvotes: 1

Related Questions