Geri silme tuşunun geri gitmesini nasıl önleyebilirim?


275

IE üzerinde bunu (korkunç standart dışı, ama çalışma) jQuery ile yapabilirsiniz

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

Ancak Firefox'ta çalışan bir şekilde veya bonus için tarayıcılar arası bir şekilde yapmak mümkün mü?

Kayıt için:

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

hiç birşey yapmıyor.

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

sorunu çözer, ancak geri silme tuşunu sayfada kullanılamaz hale getirir, bu da orijinal davranıştan daha da kötüdür.

EDIT: Bunu yapmak nedeni basit bir web sayfası değil büyük bir uygulama oluşturmak olmasıdır. Yanlış yere geri bastığınız için 10 dakikalık işi kaybetmek inanılmaz derecede can sıkıcı. Hataların önlenmesi ile sinir bozucu kullanıcılar arasındaki oran, geri silme tuşunun geri gitmesini engelleyerek 1000/1'in çok üzerinde olmalıdır.

EDIT2: Geçmişte gezinmeyi engellemeye çalışmıyorum , sadece kazalar.

EDIT3: @brentonstrines yorum (soru çok popüler olduğu için buraya taşındı): Bu uzun vadeli bir 'düzeltme', ancak webkit'teki bu davranışı değiştirmek için desteğinizi Chromium hatasının arkasına atabilirsiniz


137
Çünkü geri tuşu aşırı yüklenmiş. Fark etmemiş olabilirsiniz, ancak muhtemelen bir metin alanına yeni yazdığınız harfleri silmek için her zaman kullanıyorsunuzdur. Bazı müşterilerim, sayfanın geri dönmesine neden olma konusunda sorun yaşıyor, bu yüzden bu yararlı bilgiler. Senin palyaçolardan başka hiç kimse geri almanın bir sayfaya geri dönmesi gerektiğini bilmiyor . Bu hiç bilmediğim bir şey ve bir tarayıcının sahip olması açıkça düşmanca bir davranış. Tüm sayfaların bu davranışı devre dışı bırakması gerektiğini düşünüyorum.
Breton

80
İnsanlar neden bunun garip olduğunu düşünüyor? Gezinme için geri tuşu kullanmak gerçekten aptalca bir kısayoldur! kullanıcıların metin silmek isteyebileceği çok fazla metin alanı vardır - uzun bir SO cevabına sahip olduğunuzu, bir şeyi kontrol etmek için başka bir pencereye geçtiğinizi düşünün ve sonra geri dönüp düzenleme alanını yanlış tıklayın, bir kelimeyi kaldırmak için geri tuşuna basın ve aniden tarayıcı bir sayfaya geri döner ve yazdığınız her şeyi kaybetmiş olabilirsiniz.
Peter Boughton

57
Bunu neden yapmak istiyorum? Bir web sitesi değil, bir web uygulaması oluşturuyorum. Bazı giriş alanları salt okunurdur, bu durumda düzenlenebilir görünürler, ancak geri tuşuna basarsanız sayfadan ayrılırsınız. Bir şeyi silmeye çalışan backspace baskılarına karşı backspace baskılarının oranı muhtemelen 1 / 1000'den çok daha düşüktür.
erikkallen

42
Soru, bunun iyi bir fikir olup olmadığı hakkında fikriniz değil, bunun nasıl yapılacağıdır. Projenin ayrıntılarını bilmeden fikirleriniz anlamsızdır. Müşterim özellikle bu davranışı projelerimden biri için "Neden bunu yapmak istesin?" yardımcı olur.
Hiçbiri

7
Bu uzun vadeli bir düzeltme, ancak
webkit'te

Yanıtlar:


335

Bu kod, en azından IE ve Firefox'ta sorunu çözer (başkalarını test etmedim, ancak sorun diğer tarayıcılarda bile mevcutsa çalışma şansı verdim).

// 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
Şifre alanlarını keser.
Hemlock

