캐치 페이스트 입력


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의 추천되지 않습니다, 그들은 대신) (CSTE 연구진 추천
사미르 Alibhai

답변:


337

좋아, 그냥 같은 문제에 부딪쳤다. 나는 먼 길을 갔다

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

.val () func이 채워질 때까지 작은 시간 초과.

이자형.


20
텍스트 영역에 텍스트가 이미 있고 붙여 넣은 경우 붙여 넣은 텍스트를 원하면 어떻게됩니까?
barfoon

39
완벽하게 작동합니다. 감사합니다. 시간 종료 0도 마찬가지로 작동합니다. 이 함수는 다음 루프로 연기되어야합니다.
Daniel Lewis

4
비슷한 상황에 처해있었습니다. 붙여 넣기 이벤트가 즉각적이지 않지만 클립 보드 내용을 붙여 넣는 데 몇 밀리 초가 걸리기 때문에 시간이 초과됩니다.
James

8
@ user563811 : HTML5에서 공식 최소 시간 제한은 4ms입니다.
pimvdb

4
sharif가 말했듯이 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로만 할 수 있습니다 .
Asier Paz

가장 좋은 답변은 여기입니다! 그러나-바인딩의 짧은 버전이 이것과 작동하지 않는 것이 이상하다는 것을 알았습니다. 예를 들어 시도하면 오류가 발생했습니다 : $ (this) .paste (function (e) {...}); 그것은
.on

낄낄 거리는 소리 : 코드에 닫는 패런이 없습니다. 변경 사항이 너무 작아서 수정 사항으로 수정할 수없는 것 같습니다.
Joachim Lous

42

크로스 플랫폼 호환성을 위해서는 입력 및 속성 변경 이벤트를 처리해야합니다.

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

2
붙여 넣기 및 키업 이벤트 잡기로 모두 작동하는 아름다운 솔루션입니다. 참고 : 이 이벤트 기능을 사용하면 입력 내용을 강조하는 경우 어떤 이유로 두 번 화재가 발생 다음 에 뭔가 입력 적어도 IE8 (많은 경우에 중요하지만, 다른 사람의 가능성이 매우 중요한되지 않음).
baacke

좋아요! 나는 이것에 대해 몰랐다. 그리고 그것은 나의 필요에 완벽하게 들어 맞는다!
Marc Brillault

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')캐럿 위치를 결정하는 것을 알고 있습니다. 참조 .
Jacob

"live"는 "on"을 위해 사용되지 않습니다.
NBPalomino

input차이가 있습니다 :) 나는 보통 내 텍스트 상자 이벤트에서 이것들을 가지고 keyup keydown paste input있지만 분명히 당신의 동기가 무엇인지에 달려 있습니다
Pierre

10

흠 ... 붙여 넣는 데이터를 잡는 데 사용할 수 있다고 생각 합니다 e.clipboardData. 팬 아웃되지 않으면 여기를 살펴 보십시오 .

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

2
내가 Safari에서 이것을 실행하면 '정의되지 않음'을 얻습니다 :(
Christoffer Winterkvist

1
clipboardData는 대부분의 브라우저에서 샌드 박스 처리됩니다 (분명한 보안 허점)
podperson

2
인터넷 익스플로러 전용!
Lodewijk

9

붙여 넣기 이벤트를 수신하고 키업 이벤트 리스너를 설정하십시오. 키업시 값을 캡처하고 키업 이벤트 리스너를 제거하십시오.

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

6
이것은 매우 좋지만 오른쪽 클릭 붙여 넣기에는 작동하지 않습니다.
Joseph Ravenwolfe

가운데 클릭 붙여 넣기 (X11)에서는 작동하지 않으며 키보드를 사용하여 붙여 넣기 한 경우에만 작동합니다.
Jasen

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() {....});                      

이것은 마우스 붙여 넣기 이벤트에서 작동합니다.


2
이것은 모두의 가장 좋은 사용법입니다.
Sinan Eldem

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텍스트 상자에.

