Ловіть введення пасти


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

Відповіді:


337

Гаразд, просто наткнувся на те саме питання .. Я пройшов довгий шлях

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

Лише невеликий тайм-аут, поки функція .val () може заповнитися.

E.


20
Що робити, якщо в текстовій області вже є текст, і ви вставляєте текст, і ви просто хотіли вставити текст?
барфун

39
Працює чудово, дякую. Час очікування 0 працює так само добре. Функцію просто потрібно перенести на наступний цикл.
Даніель Льюїс

4
Просто опинився в подібній ситуації. Час очікування є, тому що подія вставлення не є негайною, але потрібно вставити кілька мілісекунд, щоб вміст буфера обміну був вставлений.
Джеймс,

8
@ user563811: Зауважте лише, що офіційний мінімальний час очікування в HTML5 становить 4 мс.
pimvdb

4
Як каже шаріф, 0ms все ще ставить подію внизу стеку.
BobRodes

67

Ви можете фактично схопити значення прямо з події . Це трохи тупо, як дістатися до нього.

Поверніть помилкове значення, якщо ви не хочете, щоб воно пройшло.

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

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

});

2
Це шлях
DdW

1
тобто 11: window.clipboardData.getData ('текст')
Wallstrider

4
Однак зауважте, що властивість "originalEvent" потрібна лише в тому випадку, якщо ви обробляєте подію jQuery. Ви можете робити це просто e.clipboardData.getData('text')в простому JavaScript.
Asier Paz

Найкраща відповідь тут! Але - мені здається дивним, що короткоформатна версія прив'язки не працює з цим, тобто помилка, якщо я спробую це: $ (this) .paste (function (e) {...}) ;, even хоча це працює для короткошерстного .on ("натискання") тощо.
HoldOffHunger

niggle: у коді відсутній закриваючий батьків. Мабуть, зміна занадто мала, щоб дозволити мені виправити це як редагування.
Йоахім Люс

42

Для сумісності між платформами він повинен обробляти події входу та зміни власності:

$ (something).bind ("input propertychange", function (e) {
    // check for paste as in example above and
    // do something
})

2
Прекрасне рішення, яке працює як вставки, так і вловлювання подій клавіатури. Примітка. Це призводить до того, що функція події з двох причин вимикається двічі, якщо виділити вхідний вміст, а потім набрати щось принаймні 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

@Petah Ви можете перевірити, який елемент має фокус .find(':focus'), і знаючи, що цей елемент визначає розташування карети для нього. Дивіться це .
Яків

Пам’ятайте, що "Live" застаріло на користь "on"
NBPalomino

inputмає значення: У мене це зазвичай є у моїх подіях, keyup keydown paste inputале очевидно, що залежить від ваших мотивів
П'єр,

10

Хм ... я думаю, ви можете використовувати e.clipboardDataдля вловлювання даних, що вставляються. Якщо це не вийшло, подивіться тут .

$(this).live("paste", function(e) {
    alert(e.clipboardData); // [object Clipboard]
});

2
Коли я запускаю це в Safari, я отримую "невизначений" :(
Крістоффер Вінтерквіст,

1
clipboardData є пісочницею у більшості веб-переглядачів (очевидний отвір для безпеки.)
podperson

2
Тільки Internet Explorer!
Lodewijk

9

Прослухайте подію вставки та встановіть слухача подій клавіатури. Під час клавіатури введіть значення та видаліть слухач подій клавіатури.

$('.inputTextArea').bind('paste', function (e){
    $(e.target).keyup(getInput);
});
function getInput(e){
    var inputText = $(e.target).val();
    $(e.target).unbind('keyup');
}

6
Це дуже добре, але це не працює для вставлення правою кнопкою миші.
Джозеф Равенволф

він також не працює для вставки середнього клацання (X11), він працює лише в тому випадку, якщо для вставки вставили клавіатуру.
Ясен


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), ви отримуєте повне значення елемента + значення clipboard'ed.

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



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();

        ...
    }
});

Далі:


text / html недійсний, лише URL-адреса та текст.
Майк

@Mike Я скопіював фрагмент прямо з посилається на документацію.
davidcondrey

Я пробував це близько дня. текст / html ніколи не працюватиме. Я в кінцевому підсумку додав тайм-аут із затримкою 0 і зміг схопити html з дива, куди вони вставляли. Якщо у когось є робоча загадка, це допоможе. Можливо, я просто роблю це неправильно ...
Майк,

3

Дивіться цей приклад: http://www.p2e.dk/diverse/detectPaste.htm

Він суттєво відстежує кожну зміну за допомогою події oninput, а потім перевіряє, чи це порівняння вставки за рядком. О, і в IE відбувається подія на шляху пасти. Так:

$ (something).bind ("input paste", function (e) {
    // check for paste as in example above and
    // do something
})

Тож неможливо просто дістати текст вставлення, коли відбувається подія?
Крістоффер Вінтерквіст

Ну, мабуть, вам доведеться зіткнутися з цим самостійно, як, порівняйте до і після. Це повинно бути досить легко. Але чому ви просто не скасуєте весь внесок? Повільно?
Ілля Бірман

Я просто думав, що це можна зробити, але, мабуть, ні, зараз я намагаюся інший метод, вставивши його в текстовий пояс і потім перенести його до кінцевого пункту призначення. Я сподіваюся, що це спрацює.
Крістофер Вінтерквіст

Вам просто потрібно знайти фрагмент максимальної відповідності на початку двох рядків (до і після). Все звідти і аж до різниці довжин - це вставлений текст.
Ілля Бірман

@IlyaBirman ні, це не так: наприклад, вставлений текст може замінити частину (або всю) оригіналу
Jasen

1

Цей метод використовує вміст jqueries (). Unrap ().

  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

Це виявилося досить ілюзивно. Значення вводу не оновлюється до виконання коду всередині функції події вставки. Я намагався викликати інші події з функції події вставки, але вхідне значення все ще не оновлюється вставленим текстом всередині функції будь-яких подій. Це все події, крім клавіатури. Якщо ви зателефонуєте за допомогою клавіатури в межах функції події вставки, ви можете очистити вкладений текст із функції події клавіатури. так ...

$(':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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.