백 스페이스 키가 다시 탐색되지 않도록하려면 어떻게해야합니까?


275

IE에서는 (아주 비표준이지만 작동하는) jQuery 로이 작업을 수행 할 수 있습니다

if ($.browser.msie)
    $(document).keydown(function(e) { if (e.keyCode == 8) window.event.keyCode = 0;});

그러나 Firefox에서 작동하는 방식으로 또는 보너스를 위해 크로스 브라우저 방식으로 할 수 있습니까?

기록을 위해 :

$(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); });

아무것도하지 않습니다.

$(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); });

문제를 해결하지만 페이지에서 백 스페이스 키를 사용할 수 없게합니다. 이는 원래 동작보다 훨씬 나쁩니다.

편집 : 내가 이것을하는 이유는 간단한 웹 페이지가 아니라 큰 응용 프로그램을 만들고 있기 때문입니다. 잘못된 장소에서 백 스페이스를 눌렀 기 때문에 10 분의 작업 시간을 잃는 것은 매우 성가신 일입니다. 백 스페이스 키가 다시 탐색되지 않도록하여 실수 방지와 성가신 사용자 방지 비율은 1000/1 이상이어야합니다.

EDIT2 : 나는 역사 탐색을 막기 위해 노력 하지 않고 단지 사고 만합니다.

EDIT3 : @brentonstrines comment (질문이 너무 인기가 있기 때문에 여기로 이동) : 이것은 장기적인 수정 사항이지만 웹킷 에서이 동작을 변경하기 위해 Chromium 버그 뒤에 지원을 던질 수 있습니다


137
백 스페이스 키가 오버로드 되었기 때문입니다. 눈치 채지 못했을 수도 있지만 텍스트 필드에 방금 입력 한 문자를 지우는 데 항상 사용할 수도 있습니다. 내 고객 중 일부가 페이지를 다시 가져 오는 데 문제가있어 유용한 정보입니다. 아무도하지만 광대 백 스페이스는 것을 알고 가정 페이지를 돌아갑니다. 그것은 내가 전혀 몰랐던 일이며, 브라우저가 가지고있는 것은 명백한 적대적인 행동입니다. 모든 페이지에서 해당 동작을 비활성화해야한다고 생각합니다.
Breton

80
사람들이 왜 이것이 이상하다고 생각합니까? 탐색에 백 스페이스를 사용하는 것은 정말 바보 같은 단축키입니다! 사용자가 텍스트를 삭제할 수있는 텍스트 필드가 너무 많습니다 .SO 답변이 길고 다른 창으로 전환하여 무언가를 확인한 다음 다시 돌아와서 편집 영역을 잘못 클릭하고 백 스페이스를 눌러 단어를 제거하고 갑자기 브라우저가 페이지로 돌아가서 방금 작성한 모든 내용을 잃어 버릴 수 있습니다.
Peter Boughton

57
왜 내가 이것을하고 싶어? 웹 사이트가 아닌 웹 응용 프로그램을 만들고 있습니다. 일부 입력 필드는 읽기 전용이며이 경우 편집 가능한 것처럼 보이지만 백 스페이스 키를 누르면 페이지를 떠납니다. 삭제 뭔가하려고 탐색 백 대 백 스페이스 프레스하려는 백 스페이스 프레스의 비율은 훨씬 적은 1 / 1000보다 아마
erikkallen

42
문제는 이것이 좋은 아이디어인지 아닌지에 대한 당신의 의견이 아니라 이것을하는 방법입니다. 프로젝트의 세부 사항을 알지 못하면 귀하의 의견은 의미가 없습니다. 내 고객이 내 프로젝트 중 하나에 대해이 동작을 구체적으로 요청했으며 "왜 그렇게 하시겠습니까?" 도움이 될 것입니다.
없음

7
이것은 장기적인 '수정'이지만 웹킷에서이 동작을 변경하기 위해 Chromium 버그 뒤에 지원을 던질 수 있습니다. code.google.com/p/chromium/issues/detail?id=144832
brentonstrine

답변:


335

이 코드는 적어도 IE와 Firefox에서 문제를 해결합니다 (다른 테스트는하지 않았지만 다른 브라우저에서도 문제가 발생하면 합리적으로 작동 할 수 있습니다).

// Prevent the backspace key from navigating back.
$(document).unbind('keydown').bind('keydown', function (event) {
    if (event.keyCode === 8) {
        var doPrevent = true;
        var types = ["text", "password", "file", "search", "email", "number", "date", "color", "datetime", "datetime-local", "month", "range", "search", "tel", "time", "url", "week"];
        var d = $(event.srcElement || event.target);
        var disabled = d.prop("readonly") || d.prop("disabled");
        if (!disabled) {
            if (d[0].isContentEditable) {
                doPrevent = false;
            } else if (d.is("input")) {
                var type = d.attr("type");
                if (type) {
                    type = type.toLowerCase();
                }
                if (types.indexOf(type) > -1) {
                    doPrevent = false;
                }
            } else if (d.is("textarea")) {
                doPrevent = false;
            }
        }
        if (doPrevent) {
            event.preventDefault();
            return false;
        }
    }
});

6
비밀번호 필드를 끊습니다.
Hemlock

7
Hemlock이 언급했듯이 확인하십시오 d.type.toUpperCase() === 'PASSWORD'. 그렇지 않으면 좋아 보인다
stevendesu 2016 년