7
Hemlock'un belirttiği gibi - kontrol edin d.type.toUpperCase() === 'PASSWORD'. Aksi takdirde iyi görünüyor
stevendesu

17
Zaten jQuery kullandığınız içinif( $(d).is( ":input" ) )...
Paul Alexander

23
Bunun "geri" işlevselliğini kara listeye alabilmek yerine beyaz liste olması gerektiği berbat. Buraya bir çek eklemek isteyebilirsiniz d.isContentEditable.
iono

3
Şu anda kabul edilen cevabın temiz bir versiyonuyla bir NPM projesi hazırladım: github.com/slorber/backspace-disabler (aynı zamanda içeriği de destekliyor ve bağımlılığı yok)
Sebastien Lorber

62

Bu kod, tüm tarayıcılarda çalışır ve bir form öğesinde değilken veya form öğesi devre dışı bırakılırsa geri silme tuşunu yutar | readOnly. Aynı zamanda etkilidir, bu da yazılan her anahtar üzerinde yürütülürken önemlidir.

$(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
Lütfen örneğimi test edin, kodunuzu buna göre güncellemek isteyebilirsiniz.
Biff MaGriff

10
Bunu @ erikkallen'in çözümüne tercih ediyorum çünkü daha temiz. Ancak, düğmeler, radyo düğmeleri ve onay kutularının da göz ardı edilmesini istedim, bu nedenle if () 'i şu şekilde değiştirdim: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'in cevabı hakkındaki yorumuma bakın. Bu da hesaba katılmalıdır contentEditable.
sarsıntı

10
@MaffooClock: Eğer daha özlü olabilir.is(':checkbox,:radio,:submit')
cdmckay

1
@cdmckay: İlk başta bu şekilde yazmadığımı düşünemiyorum. Hepimizi temizlediğiniz için teşekkürler :)
Matthew Clark

41

Buradaki diğer cevaplar, bunun Backspace'e izin verilen beyaz liste öğeleri olmadan yapılamayacağını belirledi. Bu çözüm ideal değildir, çünkü beyaz liste yalnızca textareas ve metin / şifre girişleri kadar basit değildir, ancak tekrar tekrar eksik ve güncellenmesi gerektiği bulunmuştur.

Bununla birlikte, arka boşluk işlevselliğini bastırmanın amacı kullanıcıların yalnızca yanlışlıkla veri kaybetmesini önlemek olduğundan, önceki yükleme çözümü iyi bir çözümdür, çünkü kalıcı açılır pencere şaşırtıcıdır - kalıcı açılır pencereler standart bir iş akışının bir parçası olarak tetiklendiğinde kötüdür, çünkü kullanıcı onları okumadan işten çıkarmaya alışır ve can sıkıcıdır. Bu durumda, kalıcı açılır pencere yalnızca nadir ve şaşırtıcı bir eyleme alternatif olarak görünecektir ve bu nedenle kabul edilebilir.

Sorun, kullanıcı sayfadan her uzaklaştığında (örneğin bir bağlantıyı tıklarken veya bir form gönderirken olduğu gibi) bir onbeforeload modunun açılmaması ve önceden yüklenme koşullarında belirli beyaz listeye veya kara listeye başlamak istemiyoruz.

Genelleştirilmiş bir çözüm için dengesizliklerin ideal kombinasyonu aşağıdaki gibidir: geri tuşuna basıp basılmadığını takip edin ve yalnızca onbeforeunload modunu açın. Diğer bir deyişle:

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 ve Opera'da çalıştığı test edilmiştir. Bu işlevi global.js'nize bırakın ve kullanıcıların yanlışlıkla verilerini kaybetmesini istemediğiniz herhangi bir sayfadan çağırın.

Önceden yüksüz bir modun yalnızca bir kez tetiklenebileceğini unutmayın, bu nedenle kullanıcı tekrar geri tuşuna basarsa mod tekrar ateşlenmez.

