Поймать ввод пасты

210

Я ищу способ очистки ввода, который я вставляю в браузер, это возможно сделать с помощью jQuery?

Мне удалось придумать это до сих пор:

$(this).live(pasteEventName, function(e) {
 // this is where i would like to sanitize my input
 return false;
}

К сожалению, мое развитие зашло в тупик из-за этой "мелкой" проблемы. Я действительно сделал бы меня счастливым туристом, если бы кто-то мог указать мне правильное направление.

Кристоффер Винтерквист
источник
6
Отметьте stackoverflow.com/a/1503425/749232 как ответ для использования другими людьми, испытывающими ту же проблему. Это решило это для меня.
saji89
2
.live () устарела с jquery 1.9, вместо этого они рекомендуют .on ()
Sameer Alibhai
stackoverflow.com/a/19269040/530153
Раджат Гупта

Ответы:

337

ОК, просто столкнулся с той же проблемой .. Я прошел долгий путь

$('input').on('paste', function () {
  var element = this;
  setTimeout(function () {
    var text = $(element).val();
    // do something with text
  }, 100);
});

Просто маленький тайм-аут до .val () func может быть заполнен.

E.

Евгений Димов
источник
20
Что, если в текстовой области уже есть текст, и вы вставляете его, а вы просто хотите вставить этот текст?
Барфун
39
Работает отлично, спасибо. Тайм-аут 0 работает так же хорошо. Функция просто должна быть отложена до следующего цикла.
Дэниел Льюис,
4
Просто был в похожей ситуации. Тайм-аут истекает, потому что событие вставки не является немедленным, но занимает несколько миллисекунд для вставки содержимого буфера обмена.
James
8
@ user563811: Просто обратите внимание, что в HTML5 официальное минимальное время ожидания составляет 4 мс.
pimvdb
4
Как говорит Шариф, 0ms по-прежнему помещает событие в конец стека.
BobRodes
67

Вы можете получить значение прямо из события . Это немного глупо, как добраться до него, хотя.

Верните false, если вы не хотите, чтобы он прошел.

$(this).on('paste', function(e) {

  var pasteData = e.originalEvent.clipboardData.getData('text')

});
Чарльз Аро
источник
2
Это путь
DdW
1
то есть 11: window.clipboardData.getData ('text')
Wallstrider
4
Однако обратите внимание, что необходимость в свойстве «originalEvent» требуется только в том случае, если вы обрабатываете событие с помощью jQuery. Вы можете сделать только e.clipboardData.getData('text')в простом JavaScript.
Пас
Лучший ответ здесь! Но - мне показалось странным, что сокращенная версия привязки не работает с этим, то есть ошибка, если я попробую это: $ (this) .paste (function (e) {...}) ;, даже хотя это работает для короткой передачи .on ('click') и т. д.
HoldOffHunger
niggle: в коде отсутствует закрывающая скобка. Видимо, изменение слишком мало, чтобы я мог исправить его как правку.
Иоахим Лус
42

Для кросс-платформенной совместимости он должен обрабатывать события oninput и onpropertychange:

$ (something).bind ("input propertychange", function (e) {
    // check for paste as in example above and
    // do something
})
Сюэ Лянлян
источник
2
Прекрасное решение, которое работает как для вставки, так и для захвата событий keyup. Примечание: Это заставляет функцию события запускаться дважды по какой-то причине, если вы выделите входное содержимое, а затем наберете что-то по крайней мере в IE8 (не важно во многих случаях, но, возможно, очень важно в других).
baacke
Ницца ! Я не знал об этом, и он идеально соответствует моим потребностям!
Марк Брильо
18

Я вроде исправил это с помощью следующего кода:

$("#editor").live('input paste',function(e){
    if(e.target.id == 'editor') {
        $('<textarea></textarea>').attr('id', 'paste').appendTo('#editMode');
        $("#paste").focus();
        setTimeout($(this).paste, 250);
    }
});

Теперь мне просто нужно сохранить местоположение каретки и добавить к этой позиции, тогда я все готово ... Я думаю :)

Кристоффер Винтерквист
источник
1
Как вы сохранили место для каретки?
Петах
@Petah Вы можете проверить, на каком элементе находится фокус .find(':focus'), и зная, что этот элемент определяет местоположение каретки для него. Смотрите это .
Джейкоб
Помните, что «жить» не рекомендуется в пользу «на»
NBPalomino
inputимеет значение :) У меня обычно есть это в моих событиях текстового поля, keyup keydown paste inputно очевидно зависит от ваших побуждений
Pierre
10