17
이미 jQuery를 사용하고 있으므로if( $(d).is( ":input" ) )...
Paul Alexander

23
이것은 "뒤로"기능을 블랙리스트 할 수있는 것이 아니라 화이트리스트 여야한다는 것을 짜증나게합니다. d.isContentEditable여기에 수표를 추가 할 수 있습니다.
iono

3
: 나는 현재 허용 대답의 깨끗한 버전으로 NPM 프로젝트를 생성 github.com/slorber/backspace-disabler가 (그것도 contenteditables을 지원하고 종속성이 없습니다)
세바스티앙 Lorber을

62

이 코드는 모든 브라우저에서 작동하며 양식 요소에 없거나 양식 요소가 비활성화되어있는 경우 백 스페이스 키를 삼킨다. 또한 입력하는 모든 키에서 실행될 때 중요합니다.

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});

1
내 예제를 테스트하십시오. 코드를 적절하게 업데이트 할 수 있습니다.
Biff MaGriff

10
더 깨끗하기 때문에 @erikkallen의 솔루션보다 이것을 선호합니다. 그러나 제출 버튼, 라디오 버튼 및 확인란도 무시하기를 원했기 때문에 if ()를 다음과 같이 변경했습니다.if(!rx.test(e.target.tagName) || $(e.target).is(':checkbox') || $(e.target).is(':radio') || $(e.target).is(':submit') || e.target.disabled || e.target.readOnly )
Matthew Clark

@ thetoolman, erikallen의 답변에 대한 내 의견을 참조하십시오. 이 또한 설명해야합니다 contentEditable.
jolt

10
@MaffooClock : 당신은 더 간결 할 수 있습니다.is(':checkbox,:radio,:submit')
cdmckay

1
@ cdmckay : 처음에는 그런 식으로 쓰지 않았다는 것을 믿을 수 없습니다. 우리 모두를 위해 청소 해 주셔서 감사합니다 :)
Matthew Clark

41

다른 답변은 백 스페이스가 허용되는 요소를 화이트리스트에 올리지 않으면이 작업을 수행 할 수 없다는 것을 입증했습니다. 화이트리스트는 단순한 텍스트 영역 및 텍스트 / 암호 입력만큼 간단하지는 않지만 반복적으로 불완전하고 업데이트가 필요하기 때문에이 솔루션은 이상적이지 않습니다.

그러나 백 스페이스 기능을 억제하는 목적은 사용자가 실수로 데이터를 잃는 것을 방지하기위한 것이므로 사전 언로드 솔루션은 모달 팝업이 놀랍기 때문에 좋은 솔루션입니다. 모달 팝업은 표준 워크 플로의 일부로 트리거 될 때 좋지 않습니다. 사용자가 읽지 않고 해제하는 데 익숙해지기 때문에 성가시다. 이 경우 모달 팝업은 희귀하고 놀라운 작업에 대한 대안으로 만 나타나므로 허용됩니다.

문제는 사용자가 링크를 클릭하거나 양식을 제출할 때와 같이 페이지에서 벗어날 때마다 onbeforeunload 모달이 팝업되어서는 안되며 특정 onbeforeunload 조건을 허용 목록 또는 차단 목록에 포함하고 싶지 않다는 것입니다.

일반화 된 솔루션에 대한 트레이드 오프의 이상적인 조합은 다음과 같습니다. 백 스페이스를 눌렀는지 여부를 추적하고 onloadforload 모달이있는 경우에만 팝업합니다. 다시 말해:

function confirmBackspaceNavigations () {
    // http://stackoverflow.com/a/22949859/2407309
    var backspaceIsPressed = false
    $(document).keydown(function(event){
        if (event.which == 8) {
            backspaceIsPressed = true
        }
    })
    $(document).keyup(function(event){
        if (event.which == 8) {
            backspaceIsPressed = false
        }
    })
    $(window).on('beforeunload', function(){
        if (backspaceIsPressed) {
            backspaceIsPressed = false
            return "Are you sure you want to leave this page?"
        }
    })
} // confirmBackspaceNavigations

이것은 IE7 +, FireFox, Chrome, Safari 및 Opera에서 작동하도록 테스트되었습니다. 이 함수를 global.js에 드롭하고 사용자가 실수로 데이터를 잃지 않기를 원하는 페이지에서 호출하십시오.

온로드로드 모달은 한 번만 트리거 될 수 있으므로 사용자가 백 스페이스를 다시 누르면 모달이 다시 시작되지 않습니다.

이것은 해시 체인지 이벤트에서 트리거되지는 않지만 다른 컨텍스트를 사용하여 사용자가 실수로 데이터를 잃지 않도록 할 수 있습니다.


2
방금 동일한 솔루션을 추가하고 LOL 페이지 하단 에서이 게시물을 보았습니다. 내가 가지고있는 한 가지 차이점은 return "Are you sure ..."문 전에 lastUserInputWasBackspace = false를 설정하는 것이므로 이미 팝업을 본 후 뒤로 버튼을 클릭하면 팝업이 표시되지 않습니다. 백 스페이스에 영향을 미치는 행동).
David Russell

