사용자가 입력을 멈출 때까지 .keyup () 처리기를 지연시키는 방법은 무엇입니까?


642

검색 창이 있습니다. 지금은 모든 키업을 검색합니다. 따라서 누군가“Windows”를 입력하면“W”,“Wi”,“Win”,“Wind”,“Windo”,“Window”,“Windows”와 같은 모든 키업에 대해 AJAX를 검색합니다.

지연을 원하므로 사용자가 200ms 동안 입력을 중지하면 검색 만합니다.

keyup함수 에 이것에 대한 옵션이 없으며 시도 setTimeout했지만 작동하지 않았습니다.

어떻게해야합니까?



2
가능하다면 이것을 복제본으로 닫을 것입니다.
a432511

7
주어진 대답과 대답이 정확하다면 복제본이 손상되는 것을 보지 못합니다. 질문 데이터베이스에 추가하는 것은 좋은 일이며 노력해야 할 일이어야합니다.
Mattis

14
해로운 것은 미래에 사람들이 동일한 질문이 100 개이면 모든 사람이 공유하는 훌륭한 답변으로부터 혜택을 볼 수 없기 때문에 속임수를 닫고 모든 사람을 원래 질문으로 리디렉션하는 것이 모범 사례와 수정 사항을 찾는 데 더 좋습니다. 중복이 닫힌 이유에 대한 자세한 내용은 stackoverflow.com/help/duplicates 를 참조하십시오 .
rncrtr

14
이것은 복제 된 것으로 추정되는 것보다 훨씬 인기가 있습니다. 더 나은 말로 표현되고, 더 나은 답변을 가지며, Google 등에서 더 높은 순위를 차지합니다. 돌이켜 보면 이것이 닫힌다면 수치스러운 일이었을 것이다. 중복으로 나쁜 사소한 것들이 있지만 이것은 그 범주에 속하지 않습니다.
사용자

답변:


1124

이 작은 함수를 동일한 목적으로 사용하여 사용자가 지정된 시간 동안 입력을 중지 한 후 또는 높은 속도로 발생하는 이벤트에서 함수를 실행합니다 resize.

function delay(callback, ms) {
  var timer = 0;
  return function() {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      callback.apply(context, args);
    }, ms || 0);
  };
}


// Example usage:

$('#input').keyup(delay(function (e) {
  console.log('Time elapsed!', this.value);
}, 500));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="input">Try it:
<input id="input" type="text" placeholder="Type something here..."/>
</label>

작동 방식 :

그만큼 delay 함수는 개별 타이머를 내부적으로 처리하는 랩핑 된 함수를 반환합니다. 각 실행에서 제공된 시간 지연으로 타이머가 다시 시작됩니다.이 시간이 지나기 전에 여러 번 실행되면 타이머가 재설정되고 다시 시작됩니다.

타이머가 마지막으로 끝나면 콜백 함수가 실행되어 원래 컨텍스트와 인수 (이 예제에서는 jQuery의 이벤트 객체 및 DOM 요소를 전달 함)를 전달합니다. this )로 전달합니다.

업데이트 2019-05-16

현대적인 환경에서 ES5 및 ES6 기능을 사용하여 기능을 다시 구현했습니다.

function delay(fn, ms) {
  let timer = 0
  return function(...args) {
    clearTimeout(timer)
    timer = setTimeout(fn.bind(this, ...args), ms || 0)
  }
}

구현은 일련의 테스트가 포함 됩니다.

좀 더 정교한 것을 원하면 jQuery Typewatch 플러그인을 살펴보십시오 .


64
또 다른 대안 : github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js . 그것은 당신이 묘사 한 것과 거의 같은 방식으로 작동합니다. 저는 그 패턴을 많이 사용하여 구문을 단순화하기 위해 jQuery 플러그인으로 구현했습니다. 데모 페이지는 다음과 같습니다. briangrinstead.com/files/bindWithDelay
Brian Grinstead

