4

I've got an editor in a contentEditable div inside a Windows Store app WebView, and because of quirks in contentEditable handling of PageUp / PageDown I've had to implement my own Page Up / Page Down by trapping the key down event in Javascript and scrolling the page up or down by one screen height.

The trouble is, the cursor does not move when paging, as it should. When the user presses the cursor keys the page scrolls back to where it was before pressing Page Up / Page Down

Here's the code I'm using the catch the key down events

$(window).bind('keydown', function (event) {
    if (event.which == 33) {
        // page up
        event.preventDefault();
        // scroll page to current scroll - window height
        $(document).scrollTop($(document).scrollTop() - document.body.clientHeight);
        // place cursor on page

    }
    else if (event.which == 34) {
        // page down
        event.preventDefault();
        // scroll page to current scroll + window height
        $(document).scrollTop($(document).scrollTop() + document.body.clientHeight);
        // move cursor to bottom 
    }
});

I can set the caret position using this function

// 'editor' is a reference to my contentEditable div

function setCaretPosition(cPos) {
    var charIndex = 0, range = document.createRange();
    range.setStart(editor, 0);
    range.collapse(true);
    var nodeStack = [editor], node, foundStart = false, stop = false;

    while (!stop && (node = nodeStack.pop())) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && cPos >= charIndex && cPos <= nextCharIndex) {
                range.setStart(node, cPos - charIndex);
                foundStart = true;
            }
            if (foundStart && cPos >= charIndex && cPos <= nextCharIndex) {
                range.setEnd(node, cPos - charIndex);
                stop = true;
            }
            charIndex = nextCharIndex;
        } else {
            var i = node.childNodes.length;
            while (i--) {
                nodeStack.push(node.childNodes[i]);
            }
        }
    }
    selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
}

But how do I know where to set it? I can infer the text height from a given position by truncating the text after the cursor and then measuring the height of the div, but I don't know how to do the reverse.

Update

I'm looking for any solution which will allow the Page Up / Page Down keys to function as normal within a contentEditable div, in a WebView, in a Windows Store App.

Definition of "Normal": With the cursor at the top of a long, contentEditable document, pressing Page Down should scroll the div down by the height of that div, and move the cursor the same amount. Page Up should obviously do the opposite, scrolling up the way.

This is apparently not how Page Up / Page Down work on a Mac, but I'm not interested in that as this is a Windows Store app.

NOTE: I am not looking for a function to set the caret position. I already have that.

FYI: I find it is adequate to test in IE11 in desktop mode. This uses the same rendering / javascript engine as the Windows Store WebView.

ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
roryok
  • 9,325
  • 17
  • 71
  • 138
  • Isn't that entirely the correct behaviour? The carat's position has nothing to do with the page's scroll position (and nor should it). For example, if I enter some text in the Your Answer textbox on this page and then hit page-up the page is scrolled up but the carat is still in the textarea. Hitting a cursor key moves the carat and the page duly scrolls down so that its is view. I may be missing something important here but perhaps you could remove focus from the div when paging up/down? – Moob Aug 14 '14 at 09:54
  • @Moob, place the cursor at the start of the text and press pagedown. it will scroll the page and move the cursor to the end of the text within the textarea. It's the same in a giant textarea, or in wordpad. – roryok Aug 14 '14 at 14:43
  • Nope, not for me. It scrolls the page but the cursor remains where I left it. I'm on a Mac, but I've never noticed the behaviour you describe on a PC either. – Moob Aug 14 '14 at 14:50
  • Well, I'm really trying to emulate word / wordpad. Open the equivalent in OSX and tell me what happens, I'm curious! – roryok Aug 14 '14 at 18:50
  • In both TextEdit and LibraOffice the cursor stays put when you page-up/down however in SublimeText the behaviour is as you describe. For example, if my cursor/carat is on line 3 char 4 and I page-down 50 lines the carat moves to line 53 char 4 (ie, its in the same position within the viewport). This is odd, but if that's the behaviour you're trying to replicate you'll need to find and set the position of the cursor relative to the viewport. – Moob Aug 15 '14 at 12:35
  • Yes, that's what I'm trying to do! – roryok Aug 15 '14 at 15:53
  • See [this question](http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textbox) – Zach Saucier Aug 19 '14 at 16:27
  • @ZachSaucier thanks but that question is not relevant. You may notice my question contains a method to set Caret position already, which works. The issue is I need to first determine the position, from the current scroll position of my content editable div – roryok Aug 20 '14 at 08:20
  • I made a plunk to try to help on this: http://plnkr.co/edit/1wLEeLCLw8v6ykMT1jnV?p=preview, but when I tested it out in IE11 on my Windows 8 machine, page up/down work as expected seemingly out of the box for me. Even setting the document mode and UA string to IE10, it still works. Am I understanding the problem correctly per my plunker example? – Michael Bromley Aug 26 '14 at 11:02
  • 1
    Unbelievable. It looks like simply adding a fixed height and overflow-y: scroll was all that it needed. And after all the messing around I did with javascript. There's an hour left on that bounty, it's yours if you post this as an answer – roryok Aug 26 '14 at 13:59
  • @roryok: Please post your comment and self-accept as the answer. You solved my problem too! =) – user21820 Dec 22 '18 at 15:35

0 Answers0