Хм ... Я думаю, что вы можете использовать, e.clipboardDataчтобы поймать данные вставляются. Если это не удастся, посмотрите здесь .

$(this).live("paste", function(e) {
    alert(e.clipboardData); // [object Clipboard]
});
мофф
источник
2
Когда я запускаю это в Safari, я получаю 'undefined' :(
Christoffer Winterkvist
1
clipboardData
помещается в «
2
Только Internet Explorer!
Лодевийк,
9

Прослушайте событие вставки и установите прослушиватель события keyup. В keyup перехватите значение и удалите прослушиватель событий keyup.

$('.inputTextArea').bind('paste', function (e){
    $(e.target).keyup(getInput);
});
function getInput(e){
    var inputText = $(e.target).val();
    $(e.target).unbind('keyup');
}
Эрик
источник
6
Это очень хорошо, но не работает для вставки правой кнопкой мыши.
Джозеф Равенвольф
он также не работает для вставки среднего щелчка (X11), он работает, только если они использовали клавиатуру для вставки.
Ясен
7
$("#textboxid").on('input propertychange', function () {
    //perform operation
        });

Это будет работать нормально.

Раджат Джайн
источник
6

Это становится ближе к тому, что вы могли бы хотеть.

function sanitize(s) {
  return s.replace(/\bfoo\b/g, "~"); 
};

$(function() {
 $(":text, textarea").bind("input paste", function(e) {
   try {
     clipboardData.setData("text",
       sanitize(clipboardData.getData("text"))
     );
   } catch (e) {
     $(this).val( sanitize( $(this).val() ) );
   }
 });
});

Обратите внимание, что когда объект clipboardData не найден (в браузерах, отличных от IE), вы в настоящее время получаете полное значение элемента + значение буфера обмена.

Вероятно, вы можете сделать несколько дополнительных шагов, чтобы различать два значения, до ввода и после ввода, если вы действительно только после того, какие данные были действительно вставлены в элемент.

Мистер Лаки
источник
6
 $('').bind('input propertychange', function() {....});                      

Это будет работать для события вставки мыши.

Abhiram
источник
2
Это лучшее использование из всех.
Синан Элдем
5

Как насчет сравнения исходного значения поля и измененного значения поля и вычета разности как вставленного значения? Это правильно фиксирует вставленный текст, даже если в поле уже есть текст.

http://jsfiddle.net/6b7sK/

function text_diff(first, second) {
    var start = 0;
    while (start < first.length && first[start] == second[start]) {
        ++start;
    }
    var end = 0;
    while (first.length - end > start && first[first.length - end - 1] == second[second.length - end - 1]) {
        ++end;
    }
    end = second.length - end;
    return second.substr(start, end - start);
}
$('textarea').bind('paste', function () {
    var self = $(this);
    var orig = self.val();
    setTimeout(function () {
        var pasted = text_diff(orig, $(self).val());
        console.log(pasted);
    });
});
Ало Сарв
источник
5

Этот код работает для меня, либо вставка с правого клика, либо прямая копия вставки

   $('.textbox').on('paste input propertychange', function (e) {
        $(this).val( $(this).val().replace(/[^0-9.]/g, '') );
    })

Когда я вставляю Section 1: Labour Costэто становится 1в текстовом поле.

Чтобы разрешить только значение с плавающей точкой, я использую этот код

 //only decimal
    $('.textbox').keypress(function(e) {
        if(e.which == 46 && $(this).val().indexOf('.') != -1) {
            e.preventDefault();
        } 
       if (e.which == 8 || e.which == 46) {
            return true;
       } else if ( e.which < 48 || e.which > 57) {
            e.preventDefault();
      }
    });
Р. Н. Кушваха
источник
4
document.addEventListener('paste', function(e){
    if(e.clipboardData.types.indexOf('text/html') > -1){
        processDataFromClipboard(e.clipboardData.getData('text/html'));
        e.preventDefault();

        ...
    }
});

Дальше:

davidcondrey
источник
Недопустимый текст / html, только URL и текст.
Майк
@Mike Я скопировал фрагмент прямо из ссылочной документации.
davidcondrey
Я пробовал это около дня. Текст / HTML никогда не будет работать. Я закончил тем, что добавил тайм-аут с задержкой 0 и смог получить html из div, где они вставляли. Если у кого-то была рабочая скрипка, это помогло бы. Может быть, я просто делаю это неправильно ...
Майк
3

Смотрите этот пример: http://www.p2e.dk/diverse/detectPaste.htm

Он обязательно отслеживает каждое изменение с помощью события oninput, а затем проверяет, является ли это вставкой по сравнению строк. О, и в IE есть событие onpaste. Так:

$ (something).bind ("input paste", function (e) {
    // check for paste as in example above and
    // do something
})
Илья Бирман
источник
Так что невозможно просто получить текст вставки, когда происходит событие?
Кристофер Винтерквист
Ну, я думаю, вам придется разобраться с этим самостоятельно, например, сравнить до и после. Это должно быть довольно легко. Но почему бы вам просто не переоценить весь вклад? Медленный?
Илья Бирман
Я просто подумал, что это можно было бы сделать, но, думаю, нет, сейчас я пытаюсь использовать другой метод, вставив его в текстовую область, а затем перенеся в конечный пункт назначения. Я надеюсь, что это сработает.
Кристофер Винтерквист
Вам просто нужно найти максимально подходящий фрагмент в начале двух строк (до и после). Все оттуда и вплоть до разницы длин - это вставленный текст.
Илья Бирман
@IlyaBirman нет, это не так: например, вставленный текст может заменить часть (или все) оригинала
Jasen
1

Этот метод использует jqueries contents (). Unwrap ().

  1. Во-первых, обнаружить событие вставки
  2. Добавьте уникальный класс к тегам, которые уже находятся в элементе, в который мы вставляем.
  3. По истечении заданного времени ожидания просмотрите все теги разворачивания содержимого, которые не имеют класс, который вы установили ранее. Примечание. Этот метод не удаляет самозакрывающиеся теги, например,
    см. Пример ниже.

    //find all children .find('*') and add the class .within .addClass("within") to all tags
    $('#answer_text').find('*').each(function () {
    $(this).addClass("within");
    });
    setTimeout(function() {
    $('#answer_text').find('*').each(function () {
        //if the current child does not have the specified class unwrap its contents
        $(this).not(".within").contents().unwrap();
    });
    }, 0);
Шадрак Б. Орина
источник
Определенно лучший, самый короткий и говорящий на всю жизнь ответ, который когда-либо видел !!! Большое вам спасибо, вы сделали мой день;)
веб-программист
0