2
내가 처음에 입력 한 문자의 양을 하드 코딩이 방법은 (sulfer없이) 당밀로 부드러운
하르

2
이것을 $ .post ()와 함께 사용하면 동시에 입력 한 모든 것을 보내지 만 키 업 횟수만큼 보냅니다. 타임 아웃이 끝났을 때만 보낼 수있는 방법이 있습니까?
ntgCleaner 2016 년

7
그러나 개별 지연이 필요한 둘 이상의 다른 기능을 호출하는 경우에는 작동하지 않습니다. 대신이 솔루션을 사용했습니다. stackoverflow.com/a/30503848/1834212
Miguel

4
상단 코멘트에 링크 된 'bindWithDelay'플러그인을 권장합니다. 그러나 나는이 질문에 대한 @Hazerider의 대답 (아래 stackoverflow.com/a/19259625/368896 )을 제안합니다. 위의 플러그인 코드에서 사용 된 것과 동일한 원리이지만 이해하기 쉽습니다.
Dan Nissenbaum

60

유형이 완료 된 후 검색하려면 전역 변수를 사용하여 setTimout호출 에서 반환 된 시간 초과를 유지하고 clearTimeout아직 발생하지 않은 경우로 취소 하여 마지막 keyup이벤트를 제외하고 시간 초과가 발생하지 않도록하십시오

var globalTimeout = null;  
$('#id').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
}   
function SearchFunc(){  
  globalTimeout = null;  
  //ajax code
}

또는 익명 함수 :

var globalTimeout = null;  
$('#id').keyup(function() {
  if (globalTimeout != null) {
    clearTimeout(globalTimeout);
  }
  globalTimeout = setTimeout(function() {
    globalTimeout = null;  

    //ajax code

  }, 200);  
}   

39

CMS의 답변에 대한 또 다른 약간의 향상. 별도의 지연을 쉽게 허용하기 위해 다음을 사용할 수 있습니다.

function makeDelay(ms) {
    var timer = 0;
    return function(callback){
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
};

동일한 지연을 재사용하려면 다음을 수행하십시오.

var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});

별도의 지연을 원한다면 할 수 있습니다

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});

1
필자가이 의견을 작성하는 시점에 600 개가 넘는 투표율을 가진 솔루션이 2 개의 투표율 (내 포함) 만있는이 답변만큼 좋지 않다는 점에 흥미가 있습니다. 지연을 공유하거나 공유 할 수없는 여러 위젯을 지원하기 때문에 분명히 우수합니다. 훌륭한 답변입니다.
Dan Nissenbaum

... 응답 아래 주석의 jQuery 플러그인은 개별 요소에 대한 별도의 타이머를 처리하고 스로틀 및 이벤트 인수도 추가합니다 : github.com/bgrins/bindWithDelay/blob/master/bindWithDelay.js. 해당 플러그인의 일반적인 접근 방식은 코드와 동일하므로보다 정교한 플러그인을 이해하기 전에 코드의 단순성을 이해하기 위해 코드를주의 깊게 연구해야합니다. 플러그인을 권장하지만 스로틀이나 이벤트 데이터 전달이 필요하지 않으면 코드가 훌륭합니다! 두 가지 좋은 옵션. 감사!
Dan Nissenbaum

1
흠, 그것은 나를 지연 시키지만 someApiCall여전히 여러 번 트리거합니다-이제 입력 필드의 최종 값으로.
Roelant


14

CMS의 답변을 바탕으로 다음과 같이했습니다.

jQuery를 포함시킨 후 아래 코드를 입력하십시오.

/*
 * delayKeyup
 * http://code.azerti.net/javascript/jquery/delaykeyup.htm
 * Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
 * Written by Gaten
 * Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
 */
(function ($) {
    $.fn.delayKeyup = function(callback, ms){
        var timer = 0;
        $(this).keyup(function(){                   
            clearTimeout (timer);
            timer = setTimeout(callback, ms);
        });
        return $(this);
    };
})(jQuery);

