JavaScript: выделите выделение после использования textarea.setSelectionRange в Chrome - PullRequest
13 голосов
/ 19 сентября 2011

Функция javascript выбирает определенное слово в текстовой области с помощью .setSelectionRange (). В Firefox текстовая область автоматически прокручивается вниз, чтобы показать выбранный текст. В Chrome (v14) это не так. Есть ли способ заставить Chrome прокрутить текстовую область до вновь выделенного текста? Решения jQuery приветствуются.

Ответы [ 7 ]

7 голосов
/ 19 сентября 2011

Вот простое и эффективное решение, чисто js:

//first of all, you ignore any bad english, as i'm french and had a funny evening
//get the textarea
var textArea = document.getElementById('myTextArea');

//define your selection
var selectionStart = 50;
var selectionEnd = 60;
textArea.setSelectionRange( selectionStart, selectionEnd);

// now lets do some math
// we need the number of chars in a row
var charsPerRow = textArea.cols;

// we need to know at which row our selection starts
var selectionRow = (selectionStart - (selectionStart % charsPerRow)) / charsPerRow;

// we need to scroll to this row but scrolls are in pixels,
// so we need to know a row's height, in pixels
var lineHeight = textArea.clientHeight / textArea.rows;

// scroll !!
textArea.scrollTop = lineHeight * selectionRow;

Поместите это в функцию, добавьте в нее прототип объекта Element javascript, и все хорошо.

Не стесняйтесь спрашивать, нужна ли вам дополнительная помощь.

7 голосов
/ 19 сентября 2011

Вы можете увидеть, как мы решили проблему в ProveIt (см. HighlightLengthAtIndex). По сути, дело в том, чтобы обрезать текстовую область, прокрутить до конца, а затем восстановить вторую часть текста. Мы также использовали плагин textSelection для согласованного поведения в разных браузерах.

2 голосов
/ 13 октября 2016

Это код, вдохновленный ответом Мэтью Флашена .

/**
 * Scroll textarea to position.
 *
 * @param {HTMLInputElement} textarea
 * @param {Number} position
 */
function scrollTo(textarea, position) {
    if (!textarea) { return; }
    if (position < 0) { return; }

    var body = textarea.value;
    if (body) {
        textarea.value = body.substring(0, position);
        textarea.scrollTop = position;
        textarea.value = body;
    }
}

По сути, дело в том, чтобы обрезать текстовую область, прокрутить до конца, а затем восстановить вторую часть текста.

Используйте его следующим образом

var textarea, start, end;
/* ... */

scrollTo(textarea, end);
textarea.focus();
textarea.setSelectionRange(start, end);
1 голос
/ 31 октября 2018

Много ответов, но принятый не учитывает разрывы строк, Мэтью Флашен не добавил код решения, а naXa ответесть ошибка.Самый простой код решения:

textArea.focus();

const fullText = textArea.value;
textArea.value = fullText.substring(0, selectionEnd);
textArea.scrollTop = textArea.scrollHeight;
textArea.value = fullText;

textArea.setSelectionRange(selectionStart, selectionEnd);
0 голосов
/ 12 марта 2019

Элегантное решение Валерия Каткова прекрасно работает, но имеет две проблемы:

  1. Не работает для длинных строк
  2. Выбранное содержимое прокручивается до нижней частитекстовое поле, затрудняющее просмотр контекста, окружающего выделение

Вот моя улучшенная версия, которая работает для длинных строк (протестировано не менее чем с 50 000 слов) и прокрутки выделения до центра текстового поля:

function setSelectionRange(textarea, selectionStart, selectionEnd) {
    // First scroll selection region to view
    const fullText = textarea.value;
    textarea.value = fullText.substring(0, selectionEnd);
    // For some unknown reason, you must store the scollHeight to a variable
    // before setting the textarea value. Otherwise it won't work for long strings
    const scrollHeight = textarea.scrollHeight
    textarea.value = fullText;
    let scrollTop = scrollHeight;
    const textareaHeight = textarea.clientHeight;
    if (scrollTop > textareaHeight){
        // scroll selection to center of textarea
        scrollTop -= textareaHeight / 2;
    } else{
        scrollTop = 0;
    }
    textarea.scrollTop = scrollTop;

    // Continue to set selection range
    textarea.setSelectionRange(selectionStart, selectionEnd);
}

Работает в Chrome 72, Firefox 65, Opera 58 и Edge 42

Пример использования этой функции см. В моем проекте GitHub SmartTextarea .

0 голосов
/ 08 сентября 2017

Полный код для Chrome

<script type="text/javascript">
            var SAR = {};

            SAR.find = function () {
                debugger;
                var parola_cercata = $("#text_box_1").val(); // the searched word
                // make text lowercase if search is supposed to be case insensitive
                var txt = $('#remarks').val().toLowerCase();
                parola_cercata = parola_cercata.toLowerCase();

                var posi = jQuery('#remarks').getCursorPosEnd(); // take the position of the word in the text

                var termPos = txt.indexOf(parola_cercata, posi);

                if (termPos !== -1) {
                    debugger;
                    var target = document.getElementById("remarks");
                    var parola_cercata2 = $("#text_box_1").val();
                    // select the textarea and the word
                    if (target.setSelectionRange) {

                        if ('selectionStart' in target) {
                            target.selectionStart = termPos;
                            target.selectionEnd = termPos;
                            this.selectionStart = this.selectionEnd = target.value.indexOf(parola_cercata2);
                            target.blur();
                            target.focus();
                            target.setSelectionRange(termPos, termPos + parola_cercata.length);
                        }
                    } else {
                        var r = target.createTextRange();
                        r.collapse(true);
                        r.moveEnd('character', termPos + parola_cercata);
                        r.moveStart('character', termPos);
                        r.select();
                    }
                } else {
                    // not found from cursor pos, so start from beginning
                    termPos = txt.indexOf(parola_cercata);
                    if (termPos !== -1) {
                        var target = document.getElementById("remarks");
                        var parola_cercata2 = $("#text_box_1").val();
                        // select the textarea and the word
                        if (target.setSelectionRange) {

                            if ('selectionStart' in target) {
                                target.selectionStart = termPos;
                                target.selectionEnd = termPos;
                                this.selectionStart = this.selectionEnd = target.value.indexOf(parola_cercata2);
                                target.blur();
                                target.focus();
                                target.setSelectionRange(termPos, termPos + parola_cercata.length);
                            }
                        } else {
                            var r = target.createTextRange();
                            r.collapse(true);
                            r.moveEnd('character', termPos + parola_cercata);
                            r.moveStart('character', termPos);
                            r.select();
                        }
                    } else {
                        alert("not found");
                    }
                }
            };


            $.fn.getCursorPosEnd = function () {
                var pos = 0;
                var input = this.get(0);
                // IE Support
                if (document.selection) {
                    input.focus();
                    var sel = document.selection.createRange();
                    pos = sel.text.length;
                }
                // Firefox support
                else if (input.selectionStart || input.selectionStart === '0')
                    pos = input.selectionEnd;
                return pos;
            };
</script> 
0 голосов
/ 10 августа 2012

Я опубликовал ответ здесь:

http://blog.blupixelit.eu/scroll-textarea-to-selected-word-using-javascript-jquery/

Он отлично работает с одним необходимым правилом: установите высоту строки в CSS текстовой области!

Он вычисляет позицию слова, к которому нужно прокрутиться, просто выполняя некоторые математические вычисления, и он отлично работает во всех моих экспериментах!

Не стесняйтесь спрашивать меня о том, что вам нужно о коде!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...