Bunun hashchange olaylarında tetiklenmeyeceğini unutmayın, ancak bu bağlamda kullanıcıların yanlışlıkla verilerini kaybetmesini önlemek için başka teknikler kullanabilirsiniz.


2
Aynı çözümü eklemeye gittim ve bu yazıyı LOL sayfasının altında gördüm. Bir fark var lastUserInputWasBackspace = yanlış "Emin misiniz ..." ifadesi önce ayarlamaktır, bu yüzden zaten pop-up gördükten sonra geri düğmesini tıklarsanız pop-up alamazsınız (böylece backspace'den etkilenen davranış).
David Russell

1
@ user2407309 Çözümünüzle çalışmayan firefox hakkındaki yorumumu (şikayet değil) kaldırdım. Hata ayıklayıcımla ilgili bir sorun vardı. Kodunuzu düzenlemek / kırmaktan dolayı özür dilerim. Şimdi sınırlarımı (düzenleme) aştığımı anlıyorum beni affetti. Gerçekten üzgünüm ve bu soruna harika çözümünüzden şikayet etmedim. Tekrar özür dilerim. Bu kod iyi çalışıyor. Bunun en iyi cevap olduğuna inanıyorum ve sizi bunun için övüyorum.
Charles Byrne

1
Bu çözüm yerel makinemde çalıştı, ancak onu taşıdığımda, istemci (en azından bazıları) uygulamanın yarısının işlevselliğini kaybetti. Sanırım bir şey reddediyor, ama ne olduğu hakkında hiçbir fikrim yok.
Steve

1
@Steve, nadir ya da değil, işlevle ilgili bir sorun varsa, bu bilgi buraya aittir. Sadece gerçekten bir sorun olup olmadığını bilmek istiyorum.
Vladimir Kornea

1
Güzel bir çözüm, ancak ne yazık ki, bir kullanıcı yanlışlıkla geri tuşuna iki kez basarsa, yine de geri gider. (en azından firefox'ta)
Remco de Zwart

26

Daha zarif / özlü bir çözüm:

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

1
Bu çok daha özlü ve söyleyebileceğim kadarıyla da işe yarıyor. Neden en popüler cevap tüm bu girdi türlerini kontrol ediyor ve daha karmaşık görünüyor? Daha güvenilir mi?
Nearpoint

1
En popüler cevap soruyu ilk cevaplayan kişi, dolayısıyla yüksek oylardı.
Darwayne

4
salt okunur alanlar odaklandığında silme işlemi hala kromda geri döner
Will D

16

Erikkallen'in cevabının değişik giriş tiplerine cevap vermesi

Girişimci bir kullanıcının boşaltma girişiminde bir onay kutusuna veya radyo düğmesine geri basabileceğini ve bunun yerine geriye doğru gidip tüm verilerini kaybedeceğini buldum.

Bu değişiklik bu konuyu ele almalıdır.

Yeni içerik düzenlenebilir div'lere yönelik düzenleme

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

Örnek
2 dosyayı test etmek için.

starthere.htm - geri dönmek için bir yeriniz olması için önce bunu açın

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

test.htm - Onay kutusu veya gönderme odaktayken (sekme ile elde edilir) geri tuşuna basıldığında geriye doğru gider. Düzeltmek için kodumla değiştirin.

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

Hangi tarayıcıda backspace tuşuna basıldığını gördünüz | onay kutusu | gönder -> geri işlevi? Bunu yapan bir tarayıcı görmedim ..
thetoolman

Internet Explorer 8 ve Chrome
Biff MaGriff

2
Bu iş parçacığında bir dizi diğer çözümü denedim, ancak bu tüm durumlarımda iyi çalıştı ve kodun anlaşılması en temiz, en kolayı vardı. Teşekkür ederim.
Ezward

@Darwayne'i denediniz mi Neden bu kadar kısa ve bu daha karmaşık olduğunu merak ediyorum, ama her ikisi de benim için aynı şekilde çalışıyor gibi görünüyor
Nearpoint

Bu bağlantılar üzerinde çalışıyor mu? Bir öğeyi kaldırmak için görüntü düğmeli bir ASP.Net uygulaması var. Bunun şu ana kadar çalışmadığı tek şey ...
Steve

8

Görünen yorumlara göre, silmek için geri tuşuna basarlarsa ancak alan odaklanmazsa, formlardaki bilgileri kaybetmelerini durdurmak istersiniz.

Bu durumda onunload olay işleyicisine bakmak istersiniz . Yığın Taşması kullanır - bir yanıt yazmaya başladığınızda bir sayfadan ayrılmaya çalışırsanız bir uyarı görüntülenir.


4
üzgünüm kaba bir yorum oldu. Demek istediğim, kullanıcı muhtemelen yanlış olduğunu bilmedikleri bir şey yapmak için berated olmak istemiyor. Neden sadece bir anahtarla sessizce yemek istemiyorsun? Amaç, kullanıcının sayfadan ayrılmasını tamamen önlemek değil, bu yaygın hataya karşı korunmaktır. Ayrıca, açılır diyaloglar çok etkili veya yararlı değildir. Kullanıcılar bunları okumuyor. Sayfadan ayrılmak istediğinizden emin misiniz? Tamam! Beklemek yok, sayfadan ayrılmak istemiyordum .. ayy çok geç.
Breton

3
Tamam sonra al ya da bırak. Bence, gerçekten var olmayan veya en azından önemli olmayan bir sorunu aşırı mühendisliğe sokmaya çalışıyorsunuz. Ve benim tecrübelerime göre, tanıdık olmayan diyaloglarda "Tamam" ı tıklayan kullanıcılar sadece onları düzgün okumadan. ;)
DisgruntledGoat

3
Siz ve Breton aynı kişi misiniz? Yine de biraz orada ayak kendinizi vurdu - makale "İptal" sayfasını bırakma konusunda iletişim görünce yüzden onlar basına gidiyoruz ve bu nedenle "varsayılan cevabı iptal olduğunu" söylüyor değil sayfadan ayrılmayın. Bununla birlikte, Chrome'un bu iletişim kutusundaki seçeneklerinin "Bu sayfadan ayrıl" ve "Bu sayfada kal" ifadelerinin çok açık olduğu belirtilmelidir.
DisgruntledGoat

1
Hayır, o ben değilim, ama daha önce bu bağlantıya rastladım. Bence yorumlar çok komik. "Ne !? insanlar kalıcı iletişim kutularını görmezden geliyorlar mı? Gerçekten microsoft yazılımı hakkında çok şey açıklıyor.
Breton

3
@Disgruntled: Hayır, ben Breton değilim ve makalenin amacı "Varsayılan seçim ..." değil, "kullanıcılar hiçbir şey okumuyor."
erikkallen

7

Bu kod gezinme durdurmak çalışır!

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

Ancak metin alanlarını değil diğerlerini kısıtlamak için

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

Belirli bir alanda kullanılmasını önlemek için

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

Aşağıdakilere atıfta bulunarak!

BACKSPACE'in jQuery ile geri dönmesini engelleyin (Google'ın Ana Sayfası gibi)