float 값만 허용하려면이 코드를 사용하십시오.

 //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

@Mike 나는 참조 문서에서 직접 스 니펫을 복사했습니다.
davidcondrey 2016 년

나는 약 하루 동안 이것을 시도했다. text / html은 작동하지 않습니다. 결국 0 시간 지연 시간을 추가하고 div를 붙여 넣은 div에서 html을 가져올 수있었습니다. 아마 그냥 잘못하고있어 ...
마이크

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
})

이벤트가 발생할 때 붙여 넣기 텍스트를 얻는 것이 불가능합니까?
Christoffer Winterkvist

글쎄, 전과 후를 비교하는 것처럼 직접 처리해야 할 것 같습니다. 오히려 쉬워야합니다. 그러나 전체 입력 내용을 다시 확인하지 않는 이유는 무엇입니까? 느린?
Ilya Birman

방금 할 수 있다고 생각했지만 그렇지 않습니다. 지금은 텍스트 영역에 붙여 넣은 다음 최종 목적지로 다른 방법을 시도하고 있습니다. 나는 그것이 효과가 있기를 바라고있다.
Christoffer Winterkvist

두 문자열의 시작 부분 (전후)에서 최대 일치 조각을 찾아야합니다. 거기에서 길이 차이까지의 모든 것은 붙여 넣은 텍스트입니다.
Ilya Birman

@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

이것은 꽤 현명한 것으로 판명되었습니다. 붙여 넣기 이벤트 함수 내에서 코드를 실행하기 전에 입력 값이 업데이트되지 않습니다. 붙여 넣기 이벤트 함수 내에서 다른 이벤트를 호출하려고 시도했지만 입력 값이 여전히 이벤트 함수 내에서 붙여 넣은 텍스트로 업데이트되지 않았습니다. 이것이 키업을 제외한 모든 이벤트입니다. 붙여 넣기 이벤트 함수 내에서 키업을 호출하면 키업 이벤트 함수 내에서 붙여 넣은 텍스트를 삭제합니다. 그렇게 ...

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

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

여기에 하나의 경고가 있습니다. Firefox에서 모든 키업에서 입력 텍스트를 재설정하는 경우 텍스트가 입력 너비에서 허용되는 볼 수있는 영역보다 긴 경우 모든 키업에서 값을 재설정하면 자동으로 캐럿 위치로 텍스트를 스크롤하는 브라우저 기능이 작동하지 않습니다. 텍스트의 끝. 대신 텍스트가 맨 처음으로 스크롤되어 캐럿이 보이지 않게됩니다.


onpaste는 내용을 붙여 넣기 전에 호출됩니다. 붙여 넣기 결과를 씻기 위해 자체 붙여 넣기 기능을 만들려면 최소 4ms의 시간 지연이 필요합니다.
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
관련 위생 처리에 대한 설명과 포스터 문제 해결에 도움이되는 이유를 추가해 주시겠습니까? 단순히 코드 블록을 제공한다고해서 OP (또는 향후 검색 자)가 문제를 해결하는 방법을 이해하는 데 실제로 도움이되는 것은 아니며 잘못 이해 된 코드를 복사 / 붙여 넣기 만하면됩니다.
Troy Alford

-2

여기에 하나의 경고가 있습니다. Firefox에서 모든 키업에서 입력 텍스트를 재설정하는 경우 텍스트가 입력 너비에서 허용되는 볼 수있는 영역보다 긴 경우 모든 키업에서 값을 재설정하면 자동으로 캐럿 위치로 텍스트를 스크롤하는 브라우저 기능이 작동하지 않습니다. 텍스트의 끝. 대신 텍스트가 맨 처음으로 스크롤되어 캐럿이 보이지 않게됩니다.

function scroll(elementToBeScrolled) 
{
     //this will reset the scroll to the bottom of the viewable area. 
     elementToBeScrolled.topscroll = elementToBeScrolled.scrollheight;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.