1
@ user2407309 귀하의 솔루션으로 작동하지 않는 firefox에 대한 내 의견 (불만)이 제거되었습니다. 내 디버거에 문제가있었습니다. 코드 편집 / 중단에 대해 사과드립니다. 나는 내가 한계를 넘어 섰다는 것을 깨닫고있다. 정말 죄송합니다.이 문제에 대한 귀하의 훌륭한 해결책에 대한 불만은 없습니다. 다시 한번 사과드립니다. 이 코드는 잘 작동합니다. 이것이 최선의 답변이라고 믿습니다.
Charles Byrne

1
이 솔루션은 로컬 컴퓨터에서 작동했지만 이동했을 때 클라이언트 (적어도 일부)는 응용 프로그램의 절반 기능을 잃었습니다. 나는 무언가가 그것을 거부하고 있다고 생각하지만, 나는 무엇을 모른다.
Steve

1
@Steve, 드물거나, 함수에 문제가있는 경우 해당 정보가 여기에 속합니다. 나는 정말로 문제가 있는지 알고 싶습니다.
Vladimir Kornea

1
좋은 해결책이지만 불행히도 사용자가 실수로 백 스페이스를 두 번 누르면 여전히 뒤로 탐색합니다. (적어도 firefox에서)
Remco de Zwart

26

보다 우아하고 간결한 솔루션 :

$(document).on('keydown',function(e){
  var $target = $(e.target||e.srcElement);
  if(e.keyCode == 8 && !$target.is('input,[contenteditable="true"],textarea'))
  {
    e.preventDefault();
  }
})

1
이것은 훨씬 간결하며 내가 말할 수있는 것뿐만 아니라 작동합니다. 가장 인기있는 답변이 모든 유형의 입력을 검사하고 더 복잡한 것처럼 보이는 이유는 무엇입니까? 더 신뢰할 수 있습니까?
Nearpoint

1
가장 인기있는 답변은 질문에 대한 첫 번째 답변이므로 높은 투표였습니다.
Darwayne

4
읽기 전용 필드가 집중 삭제 정지를 탐색이 때 크롬에서 백업
윌 D

16

다른 입력 유형을 처리하기위한 erikkallen의 답변 수정

나는 진취적인 사용자가 체크 박스 또는 라디오 버튼의 백 스페이스를 헛되이 지우려고 시도했지만 대신 뒤로 탐색하고 모든 데이터를 잃을 수 있음을 발견했습니다.

이 변경은 해당 문제를 해결해야합니다.

컨텐츠 편집 가능한 div를 해결하기위한 새로운 편집

    //Prevents backspace except in the case of textareas and text inputs to prevent user navigation.
    $(document).keydown(function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            switch (d.tagName.toUpperCase()) {
                case 'TEXTAREA':
                    preventKeyPress = d.readOnly || d.disabled;
                    break;
                case 'INPUT':
                    preventKeyPress = d.readOnly || d.disabled ||
                        (d.attributes["type"] && $.inArray(d.attributes["type"].value.toLowerCase(), ["radio", "checkbox", "submit", "button"]) >= 0);
                    break;
                case 'DIV':
                    preventKeyPress = d.readOnly || d.disabled || !(d.attributes["contentEditable"] && d.attributes["contentEditable"].value == "true");
                    break;
                default:
                    preventKeyPress = true;
                    break;
            }
        }
        else
            preventKeyPress = false;

        if (preventKeyPress)
            e.preventDefault();
    });

예제
2 개의 파일을 테스트합니다.

starthere.htm-처음 열면 다시 갈 곳이 생깁니다.

<a href="./test.htm">Navigate to here to test</a>

test.htm-체크 박스 또는 제출에 포커스가있는 동안 백 스페이스를 누르면 뒤로 이동합니다 (탭하여 달성). 수정하려면 내 코드로 바꾸십시오.

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

    $(document).keydown(function(e) {
        var doPrevent;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (d.tagName.toUpperCase() == 'INPUT' || d.tagName.toUpperCase() == 'TEXTAREA') {
                doPrevent = d.readOnly || d.disabled;
            }
            else
                doPrevent = true;
        }
        else
            doPrevent = false;

        if (doPrevent)
            e.preventDefault();
    });
</script>
</head>
<body>
<input type="text" />
<input type="radio" />
<input type="checkbox" />
<input type="submit" />
</body>
</html>

radio | checkbox | submit-> back 기능에서 어떤 브라우저가 백 스페이스 프레스를 보았습니까? 브라우저가이 작업을 수행하는 것을 보지
못했습니다

Internet Explorer 8 및 Chrome
Biff MaGriff

2
이 스레드에서 여러 가지 다른 솔루션을 시도했지만이 상황은 모든 상황에서 잘 작동했으며 가장 깨끗하고 이해하기 쉬운 코드를 가지고있었습니다. 감사합니다.
Ezward

@Darwayne을 사용해 보셨습니까? 왜 그렇게 짧고 이것이 더 복잡한 지 궁금합니다.하지만 둘 다 나
에게도

링크에서 작동합니까? 항목을 제거하기 위해 이미지 버튼이있는 ASP.Net 응용 프로그램이 있습니다. 이것이 지금까지 작동하지 않은 유일한 방법입니다.
Steve

8

주석을 기반으로 삭제하기 위해 백 스페이스를 눌렀지만 필드에 초점이 맞지 않으면 양식에서 정보를 잃는 사람들을 막으려는 것으로 나타납니다.

이 경우 onunload 이벤트 핸들러 를 보려고 합니다. 스택 오버플로에서이를 사용합니다. 답변을 작성하기 시작할 때 페이지를 떠나려고하면 경고 메시지가 나타납니다.


