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

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 버그 뒤에 지원을 던질 수 있습니다



답변

이 코드는 적어도 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;
        }
    }
});


답변

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

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


답변

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

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

문제는 사용자가 링크를 클릭하거나 양식을 제출할 때와 같이 페이지에서 벗어날 때마다 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에 드롭하고 사용자가 실수로 데이터를 잃지 않기를 원하는 페이지에서 호출하십시오.

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

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


답변

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

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


답변

다른 입력 유형을 처리하기위한 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>


답변

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

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


답변

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

$(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 홈페이지처럼)