그리고 간단히 다음과 같이 사용하십시오 :

$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);

주의 : 매개 변수로 전달 된 함수의 $ (this) 변수가 입력과 일치하지 않습니다


12

레이블을 사용하여 다기능 호출 지연

이것이 내가 작업하는 솔루션입니다. 원하는 모든 함수에서 실행이 지연됩니다 . 키 다운 검색 쿼리 일 수도 있고 이전 또는 다음 버튼을 빠르게 클릭 할 수도 있습니다 (계속해서 계속 클릭하면 여러 요청을 보내고 결국 사용되지 않음). 각 실행 시간을 저장하고 최신 요청과 비교하는 전역 객체를 사용합니다.

결과적으로 해당 요청이 대기열에 저장되기 때문에 마지막 클릭 / 액션 만 실제로 호출됩니다. 동일한 레이블을 가진 다른 요청이 대기열에 없으면 X 밀리 초 후에 호출됩니다!

function delay_method(label,callback,time){
    if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}  
    delayed_methods[label]=Date.now();
    var t=delayed_methods[label];
    setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{  delayed_methods[label]=""; callback();}}, time||500);
  }

자체 지연 시간을 설정할 수 있습니다 (선택 사항, 기본값은 500ms). 그리고 함수 인수를 "클로저 방식"으로 보내십시오.

예를 들어 다음 함수를 호출하려는 경우 :

function send_ajax(id){console.log(id);}

여러 send_ajax 요청을 방지하려면 다음을 사용하여 요청을 지연하십시오 .

delay_method( "check date", function(){ send_ajax(2); } ,600);

"체크 날짜"레이블을 사용하는 모든 요청은 600 밀리 초 기간 동안 다른 요청이없는 경우에만 트리거됩니다. 이 인수는 선택 사항입니다

독립성을 레이블 지정 (동일한 대상 함수 호출)하지만 둘 다 실행하십시오.

delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});

동일한 함수를 호출하지만 레이블이 다르기 때문에 독립적으로 지연시킵니다.


작업중 인 프로젝트에서 코드를 사용하고 있으며 어려움을 겪고 있습니다. 실제로 아무것도 지연시키지 않습니다. 도움을 보거나 제공 할 수 있다고 생각했습니다. stackoverflow.com/questions/51393779/…
KDJ

10

사용자가 텍스트 필드에 입력을 마친 후에 기능을 실행하도록 설계된 매우 간단한 접근 방식 ...

<script type="text/javascript">
$(document).ready(function(e) {
    var timeout;
    var delay = 2000;   // 2 seconds

    $('.text-input').keyup(function(e) {
        console.log("User started typing!");
        if(timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            myFunction();
        }, delay);
    });

    function myFunction() {
        console.log("Executing function for user!");
    }
});
</script>

<textarea name="text-input" class="text-input"></textarea>

1
감사합니다! 위의 인기있는 답변은 효과가 없었지만 귀하의 제안은 완벽하게 작동했습니다.
user2662680

1
2020 년 여전히 작동
Romel Indemne

9

누군가가 동일한 기능을 지연시키고 외부 변수가 없으면 다음 스크립트를 사용할 수 있습니다.

function MyFunction() {

    //Delaying the function execute
    if (this.timer) {
        window.clearTimeout(this.timer);
    }
    this.timer = window.setTimeout(function() {

        //Execute the function code here...

    }, 500);
}

1
큰! 잘 작동하는 쉬운 솔루션!
Fellipe Sanches

1
난이게 좋아. 정확하게 재사용 할 수는 없지만 이해하기 쉽습니다.
빈센트

7

이 함수는 Gaten의 답변에서 함수를 약간 확장하여 요소를 다시 가져옵니다.

$.fn.delayKeyup = function(callback, ms){
    var timer = 0;
    var el = $(this);
    $(this).keyup(function(){                   
    clearTimeout (timer);
    timer = setTimeout(function(){
        callback(el)
        }, ms);
    });
    return $(this);
};