4
무례한 의견이었습니다. 내 말은, 사용자는 자신이 알지도 못했던 일을 저지르고 싶었을 가능성이 높다는 것입니다. 왜 키를 조용히 키로 먹지 않겠습니까? 사용자가 페이지를 떠나는 것을 완전히 막는 것이 아니라이 일반적인 실수를 막는 것이 목표입니다. 또한 팝업 대화는 효과적이지 않거나 유용하지 않습니다. 사용자는 읽지 않습니다. 페이지를 떠나시겠습니까? 괜찮아! 기다릴 필요가 없습니다. 페이지를 떠나고 싶지 않았습니다. 너무 늦었습니다.
Breton

3
그런 다음 가져 가거나 그대로 두십시오. 실제로 존재하지 않거나 적어도 중요하지 않은 문제를 과도하게 엔지니어링하려고한다고 생각합니다. 내 경험상, 익숙하지 않은 대화 상자를 제대로 읽지 않고 "확인"을 클릭하는 것은 고급 사용자 일뿐입니다. ;)
DisgruntledGoat

3
당신과 브르타뉴 어는 같은 사람입니까? 어쨌든 당신은 거기에 발을 들여 놓았습니다. 기사에는 "기본 대답은 취소입니다"라고 표시되어 있으므로 페이지를 떠나는 것에 대한 대화 상자를 볼 때 "취소"를 눌러 페이지를 떠나지 않습니다 . 해당 대화 상자에서 Chrome의 옵션은 '이 페이지를 떠나기'와 '이 페이지를 그대로 유지하십시오'라는 점에 유의해야합니다.
DisgruntledGoat

1
아니, 그는 내가 아니지만 나는 그 링크를 전에 본 적이있다. 나는 그 의견이 유쾌하다고 생각한다. "무엇!? 사람들은 모달 대화 상자를 무시합니까? 더 지속적이고 성가신 방법을 찾아야합니다!" Microsoft 소프트웨어에 대해 많은 것을 설명합니다.
Breton

3
@ Disgruntled : 아니요, 저는 Breton이 아니며 기사의 요점은 "기본 선택은 ..."이 아니라 "사용자는 아무것도 읽지 않습니다"입니다.
erikkallen

7

이 코드 탐색을 중지하십시오!

$(document).on("keydown", function (event) {        
   if (event.keyCode === 8) {
      event.preventDefault();
    }
  });

그러나 텍스트 필드를 제한하지 않고 다른 필드를 제한하기 위해

$(document).on("keydown", function (event) {
  if (event.which === 8 && !$(event.target).is("input, textarea")) {
   event.preventDefault();
  }
});

특정 분야에서 사용하지 않으려면 간단히 사용하십시오.

$('#myOtherField').on("keydown", function (event) {
  if (event.keyCode === 8 || event.which === 8) { 
   event.preventDefault(); 
  } 
});

아래 이것을 참조하십시오!

BACKSPACE가 jQuery를 사용하여 다시 탐색하지 못하도록 방지 (Google 홈페이지처럼)


7

대부분의 답변은 jquery에 있습니다. 순수 Javascript로 완벽하게 수행 할 수 있으며 간단하고 라이브러리가 필요하지 않습니다. 기사는 저에게 좋은 출발점 이었지만 keyIdentifier 는 더 이상 사용되지 않기 때문에이 코드가 더 안전 해지기를 원했기 때문에 if 문 에 || e.keyCode == 8 을 추가했습니다 . 또한 코드가 Firefox에서 제대로 작동하지 않으므로 return false를 추가했습니다 . 이제는 완벽하게 작동합니다. 여기있어:

<script type="text/javascript">
window.addEventListener('keydown',function(e){if(e.keyIdentifier=='U+0008'||e.keyIdentifier=='Backspace'||e.keyCode==8){if(e.target==document.body){e.preventDefault();return false;}}},true);
</script>

이 코드는 훌륭하게 작동합니다.

  1. 순수 자바 스크립트로되어 있습니다 (라이브러리 필요 없음).
  2. 키를 눌렀는지 확인할뿐만 아니라 작업이 실제로 브라우저 "뒤로"작업인지 확인합니다.
  3. 위와 함께 사용자는 웹 페이지의 입력 텍스트 상자에서 텍스트를 입력하고 삭제해도 아무런 문제없이 뒤로 단추 동작을 방지 할 수 있습니다.
  4. 짧고 깨끗하며 빠르고 정확합니다.

console.log (e);를 추가 할 수 있습니다. 테스트 목적으로 크롬에서 F12 키를 누르고 "콘솔"탭으로 이동하여 페이지에서 "백 스페이스"를 누르고 내부를 살펴보고 어떤 값이 반환되는지 확인한 다음 해당 매개 변수를 모두 타겟팅하여 코드를 더욱 향상시킬 수 있습니다 당신의 필요에 맞게 위.


6

"thetoolman"&& "Biff MaGriff"가 제공하는 솔루션 결합

다음 코드는 IE 8 / Mozilla / Chrome에서 올바르게 작동하는 것 같습니다