7

Cevapların çoğu jquery'de. Bunu saf Javascript, basit ve hiçbir kütüphane gerekli mükemmel yapabilirsiniz. Bu makale benim için iyi bir başlangıç ​​noktasıydı, ancak keyIdentifier kullanımdan kaldırıldığı için if koduna || e.keyCode == 8 eklediğim için bu kodun daha güvenli olmasını istedim . Ayrıca, kod Firefox üzerinde iyi çalışmadığı için return false ekledim ; ve şimdi çok iyi çalışıyor. İşte burada:

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

Bu kod harika çalışıyor çünkü,

  1. Saf javascripttedir (kütüphane gerekmez).
  2. Sadece basılan tuşu kontrol etmekle kalmaz, aynı zamanda eylemin gerçekten bir tarayıcı "geri" eylemi olduğunu doğrular.
  3. Yukarıdakilerle birlikte, kullanıcı geri düğmesi işlemini engellerken web sayfasındaki giriş metin kutularına sorunsuz bir şekilde metin yazabilir ve silebilir.
  4. Kısa, temiz, hızlı ve doğrudan doğruya.

Console.log (e) ekleyebilirsiniz; test amaçlarınız için ve kromda F12 tuşuna basın, "konsol" sekmesine gidin ve sayfadaki "geri" tuşuna basın ve hangi değerlerin döndürüldüğünü görmek için içine bakın, ardından kodu daha da geliştirmek için tüm bu parametreleri hedefleyebilirsiniz ihtiyaçlarınızı karşılamak için yukarıda.