$('#input').delayKeyup(function(el){
    //alert(el.val());
    // Here I need the input element (value for ajax call) for further process
},1000);

http://jsfiddle.net/Us9bu/2/


6

CMS의 여러 입력에 대한 문제를 아무도 언급하지 않았다는 사실에 놀랐습니다.

기본적으로 각 입력에 대해 지연 변수를 개별적으로 정의해야합니다. 그렇지 않으면 SB가 텍스트를 첫 번째 입력에 넣고 다른 입력으로 빠르게 이동하여 입력을 시작하면 첫 번째 입력에 대한 콜백 이 호출 되지 않습니다 !

다른 답변을 바탕으로 함께 제공된 아래 코드를 참조하십시오.

(function($) {
    /**
     * KeyUp with delay event setup
     * 
     * @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
     * @param function callback
     * @param int ms
     */
    $.fn.delayKeyup = function(callback, ms){
            $(this).keyup(function( event ){
                var srcEl = event.currentTarget;
                if( srcEl.delayTimer )
                    clearTimeout (srcEl.delayTimer );
                srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
            });

        return $(this);
    };
})(jQuery);

이 솔루션은 setTimeout 참조를 입력의 delayTimer 변수 내에 유지합니다. 또한 fazzyx가 제안한대로 요소 참조를 콜백에 전달합니다.

IE6, 8 (comp-7), 8 및 Opera 12.11에서 테스트되었습니다.


이것을 시도했지만 첫 번째 키업에서 제대로 작동하지 않습니다.
Lars Thorén

6

이것은 검색 논리 작업을 지연시키고 텍스트 필드에 입력 한 값과 동일한 지 확인하는 곳에서 효과적이었습니다. 값이 같으면 검색 값과 관련된 데이터에 대한 작업을 수행합니다.

$('#searchText').on('keyup',function () {
    var searchValue = $(this).val();
    setTimeout(function(){
        if(searchValue == $('#searchText').val() && searchValue != null && searchValue != "") {
           // logic to fetch data based on searchValue
        }
        else if(searchValue == ''){
           // logic to load all the data
        }
    },300);
});

예상대로 작동하지 않습니다-페치 횟수는 300ms만큼 지연됩니다. setTimeout ()을 실행하기 전에 모든 키 입력에서 clearTimeout () 함수를 사용해야합니다.
Picard

이 경우 clearTimeout을 사용할 필요가 없습니다. setTimeout 내의 searchValue == $ ( '# searchText'). val () 조건은 값이 300ms 전과 같은지 확인합니다. 이것이 의미가 있는지 알려주십시오. 감사.
Sagar Gala

4

모든 키업을 호출하는 지연 기능. jQuery 1.7.1 이상 필요

jQuery.fn.keyupDelay = function( cb, delay ){
  if(delay == null){
    delay = 400;
  }
  var timer = 0;
  return $(this).on('keyup',function(){
    clearTimeout(timer);
    timer = setTimeout( cb , delay );
  });
}

용법: $('#searchBox').keyupDelay( cb );


3

이것은 CMS 라인을 따르는 솔루션이지만 몇 가지 주요 문제를 해결합니다.

  • 여러 입력을 지원하며 지연을 동시에 실행할 수 있습니다.
  • 값을 변경하지 않은 주요 이벤트 (예 : Ctrl, Alt + Tab)를 무시합니다.
  • 경쟁 조건을 해결합니다 (콜백이 실행되고 값이 이미 변경된 경우).
var delay = (function() {
    var timer = {}
      , values = {}
    return function(el) {
        var id = el.form.id + '.' + el.name
        return {
            enqueue: function(ms, cb) {
                if (values[id] == el.value) return
                if (!el.value) return
                var original = values[id] = el.value
                clearTimeout(timer[id])
                timer[id] = setTimeout(function() {
                    if (original != el.value) return // solves race condition
                    cb.apply(el)
                }, ms)
            }
        }
    }
}())