$(function () {
    var rx = /INPUT|TEXTAREA/i;
    var rxT = /RADIO|CHECKBOX|SUBMIT/i;

    $(document).bind("keydown keypress", function (e) {
        var preventKeyPress;
        if (e.keyCode == 8) {
            var d = e.srcElement || e.target;
            if (rx.test(e.target.tagName)) {
                var preventPressBasedOnType = false;
                if (d.attributes["type"]) {
                    preventPressBasedOnType = rxT.test(d.attributes["type"].value);
                }
                preventKeyPress = d.readOnly || d.disabled || preventPressBasedOnType;
            } else {preventKeyPress = true;}
        } else { preventKeyPress = false; }

        if (preventKeyPress) e.preventDefault();
    });
}); 

IMAGE를 추가하는 것도 유용 할 수 있습니다.
mrswadge

나는 이것에 정착했다.
코 렌틴

5

왜 아무도이 질문에 대답하지 않았는지 확실하지 않습니다. 가능한지 묻는 완벽한 기술적 인 질문처럼 보입니다.

아니요, 백 스페이스 버튼을 비활성화하는 크로스 브라우저 방법이 없다고 생각합니다. 요즘 FF에서는 기본적으로 활성화되어 있지 않습니다.


3
실제 질문에 대답하지 않고 시간을 낭비한 것에 대한 빼기 1
Andrew

3

이 솔루션은 게시 된 다른 솔루션과 유사하지만 간단한 화이트리스트를 사용하여 .is () 함수에서 선택기를 설정하기 만하면 지정된 요소에서 백 스페이스를 허용하도록 쉽게 사용자 정의 할 수 있습니다.

페이지의 백 스페이스가 다시 탐색되지 않도록이 형식으로 사용합니다.

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input:not([readonly]), textarea")) {
        e.preventDefault();
    }
});

2
사용자가 contenteditable을 사용하면 콘텐츠가 비활성화됩니다. 따라서 화이트리스트에 contenteditable = true를 추가하고 싶을 수도 있습니다.
Miguel

3

@erikkallen의 훌륭한 답변을 약간 자세히 설명하기 위해 HTML5에 도입 된 것을 포함하여 모든 키보드 기반 입력 유형을 허용하는 기능이 있습니다 .

$(document).unbind('keydown').bind('keydown', function (event) {
    var doPrevent = false;
    var INPUTTYPES = [
        "text", "password", "file", "date", "datetime", "datetime-local",
        "month", "week", "time", "email", "number", "range", "search", "tel",
        "url"];
    var TEXTRE = new RegExp("^" + INPUTTYPES.join("|") + "$", "i");
    if (event.keyCode === 8) {
        var d = event.srcElement || event.target;
        if ((d.tagName.toUpperCase() === 'INPUT' && d.type.match(TEXTRE)) ||
             d.tagName.toUpperCase() === 'TEXTAREA') {
            doPrevent = d.readOnly || d.disabled;
        } else {
            doPrevent = true;
        }
    }
    if (doPrevent) {
        event.preventDefault();
    }
});

고마워, 나는이 대답을 사용하고 있습니다! 지금까지이 솔루션에 문제가 있습니까?
Nearpoint

1
모든 키 다운 이벤트에서 다시 계산되지 않도록 함수에서 INPUTTYPES, TEXTRE 선언을 이동하는 것이 좋습니다.
thetoolman

3

자바 스크립트-jQuery 방식 :

$(document).on("keydown", function (e) {
    if (e.which === 8 && !$(e.target).is("input, textarea")) {
        e.preventDefault();
    }
});

자바 스크립트-기본 방식으로 저에게 효과적입니다.

<script type="text/javascript">

//on backspace down + optional callback
function onBackspace(e, callback){
    var key;
    if(typeof e.keyIdentifier !== "undefined"){
        key = e.keyIdentifier;

    }else if(typeof e.keyCode !== "undefined"){
        key = e.keyCode;
    }
    if (key === 'U+0008' || 
        key === 'Backspace' || 
        key === 8) {
                    if(typeof callback === "function"){
                callback();
            }
            return true;
        }
    return false;
}

//event listener
window.addEventListener('keydown', function (e) {

    switch(e.target.tagName.toLowerCase()){
        case "input":
        case "textarea":
        break;
        case "body":
            onBackspace(e,function(){
                e.preventDefault();
            });

        break;
    }
}, true);
</script>

@MichaelPotter 오래 전부터 내 유스 케이스에 괜찮 았습니다. 제 답변을 개선 / 변경하여 자유롭게 기여하십시오. 고마워!
블라디미르 Djuricic

3

비 JQUERY 답변을 찾는 데 어려움을 겪었습니다. 길을 안내해 준 Stas에게 감사합니다.

Chrome : 교차 브라우저 지원이 필요하지 않은 경우 화이트리스트 대신 블랙리스트를 사용할 수 있습니다. 이 순수한 JS 버전은 Chrome에서는 작동하지만 IE에서는 작동하지 않습니다. FF에 대해 확실하지 않습니다.

Chrome (버전 36, 2014 년 중반)에서 입력 또는 콘텐츠 편집 가능 요소를 누르지 않은 키 누르기는 대상으로 보입니다 <BODY>. 이를 통해 화이트리스트를 선호하는 블랙리스트를 사용할 수 있습니다. IE는 마지막 클릭 타겟을 사용하므로 div 또는 다른 것이 될 수 있습니다. 이것은 IE에서 이것을 쓸모 없게 만듭니다.

window.onkeydown = function(event) {
    if (event.keyCode == 8) {
    //alert(event.target.tagName); //if you want to see how chrome handles keypresses not on an editable element
        if (event.target.tagName == 'BODY') {
            //alert("Prevented Navigation");
            event.preventDefault();
        }
    }
}  