6

"Thetoolman" && "Biff MaGriff" tarafından verilen çözümlerin birleştirilmesi

Aşağıdaki kod IE 8 / Mozilla / Chrome'da doğru çalışıyor gibi görünüyor

$(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 eklemek de yararlı olabilir.
mrswadge

Ben buna karar verdim.
Corentin

5

Kimsenin bunu neden yanıtlamadığından emin değilim - bunun mümkün olup olmadığını sormak için mükemmel makul bir teknik soru gibi görünüyor.

Hayır, geri silme düğmesini devre dışı bırakmanın çapraz tarayıcı yolu olduğunu sanmıyorum. Bu günlerde FF'de varsayılan olarak etkin olmadığını biliyorum.


3
Gerçek soruyu cevaplamadığı ve zaman kaybetmediği için eksi 1
Andrew

4

JQUERY olmayan bir cevap bulmakta zorlandım. Beni yolda bıraktığı için Stas'a teşekkürler.

Chrome: Çapraz tarayıcı desteğine ihtiyacınız yoksa, beyaz listeleme yerine yalnızca bir kara liste kullanabilirsiniz. Bu saf JS sürümü Chrome'da çalışır, ancak IE'de çalışmaz. FF hakkında emin değilim.

Chrome'da (sürüm 36, 2014 ortası), bir girişte veya içerikte bulunulan öğede olmayan tuşlara basılması hedeflenmiş gibi görünüyor <BODY>. Bu, beyaz listeye eklemeyi tercih ettiğim bir kara liste kullanmayı mümkün kılar. IE son tıklama hedefini kullanır - bu nedenle bir div veya başka bir şey olabilir. Bu IE'de işe yaramaz hale getirir.

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

Çapraz Tarayıcı: Saf javascript için, Stas'ın cevabının en iyisi olduğunu gördüm. İçeriğe uygun hale getirmek için bir koşul kontrolü daha eklemek benim için işe yaradı *:

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'lerde [edit: ve Spartan / TechPreview], tablo ile ilgili öğeleri düzenlenemeyen bir "özellik" bulunduğunu unutmayın . Bunlardan birini tıklar ve SONRA geri tuşuna basarsanız geri gider. Düzenlenebilir özellikleriniz yoksa <td>, bu bir sorun değildir.


3

Bu çözüm, yayınlanan diğerlerine benzer, ancak yalnızca .is () işlevinde seçiciyi ayarlayarak belirli öğelerde geri aralığa izin vermek için kolayca özelleştirilebilir hale getiren basit bir beyaz liste kullanır.

Bu formda, sayfalardaki geri aramanın geri gitmesini önlemek için kullanıyorum:

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

2
Kullanıcı içeriği düzeltilebilir kullandığında, bu devre dışı bırakılır. Bu yüzden beyaz listeye contenteditable = true ifadesini eklemek isteyebilirsiniz
Miguel

3

@ Erikkallen'in mükemmel cevabını biraz ayrıntılandırmak için , HTML5'te tanıtılanlar da dahil olmak üzere tüm klavye tabanlı giriş türlerine izin veren bir işlev :

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

Teşekkürler, bu cevabı kullanıyorum! Şimdiye kadar bu çözümlerle ilgili herhangi bir sorun buldunuz mu?
Nearpoint

1
INPUTTYPES, TEXTRE bildirimlerini işlevin dışına taşımayı öneriyorum, böylece her bir tuşlama olayında yeniden hesaplanmıyorlar.
thetoolman

3

JavaScript - jQuery yolu:

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

Javascript - benim için çalışan yerel yol:

<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 Uzun zaman önce benim kullanımım için iyiydi. Lütfen cevabımı geliştirerek / değiştirerek katkıda bulunmaktan çekinmeyin. Teşekkürler!
Vladimir Djuricic

2

Kabul edilen çözüm ve Select2.js eklentisiyle ilgili bazı sorunlar yaşadım; Silme işlemi engellendiği için düzenlenebilir kutudaki karakterleri silemedim. Bu benim çözümümdü:

//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, düzenlenebilir birleşik giriş kutusu için true olarak ayarlanan "contentEditable" özniteliğine sahip bir Span oluşturur. Kod tagName ve farklı özniteliğini hesaba eklemek için kod ekledim. Bu tüm sorunlarımı çözdü.

Düzenleme: jquery için Select2 birleşik giriş eklentisi kullanmıyorsanız, bu çözüm sizin tarafınızdan gerekli olmayabilir ve kabul edilen çözüm daha iyi olabilir.


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 kullanmamalısınız. Varsayılan tavsiye edilir. Ayrıca sadece backspace için değil, her tuş için olayın yayılmasını durduruyorsunuz. Son olarak, keyCode 13 girilir ve soru, geri tuşu ile geri gezinmeyi önlemekle ilgilidir, ancak bu, enter'un formu göndermesini veya diğer eylemleri gerçekleştirmesini önleyecektir.
Hiçbiri

1

Bu kod sorunu tüm tarayıcılarda çözer:

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
Bu kod d.tagname olmak DIVveya beklendiği gibi çalışmıyor buluyorum TD.
Biff MaGriff

Haseeb Akhtar'ın kodu Chrome ve Firefox'ta mükemmel çalışıyor, ancak sürpriz !! IE6-9 içinde değil Herhangi bir öneriniz var mı?
Martin Andersen

1

Geri tuşuna basarak navigasyonu önlemenin en kolay yolu

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

Backspcae tuşuna basıldığında gezinmeyi önler ve aynı zamanda tüm giriş denetimlerinde backspace'ye izin verir
Mohammed Irfan Mayan

Ve ilk satırı kaçırmayın .. $ (document) .keydown (function () {
Mohammed Irfan Mayan

3
bu, textareas ve girdiler içindeki düğmeyi devre dışı bırakacaktır
nodrog

1

Dojo araç seti 1.7 kullanarak, bu IE 8'de çalışır:

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

1

Salt okunur metin alanınıza aşağıdaki özelliği eklemenin çok basit bir çözümünü denediniz mi:

onkeydown = "dönüş yanlış;"

Bu, salt okunur bir metin alanında Geri tuşuna basıldığında tarayıcının geçmişe geri dönmesini engeller. Belki gerçek niyetinizi özlüyorum, ancak bu, sorununuz için en basit çözüm gibi görünüyor.


1

Çok daha temiz bir çözüm -

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

Alternatif olarak, yalnızca

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

1

Tüm tarayıcılarda çalışan saf javascript sürümü:

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

Tabii ki "INPUT, TEXTAREA" ve sonra "if (! Regex.test (elements))" kullanabilirsiniz. İlk benim için iyi çalıştı.


1

Verim?

Performans konusunda endişeliydim ve bir keman yaptım: http://jsfiddle.net/felvhage/k2rT6/9/embedded/result/

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

Bu iş parçacığında bulduğum en umut verici yöntemleri analiz ettim. Görünüşe göre hepsi çok hızlıydı ve büyük olasılıkla yazarken "durgunluk" açısından bir soruna neden olmuyor. Baktığım en yavaş Yöntem IE8'deki 10.000 Çağrı için yaklaşık 125 ms idi. Hangi İnme başına 0.0125ms.

Codenepal ve Robin Maben tarafından gönderilen yöntemleri en hızlı ~ 0.001ms (IE8) olarak buldum, ancak farklı semantiğe dikkat edin.

Belki de bu, bu tür işlevselliği koduna tanıtan birine rahatlamadır.


1

Değiştirilmiş erikkallen cevabı:

$(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
Mükemmel cevap. Başkalarından aldığım çözüm firefox'ta işe yaramadı, ancak bu üçünün hepsinde (Firefox, IE ve crome) sorunsuz bir şekilde çalıştı. Teşekkürler Prozi.
Nikhil Dinesh

1

Bu çözüm test edildiğinde çok iyi çalıştı.

Ben girdi ile etiketlenmemiş bazı girdi alanlarını işlemek ve işim için bir giriş formu üreten bir Oracle PL / SQL uygulaması entegre etmek için bazı kod ekledim.

Benim görüşüm":

 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

Şu anda kabul edilen (erikkallen) temiz bir sürümüyle bir NPM projesi oluşturdum

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

Temel olarak aynı ilkeleri kullanır, ancak:

  • Bağımlılık yok
  • İçerik düzeltilebilir destek
  • Daha okunabilir / bakımı kolay kod tabanı
  • Şirketim tarafından üretimde kullanılacağı için desteklenecek
  • MIT lisansı

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

İşte en çok oy alan cevabı yeniden yazmam. Element.value! == undefined'i kontrol etmeye çalıştım (çünkü bazı öğeler html özniteliğine sahip olmayabilir, ancak prototip zincirinde bir yerde bir javascript değeri özelliğine sahip olabilir), ancak bu çok iyi çalışmadı ve çok sayıda kenar durumu vardı. Bunu geleceğe hazırlamanın iyi bir yolu yok gibi görünüyor, bu nedenle bir beyaz liste en iyi seçenek gibi görünüyor.

Bu, olay kabarcık aşamasının sonundaki öğeyi kaydeder, bu nedenle Backspace'i herhangi bir özel şekilde işlemek istiyorsanız, bunu diğer işleyicilerde yapabilirsiniz.

Bu, HTMLTextAreElement örneğini de denetler, çünkü teorik olarak bundan devralan bir web bileşeni olabilir.

Bu, contentEditable'ı kontrol etmez (diğer cevaplarla birleştirin).

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

Sitepoint: Javascript için geri devre dışı bırak

event.stopPropagation()ve event.preventDefault()IE'de hiçbir şey yapma. Gerçi event.keyCode == 11, sadece "if not = 8, run the event"çalışmasını söylemek yerine (sadece bir şey seçtim) dönüş göndermek zorunda kaldı . event.returnValue = falseayrıca çalışır.


0

Jquery kullanan başka bir yöntem

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

Kontroller (metin kutusu) dinamik olarak eklenmişse lütfen bunun çalışmadığını unutmayın.
CodeNepal

0

Bunu bir süredir kodumda kullanıyorum. Öğrenciler için çevrimiçi testler yazdım ve öğrenciler sınavları sırasında geri tuşuna bastıklarında sorunla karşılaştım ve giriş ekranına geri dönecekti. Sinir bozucu! Kesinlikle FF üzerinde çalışır.

document.onkeypress = Backspace;
function Backspace(event) {
    if (event.keyCode == 8) {
        if (document.activeElement.tagName == "INPUT") {
            return true;
        } else {
            return false;
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.