용법:

signup.key.addEventListener('keyup', function() {
    delay(this).enqueue(300, function() {
        console.log(this.value)
    })
})

코드는 내가 좋아하는 스타일로 작성되었으므로 세미콜론을 추가해야 할 수도 있습니다.

명심해야 할 사항 :

  • 고유 ID는 양식 ID 및 입력 이름을 기반으로 생성되므로 정의되고 고유해야하거나 상황에 맞게 조정할 수 있습니다.
  • 지연 은 자신의 필요에 따라 쉽게 확장 할 수있는 객체를 반환합니다.
  • 지연에 사용 된 원래 요소는 콜백에 바인딩되므로 this 예와 같이 예상대로 작동합니다.
  • 두 번째 유효성 검사에서는 빈 값이 무시됩니다.
  • enqueue를 조심 하십시오. 밀리 초가 먼저 필요합니다. 선호하지만 매개 변수를 일치하도록 전환 할 수 있습니다 setTimeout.

내가 사용하는 솔루션은 다른 수준의 복잡성을 추가하여 실행을 취소 할 수 있지만 예를 들어 구축하기에 좋은 기반입니다.


3

CMS 답변Miguel의 답변 을 결합하면 동시 지연을 허용하는 강력한 솔루션을 얻을 수 있습니다.

var delay = (function(){
    var timers = {};
    return function (callback, ms, label) {
        label = label || 'defaultTimer';
        clearTimeout(timers[label] || 0);
        timers[label] = setTimeout(callback, ms);
    };
})();

다른 조치를 독립적으로 지연해야하는 경우 세 번째 인수를 사용하십시오.

$('input.group1').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, 'firstAction');
});

$('input.group2').keyup(function() {
    delay(function(){
        alert('Time elapsed!');
    }, 1000, '2ndAction');
});

3

CMS의 답변을 바탕으로 사용시 'this'를 유지하는 새로운 지연 방법이 있습니다.

var delay = (function(){
  var timer = 0;
  return function(callback, ms, that){
    clearTimeout (timer);
    timer = setTimeout(callback.bind(that), ms);
  };
})();

용법:

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000, this);
});

2

사용하다

mytimeout = setTimeout( expression, timeout );

여기서 expression은 실행할 스크립트이고 timeout은 실행되기 전에 밀리 초 단위로 대기하는 시간입니다. 스크립트가 실행되지는 않지만 시간 초과가 완료 될 때까지 해당 부분의 실행이 지연됩니다.

clearTimeout(mytimeout);

스크립트가 아직 실행되지 않은 한 (예 : 취소) 표현식에서 스크립트를 실행하지 않도록 시간 초과를 재설정 / 지 웁니다.


2

CMS의 답변에 따라 가치를 변경하지 않는 주요 이벤트는 무시합니다.

var delay = (function(){
    var timer = 0;
    return function(callback, ms){
      clearTimeout (timer);
      timer = setTimeout(callback, ms);
    };
})(); 

var duplicateFilter=(function(){
  var lastContent;
  return function(content,callback){
    content=$.trim(content);
    if(content!=lastContent){
      callback(content);
    }
    lastContent=content;
  };
})();

$("#some-input").on("keyup",function(ev){

  var self=this;
  delay(function(){
    duplicateFilter($(self).val(),function(c){
        //do sth...
        console.log(c);
    });
  }, 1000 );


})


1
var globalTimeout = null;  
$('#search').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
});
function SearchFunc(){  
  globalTimeout = null;  
  console.log('Search: '+$('#search').val());
  //ajax code
};

1

다음은 귀하의 양식에 여러 입력을 처리하는 제안입니다.

이 함수는 입력 필드의 객체를 가져와 코드에 넣습니다.

function fieldKeyup(obj){
    //  what you want this to do

} // fieldKeyup