Это оказалось довольно призрачным. Значение ввода не обновляется до выполнения кода внутри функции события вставки. Я попытался вызвать другие события из функции вставки события, но входное значение по-прежнему не обновляется вставленным текстом внутри функции каких-либо событий. Это все события, кроме keyup. Если вы вызываете keyup из функции события вставки, вы можете очистить вставленный текст из функции события keyup. вот так...

$(':input').live
(
    'input paste',
    function(e)
    {
        $(this).keyup();
    }
);

$(':input').live
(
    'keyup',
    function(e)
    {
        // sanitize pasted text here
    }
);

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


источник
Функция onpaste вызывается до вставки содержимого. Вам необходимо выдержать время не менее 4 мсек, чтобы создать собственную функцию после пасты, чтобы вымыть результаты пасты.
DragonLord
-1

Скрипт для удаления специальных символов из всех полей с классом portlet-form-input-field:

// Remove special chars from input field on paste
jQuery('.portlet-form-input-field').bind('paste', function(e) {
    var textInput = jQuery(this);
    setTimeout(function() {
        textInput.val(replaceSingleEndOfLineCharactersInString(textInput.val()));
    }, 200);
});

function replaceSingleEndOfLineCharactersInString(value) {
    <%
        // deal with end-of-line characters (\n or \r\n) that will affect string length calculation,
        // also remove all non-printable control characters that can cause XML validation errors
    %>
    if (value != "") {
        value = value.replace(/(\x00|\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F)/gm,'');
        return value = value.replace(/(\r\n|\n|\r)/gm,'##').replace(/(\#\#)/gm,"\r\n");
    }
}
Алекс повар
источник
2
Не могли бы вы добавить описание соответствующей дезинфекции и почему это может помочь решить проблему плаката? Простое предоставление блока кода на самом деле не помогает оператору (или будущим поисковикам) понять, как решить проблему, а просто поощряет копирование / вставку неправильно понятого кода.
Трой Алфорд
-2

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

function scroll(elementToBeScrolled) 
{
     //this will reset the scroll to the bottom of the viewable area. 
     elementToBeScrolled.topscroll = elementToBeScrolled.scrollheight;
}
lordcheeto
источник