크로스 브라우저 : 순수한 자바 스크립트의 경우 Stas의 답변이 최고라는 것을 알았습니다. contenteditable에 대한 조건 확인을 하나 더 추가하면 나를 위해 일하게되었습니다.

document.onkeydown = function(e) {stopDefaultBackspaceBehaviour(e);}
document.onkeypress = function(e) {stopDefaultBackspaceBehaviour(e);}

function stopDefaultBackspaceBehaviour(event) {
    var event = event || window.event;
    if (event.keyCode == 8) {
        var elements = "HTML, BODY, TABLE, TBODY, TR, TD, DIV";
        var d = event.srcElement || event.target;
        var regex = new RegExp(d.tagName.toUpperCase());
        if (d.contentEditable != 'true') { //it's not REALLY true, checking the boolean value (!== true) always passes, so we can use != 'true' rather than !== true/
            if (regex.test(elements)) {
                event.preventDefault ? event.preventDefault() : event.returnValue = false;
            }
        }
    }
}

* IE [edit : 및 Spartan / TechPreview]에는 테이블 관련 요소를 편집 할 수없는 "기능"이 있습니다. 그중 하나를 클릭 한 다음 백 스페이스를 누르면 다시 탐색합니다. 편집 가능한 <td>이 없으면 문제가되지 않습니다.


2

허용되는 솔루션과 Select2.js 플러그인에 문제가있었습니다. 삭제 조치가 방지되어 편집 가능한 상자에서 문자를 삭제할 수 없습니다. 이것은 내 해결책이었습니다.