이것은 실제 delayCall 함수이며 여러 입력 필드를 처리합니다.

function delayCall(obj,ms,fn){
    return $(obj).each(function(){
    if ( typeof this.timer == 'undefined' ) {
       // Define an array to keep track of all fields needed delays
       // This is in order to make this a multiple delay handling     
          function
        this.timer = new Array();
    }
    var obj = this;
    if (this.timer[obj.id]){
        clearTimeout(this.timer[obj.id]);
        delete(this.timer[obj.id]);
    }

    this.timer[obj.id] = setTimeout(function(){
        fn(obj);}, ms);
    });
}; // delayCall

용법:

$("#username").on("keyup",function(){
    delayCall($(this),500,fieldKeyup);
});

1

ES6 부터 화살표 함수 구문 도 사용할 수 있습니다 .

이 예제에서 코드는 keyup사용자가 입력을 마치고 searchFunc쿼리 요청을 하기 전에 400ms 동안 이벤트를 지연시킵니다 .

const searchbar = document.getElementById('searchBar');
const searchFunc = // any function

// wait ms (milliseconds) after user stops typing to execute func
const delayKeyUp = (() => {
    let timer = null;
    const delay = (func, ms) => {
        timer ? clearTimeout(timer): null
        timer = setTimeout(func, ms)
    }
    return delay
})();

searchbar.addEventListener('keyup', (e) => {
    const query = e.target.value;
    delayKeyUp(() => {searchFunc(query)}, 400);
})

1

jQuery :

var timeout = null;
$('#input').keyup(function() {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
      console.log($(this).val());
  }, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<input type="text" id="input" placeholder="Type here..."/>

순수한 자바 스크립트 :

let input = document.getElementById('input');
let timeout = null;

input.addEventListener('keyup', function (e) {
    clearTimeout(timeout);
    timeout = setTimeout(function () {
        console.log('Value:', input.value);
    }, 1000);
});
<input type="text" id="input" placeholder="Type here..."/>


0

자동 완성 플러그인을 살펴보십시오 . 지연 또는 최소 문자 수를 지정할 수 있음을 알고 있습니다. 플러그인을 사용하지 않아도 코드를 살펴보면 직접 구현하는 방법에 대한 아이디어를 얻을 수 있습니다.


0

글쎄, Keyup / Keydown으로 인한 고주파수 아약스 요청을 제한하기위한 코드도 만들었습니다. 이것 좀 봐:

https://github.com/raincious/jQueue

다음과 같이 쿼리를 수행하십시오.

var q = new jQueue(function(type, name, callback) {
    return $.post("/api/account/user_existed/", {Method: type, Value: name}).done(callback);
}, 'Flush', 1500); // Make sure use Flush mode.

그리고 다음과 같이 이벤트를 바인딩하십시오.

$('#field-username').keyup(function() {
    q.run('Username', this.val(), function() { /* calling back */ });
});

0

오늘 이것을 조금 늦게 보았지만 다른 누군가가 필요할 때를 대비하여 여기에 넣고 싶습니다. 재사용 할 수 있도록 함수를 분리하십시오. 아래 코드는 stop을 입력 한 후 1/2 초 동안 기다립니다.

    var timeOutVar
$(selector).on('keyup', function() {

                    clearTimeout(timeOutVar);
                    timeOutVar= setTimeout(function(){ console.log("Hello"); }, 500);
                });

0

사용자 lodash 자바 스크립트 라이브러리 및 _.debounce 함수 사용

changeName: _.debounce(function (val) {
  console.log(val)                
}, 1000)

0
// Get an global variable isApiCallingInProgress

//  check isApiCallingInProgress 
if (!isApiCallingInProgress) {
// set it to isApiCallingInProgress true
      isApiCallingInProgress = true;

      // set timeout
      setTimeout(() => {
         // Api call will go here

        // then set variable again as false
        isApiCallingInProgress = false;     
      }, 1000);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.