Javascript поймать вставить событие в текстовой области - PullRequest
4 голосов
/ 13 июля 2010

В настоящее время у меня есть текстовая область, для которой требуется контроль над вставленным текстом,

по сути, мне нужно иметь возможность взять все, что пользователь хочет вставить в текстовое поле, и поместить его в переменную.

Затем я определю позицию, в которой они вставили текст, и размер строки, чтобы удалить его из текстовой области,

Тогда в конце разберись с текстом, который находится в переменной по-моему.

Мой вопрос: как мне получить копию текста в переменной, только что вставленной пользователем?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 13 июля 2010

Я ответил на аналогичный вопрос несколько дней назад: Обнаружение вставленного текста с помощью ctrl + v или щелчка правой кнопкой мыши -> вставить . На этот раз я включил довольно длинную функцию, которая точно определяет границы выделения в текстовой области в IE; остальное относительно просто.

Вы можете использовать событие вставки, чтобы обнаружить вставку в большинстве браузеров (особенно не Firefox 2, хотя). Когда вы обрабатываете событие вставки, запишите текущий выбор, а затем установите краткий таймер, который вызывает функцию после завершения вставки. Затем эта функция может сравнивать длины, чтобы узнать, где искать вставленный контент. Примерно так:

function getSelectionBoundary(el, start) {
    var property = start ? "selectionStart" : "selectionEnd";
    var originalValue, textInputRange, precedingRange, pos, bookmark, isAtEnd;

    if (typeof el[property] == "number") {
        return el[property];
    } else if (document.selection && document.selection.createRange) {
        el.focus();

        var range = document.selection.createRange();
        if (range) {
            // Collapse the selected range if the selection is not a caret
            if (document.selection.type == "Text") {
                range.collapse(!!start);
            }

            originalValue = el.value;
            textInputRange = el.createTextRange();
            precedingRange = el.createTextRange();
            pos = 0;

            bookmark = range.getBookmark();
            textInputRange.moveToBookmark(bookmark);

            if (/[\r\n]/.test(originalValue)) {
                // Trickier case where input value contains line breaks

                // Test whether the selection range is at the end of the
                // text input by moving it on by one character and
                // checking if it's still within the text input.
                try {
                    range.move("character", 1);
                    isAtEnd = (range.parentElement() != el);
                } catch (ex) {
                    log.warn("Error moving range", ex);
                    isAtEnd = true;
                }
                range.moveToBookmark(bookmark);

                if (isAtEnd) {
                    pos = originalValue.length;
                } else {
                    // Insert a character in the text input range and use
                    // that as a marker
                    textInputRange.text = " ";
                    precedingRange.setEndPoint("EndToStart", textInputRange);
                    pos = precedingRange.text.length - 1;

                    // Delete the inserted character
                    textInputRange.moveStart("character", -1);
                    textInputRange.text = "";
                }
            } else {
                // Easier case where input value contains no line breaks
                precedingRange.setEndPoint("EndToStart", textInputRange);
                pos = precedingRange.text.length;
            }
            return pos;
        }
    }
    return 0;
}

function getTextAreaSelection(textarea) {
    var start = getSelectionBoundary(textarea, true),
        end = getSelectionBoundary(textarea, false);

    return {
        start: start,
        end: end,
        length: end - start,
        text: textarea.value.slice(start, end)
    };
}

function detectPaste(textarea, callback) {
    textarea.onpaste = function() {
        var sel = getTextAreaSelection(textarea);
        var initialLength = textarea.value.length;
        window.setTimeout(function() {
            var val = textarea.value;
            var pastedTextLength = val.length - (initialLength - sel.length);
            var end = sel.start + pastedTextLength;
            callback({
                start: sel.start,
                end: end,
                length: pastedTextLength,
                text: val.slice(sel.start, end),
                replacedText: sel.text
            });
        }, 1);
    };
}

window.onload = function() {
    var textarea = document.getElementById("your_textarea");
    detectPaste(textarea, function(pasteInfo) {
        var val = textarea.value;

        // Delete the pasted text and restore any previously selected text
        textarea.value = val.slice(0, pasteInfo.start) +
            pasteInfo.replacedText + val.slice(pasteInfo.end);

        alert(pasteInfo.text);
    });
};
1 голос
/ 02 февраля 2013

Вместо этого вы можете теперь использовать FilteredPaste.js (http://willemmulder.github.com/FilteredPaste.js/)). Это позволит вам контролировать, какой контент вставляется в текстовую область или contenteditable, и вы сможете фильтровать / изменять / извлекать контент по желанию.

0 голосов
/ 13 июля 2010

Быстрый поиск показывает, что существуют разные методы для разных браузеров. Я не уверен, что у jQuery есть решение. Prototype.js, похоже, не имеет такового. Может быть, YUI может сделать это для вас?

Вы также можете использовать TinyMCE, поскольку у него есть множество разных триггеров событий. Это полноценный текстовый процессор, но вы можете использовать его как обычный текст, если хотите. Это может быть слишком много веса, чтобы добавить, хотя. Например, при инициации он превращает ваш <textarea> в iFrame с несколькими подпрограммами. Но он будет делать то, что вы просите.

- Dave

...