如何滚动到文本区域中光标的位置?

How do you scroll to the position of the cursor in a textarea?

JS Fiddle Demo

HTML

<textarea rows='5'>
sdfasjfalsfjasf;klasdfklaksdfkjlasdfkjlasdjkfadls;fjklasdfjklasdkjlfaskljdfkalsjdfjlkasdfkjlasdkjlfasfkl;ajklsdfjklasdfkjlaskjldfaskjlfkljsadkjlfaskjldfkjlasdfkjlasdjklfaskljdfkjlasfkjlasdkjlfasjklfajklsdfjklasdfjlkadjsdfasjfalsfjasf;klasdfklaksdfkjlasdfkjlasdjkfadls;fjklasdfjklasdkjlfaskljdfkalsjdfjlkasdfkjlasdkjlfasfkl;ajklsdfjklasdfkjlaskjldfaskjlfkljsadkjlfaskjldfkjlasdfkjlasdjklfaskljdfkjlasfkjlasdkjlfasjklfajklsdfjklasdfjlkadjsdfasjfalsfjasf;klasdfklaksdfkjlasdfkjlasdjkfadls;fjklasdfjklasdkjlfaskljdfkalsjdfjlkasdfkjlasdkjlfasfkl;ajklsdfjklasdfkjlaskjldfaskjlfkljsadkjlfaskjldfkjlasdfkjlasdjklfaskljdfkjlasfkjlasdkjlfasjklfajklsdfjklasdfjlkadjsdfasjfalsfjasf;klasdfklaksdfkjlasdfkjlasdjkfadls;fjklasdfjklasdkjlfaskljdfkalsjdfjlkasdfkjlasdkjlfasfkl;ajklsdfjklasdfkjlaskjldfaskjlfkljsadkjlfaskjldfkjlasdfkjlasdjklfaskljdfkjlasfkjlasdkjlfasjklfajklsdfjklasdfjlkadj
</textarea>

<br />
<button id='scroll-to-cursor'>Scroll to Cursor</button>

JavaScript

$('#scroll-to-cursor').on('click', function() {
    // ?
});

期望的结果

  1. 单击文本区域中的某处以放置光标。
  2. 滚开以使光标不可见。
  3. 单击 "Scroll to Cursor" 按钮。
  4. 文本区域滚动到光标所在位置

注意:我正在使用 jQuery。

我唯一能弄清楚如何滚动的方法是使用 jQuery 的 scrollTop 功能。它将滚动位置设置为 "the number of pixels that are hidden from view above the scrollable area".

我在下面绘制了问题图解。将红线的长度(以像素为单位)传递给 scrollTop 应该可以解决问题。但是我不知道如何得到线的长度。

从 Jonathan Levine 的评论中,我意识到 this answer 对我有用。

Fiddle Demo

JavaScript

$('#scroll-to-cursor').on('click', function() {    
    $('textarea').focus();
    $.event.trigger({ type : 'keypress' }); // works cross-browser

    // new KeyboardEvent('keypress'); // doesn't work in IE and Safari

    /* var evt = document.createEvent('KeyboardEvent');
    evt.initKeyEvent('keypress', true, true, null, false, false, false, false, 0, 32);
    $textarea.dispatchEvent(evt);

    evt = document.createEvent('KeyboardEvent');
    evt.initKeyEvent('keypress', true, true, null, false, false, false, false, 8, 0);
    $textarea.dispatchEvent(evt); */
});

/*
    To test:
    1) Click somewhere in the textarea to place cursor
    2) Scroll away so cursor isn't visible
    3) Click "Scroll to Cursor" button
*/

说明

当用户按下一个键时,浏览器会做两件事:

  1. 将键放在光标后的位置。
  2. 滚动到该位置。

这个解决方案只是模拟(没有实际输入任何文本)。

编辑:旧的解决方案不符合标准。 initKeyEvent is deprecated. The update only uses the KeyboardEvent() 构造函数,兼容并适用于除 IE 之外的所有浏览器(Safari 是问号)。

编辑 2:使用 $.event.trigger({ type : 'keypress' }); 而不是 new KeyboardEvent() 也同样有效,并且适用于所有浏览器。

textarea.blur()
textarea.focus()

做这份工作。

示例:https://jsfiddle.net/syy25x69/

要select在IE中查看一段文字:Set textarea selection in Internet Explorer

更新

为了让它起作用,我注意到 selection 必须折叠。如果需要,您可以稍后恢复 selection。

// collapse selection here
textarea.blur()
textarea.focus() // this scrolls the textarea
// expand selection here

另一个例子:https://jsfiddle.net/rk8cL174/

这是我的观点。

我发现 Audi Nugraha 的解决方案在测试时有效,但在 Electron 应用程序中尝试时却无效。

一个对我有用的解决方案是将光标定位到开头,然后 blur/focus。

textarea.selectionEnd = textarea.selectionStart = position;
textarea.blur();
textarea.focus();

我已经将上面的内容合并到一个函数中:

function scrollTextarea(textarea,position) {
    textarea.selectionEnd = textarea.selectionStart = position;
    textarea.blur();
    textarea.focus();
}

出于某些奇怪的原因,Chrome 仅在文本框上有插入符号时滚动,而不是在选择处于活动状态时滚动,因此如果您需要滚动到选择,请执行以下小技巧:

  // set the single caret first
  textarea.setSelectionRange(index, index);

  // focus the textarea box so the scroll happens
  textarea.focus();

  // now do the selection
  textarea.setSelectionRange(index, index + x);