//Prevent backwards navigation when trying to delete disabled text.
$(document).unbind('keydown').bind('keydown', function (event) {

    if (event.keyCode === 8) {

        var doPrevent = false,
            d = event.srcElement || event.target,
            tagName = d.tagName.toUpperCase(),
            type = (d.type ? d.type.toUpperCase() : ""),
            isEditable = d.contentEditable,
            isReadOnly = d.readOnly,
            isDisabled = d.disabled;

        if (( tagName === 'INPUT' && (type === 'TEXT' || type === 'PASSWORD'))
            || tagName === 'PASSWORD'
            || tagName === 'TEXTAREA') {
            doPrevent =  isReadOnly || isDisabled;
        }
        else if(tagName === 'SPAN'){
            doPrevent = !isEditable;
        }
        else {
            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
    }
});

Select2는 속성이 "contentEditable"인 스팬을 작성합니다.이 속성은 편집 가능한 콤보 상자에 대해 true로 설정됩니다. spans tagName과 다른 속성을 설명하는 코드를 추가했습니다. 이것은 내 모든 문제를 해결했습니다.

편집 : jquery에 Select2 콤보 박스 플러그인을 사용하지 않으면이 솔루션이 필요하지 않을 수 있으며 허용되는 솔루션이 더 좋습니다.


1
    document.onkeydown = function (e) {    
        e.stopPropagation();
        if ((e.keyCode==8  ||  e.keyCode==13) &&
            (e.target.tagName != "TEXTAREA") && 
            (e.target.tagName != "INPUT")) { 
            return false;
        }
    };

2
return false를 사용해서는 안됩니다. e.preventDefault가 권장됩니다. 또한 백 스페이스뿐만 아니라 모든 키에 대한 이벤트 전파를 중지합니다. 마지막으로, keyCode 13이 입력되고 백 스페이스를 사용하여 뒤로 탐색을 방지하는 방법에 대한 의문이 있었지만 이는 입력이 양식을 제출하거나 다른 조치를 수행하지 못하게합니다.
없음

1

이 코드는 모든 브라우저에서 문제를 해결합니다.

onKeydown:function(e)
{
    if (e.keyCode == 8) 
    {
      var d = e.srcElement || e.target;
      if (!((d.tagName.toUpperCase() == 'BODY') || (d.tagName.toUpperCase() == 'HTML'))) 
      {
         doPrevent = false;
      }
       else
      {
         doPrevent = true;
      }
    }
    else
    {
       doPrevent = false;
    }
      if (doPrevent)
      {
         e.preventDefault();
       }

  }

1
나는 예상대로이 코드 때문에 d.tagname가되는 일이 있지 않는 것을 발견 DIV하거나 TD.
Biff MaGriff

Haseeb Akhtar의 코드는 Chrome 및 Firefox에서 완벽하게 작동하지만 놀랍습니다! IE6-9에없는 제안?
Martin Andersen

1

백 스페이스를 누를 때 탐색을 방지하는 가장 간단한 방법

$(document).keydown(function () {
    if (event.keyCode == 8) {
        if (event.target.nodeName == 'BODY') {
            event.preventDefault();
        }
    }
});

backspcae를 누르는 탐색을 방지하고 동시에 모든 입력 컨트롤에서 백 스페이스를 허용합니다.
Mohammed Irfan Mayan

그리고 첫 번째 줄을 놓치지 마세요 .. $ (document) .keydown (function () {
Mohammed Irfan Mayan

3
이것은 텍스트 영역과 입력 내부의
백 버튼

1

Dojo 툴킷 1.7을 사용하면 IE 8에서 작동합니다.

require(["dojo/on", "dojo/keys", "dojo/domReady!"],
function(on, keys) {
    on(document.body,"keydown",function(evt){if(evt.keyCode == keys.BACKSPACE)evt.preventDefault()});
});

1

읽기 전용 텍스트 필드에 다음 속성을 추가하는 매우 간단한 해결책을 시도해 보셨습니까?

onkeydown = "거짓을 반환;"

이렇게하면 읽기 전용 텍스트 필드에서 백 스페이스 키를 누를 때 브라우저가 히스토리로 돌아 가지 않습니다. 어쩌면 나는 당신의 진정한 의도를 잃어 버렸지 만 이것이 당신의 문제에 대한 가장 간단한 해결책 일 것 같습니다.


1

훨씬 깔끔한 솔루션-

$(document).on('keydown', function (e) {
    var key = e == null ? event.keyCode : e.keyCode;
    if(key == 8 && $(document.activeElement.is(':not(:input)')))   //select, textarea
      e.preventDefault();
});

다른 방법으로는

$(document.activeElement).is('body')

1

모든 브라우저에서 작동하는 순수 자바 스크립트 버전 :

document.onkeydown = function(e) {stopDefaultBackspaceBehaviour(e);}
document.onkeypress = function(e) {stopDefaultBackspaceBehaviour(e);}

function stopDefaultBackspaceBehaviour(event) {
  var event = event || window.event;
  if (event.keyCode == 8) {
    var elements = "HTML, BODY, TABLE, TBODY, TR, TD, DIV";
    var d = event.srcElement || event.target;
    var regex = new RegExp(d.tagName.toUpperCase());
    if (regex.test(elements)) {
      event.preventDefault ? event.preventDefault() : event.returnValue = false;
    }
  }
}

물론 "INPUT, TEXTAREA"를 사용하고 "if (! regex.test (elements))"를 사용할 수 있습니다. 첫 번째는 나를 위해 잘 작동했습니다.


1

공연?

나는 성능에 대해 걱정하고 바이올린을 만들었습니다 : http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

var stresstest = function(e, method, index){...

이 스레드에서 찾은 가장 유망한 방법을 분석했습니다. 그것들은 모두 매우 빠르며 타이핑 할 때 "느슨 함"이라는 관점에서 문제를 일으키지 않을 것입니다. 내가 본 가장 느린 방법은 IE8의 10.000 호출에 대해 약 125ms였습니다. 스트로크 당 0.0125ms입니다.

Codenepal과 Robin Maben이 게시 한 방법이 ~ 0.001ms (IE8)가 가장 빠르지 만 다른 의미를주의하십시오.

아마도 이것은 이런 종류의 기능을 그의 코드에 소개하는 누군가에게 안도감 일 것입니다.


1

수정 된 erikkallen 답변 :

$(document).unbind('keydown').bind('keydown', function (event) {

    var doPrevent = false, elem;

    if (event.keyCode === 8) {
        elem = event.srcElement || event.target;
        if( $(elem).is(':input') ) {
            doPrevent = elem.readOnly || elem.disabled;
        } else {
            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
        return false;
    }
});

1
완벽한 답변. 내가 다른 사람들로부터 얻은 해결책은 파이어 폭스에서 작동하지 않았지만이 문제는 세 가지 (파이어 폭스, IE 및 crome)에서 아무런 문제없이 완벽하게 작동했습니다. 감사합니다 Prozi.
Nikhil Dinesh

1

이 솔루션은 테스트 할 때 매우 효과적이었습니다.

입력으로 태그가 지정되지 않은 일부 입력 필드를 처리하고 내 작업에 대한 입력 양식을 생성하는 Oracle PL / SQL 응용 프로그램에 통합하는 코드를 추가했습니다.

내 "2 센트":

 if (typeof window.event != ''undefined'')
    document.onkeydown = function() {
    //////////// IE //////////////
    var src = event.srcElement;
    var tag = src.tagName.toUpperCase();
    if (event.srcElement.tagName.toUpperCase() != "INPUT"
        && event.srcElement.tagName.toUpperCase() != "TEXTAREA"
        || src.readOnly || src.disabled 
        )
        return (event.keyCode != 8);
    if(src.type) {
       var type = ("" + src.type).toUpperCase();
       return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
       }
   }
else
   document.onkeypress = function(e) {
   //////////// FireFox 
   var src = e.target;
   var tag = src.tagName.toUpperCase();
   if ( src.nodeName.toUpperCase() != "INPUT" && tag != "TEXTAREA"
      || src.readOnly || src.disabled )
      return (e.keyCode != 8);
    if(src.type) {
      var type = ("" + src.type).toUpperCase();
      return type != "CHECKBOX" && type != "RADIO" && type != "BUTTON";
      }                              
   }

1

현재 허용되는 (erikkallen의) 깨끗한 버전으로 NPM 프로젝트를 만들었습니다.

https://github.com/slorber/backspace-disabler

기본적으로 동일한 원칙을 사용하지만 다음과 같습니다.

  • 의존성 없음
  • 컨텐츠 편집 가능
  • 더 읽기 쉽고 유지 보수가 쉬운 코드베이스
  • 회사에서 생산할 때 사용되므로 지원됩니다
  • MIT 라이센스

var Backspace = 8;

// See http://stackoverflow.com/questions/12949590/how-to-detach-event-in-ie-6-7-8-9-using-javascript
function addHandler(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
}
function removeHandler(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
}




// Test wether or not the given node is an active contenteditable,
// or is inside an active contenteditable
function isInActiveContentEditable(node) {
    while (node) {
        if ( node.getAttribute && node.getAttribute("contenteditable") === "true" ) {
            return true;
        }
        node = node.parentNode;
    }
    return false;
}



var ValidInputTypes = ['TEXT','PASSWORD','FILE','EMAIL','SEARCH','DATE'];

function isActiveFormItem(node) {
    var tagName = node.tagName.toUpperCase();
    var isInput = ( tagName === "INPUT" && ValidInputTypes.indexOf(node.type.toUpperCase()) >= 0 );
    var isTextarea = ( tagName === "TEXTAREA" );
    if ( isInput || isTextarea ) {
        var isDisabled = node.readOnly || node.disabled;
        return !isDisabled;
    }
    else if ( isInActiveContentEditable(node) ) {
        return true;
    }
    else {
        return false;
    }
}


// See http://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
function disabler(event) {
    if (event.keyCode === Backspace) {
        var node = event.srcElement || event.target;
        // We don't want to disable the ability to delete content in form inputs and contenteditables
        if ( isActiveFormItem(node) ) {
            // Do nothing
        }
        // But in any other cases we prevent the default behavior that triggers a browser backward navigation
        else {
            event.preventDefault();
        }
    }
}


/**
 * By default the browser issues a back nav when the focus is not on a form input / textarea
 * But users often press back without focus, and they loose all their form data :(
 *
 * Use this if you want the backspace to never trigger a browser back
 */
exports.disable = function(el) {
    addHandler(el || document,"keydown",disabler);
};

/**
 * Reenable the browser backs
 */
exports.enable = function(el) {
    removeHandler(el || document,"keydown",disabler);
};

1

여기에 최고의 투표 답변을 다시 작성했습니다. element.value! == undefined를 확인하려고했지만 (html 속성이 없지만 프로토 타입 체인의 어딘가에 javascript value 속성이있을 수 있으므로) 정의가 잘 이루어지지 않았으며 많은 경우가있었습니다. 미래를 보장 할 수있는 좋은 방법은없는 것 같으므로 화이트리스트가 최선의 선택 인 것 같습니다.

이벤트 버블 단계의 끝에 요소를 등록하므로 백 스페이스를 사용자 정의 방식으로 처리하려는 경우 다른 핸들러에서 처리 할 수 ​​있습니다.

이론적으로 HTMLTextAreElement의 인스턴스를 확인하여 이론적으로 웹 컴포넌트를 상속받을 수 있습니다.

이것은 contentEditable을 검사하지 않습니다 (다른 답변과 결합).

https://jsfiddle.net/af2cfjc5/15/

var _INPUTTYPE_WHITELIST = ['text', 'password', 'search', 'email', 'number', 'date'];

function backspaceWouldBeOkay(elem) {
    // returns true if backspace is captured by the element
    var isFrozen = elem.readOnly || elem.disabled;
    if (isFrozen) // a frozen field has no default which would shadow the shitty one
        return false;
    else {
        var tagName = elem.tagName.toLowerCase();
        if (elem instanceof HTMLTextAreaElement) // allow textareas
            return true;
        if (tagName=='input') { // allow only whitelisted input types
            var inputType = elem.type.toLowerCase();
            if (_INPUTTYPE_WHITELIST.includes(inputType))
                return true;
        }   
        return false; // everything else is bad
    }
}

document.body.addEventListener('keydown', ev => {
    if (ev.keyCode==8 && !backspaceWouldBeOkay(ev.target)) {
        //console.log('preventing backspace navigation');
        ev.preventDefault();
    }
}, true); // end of event bubble phase


0

jquery를 사용하는 다른 방법

    <script type="text/javascript">

    //set this variable according to the need within the page
    var BACKSPACE_NAV_DISABLED = true;

    function fnPreventBackspace(event){if (BACKSPACE_NAV_DISABLED && event.keyCode == 8) {return false;}}
    function fnPreventBackspacePropagation(event){if(BACKSPACE_NAV_DISABLED && event.keyCode == 8){event.stopPropagation();}return true;}

    $(document).ready(function(){ 
        if(BACKSPACE_NAV_DISABLED){
            //for IE use keydown, for Mozilla keypress  
            //as described in scr: http://www.codeproject.com/KB/scripting/PreventDropdownBackSpace.aspx
            $(document).keypress(fnPreventBackspace);
            $(document).keydown(fnPreventBackspace);

            //Allow Backspace is the following controls 
            var jCtrl = null;
            jCtrl = $('input[type="text"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('input[type="password"]');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            jCtrl = $('textarea');
            jCtrl.keypress(fnPreventBackspacePropagation);
            jCtrl.keydown(fnPreventBackspacePropagation);

            //disable backspace for readonly and disabled
            jCtrl = $('input[type="text"][readonly="readonly"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);

            jCtrl = $('input[type="text"][disabled="disabled"]')
            jCtrl.keypress(fnPreventBackspace);
            jCtrl.keydown(fnPreventBackspace);
        }
    }); 

    </script>

controls (textbox)가 동적으로 추가 된 경우에는 작동하지 않습니다.
CodeNepal

0

나는 이것을 얼마 동안 내 코드에서 사용 해왔다. 학생들을 위해 온라인 테스트를 작성하고 학생들이 테스트 중에 백 스페이스를 누를 때 문제가 발생하여 다시 로그인 화면으로 돌아갑니다. 답답해! 확실히 FF에서 작동합니다.

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.