Geri düğmesini tıkladığınızda tarayıcılar arası bir yükleme olayı var mı?


185

Tüm büyük tarayıcılarda (IE hariç), onloadbir geri düğmesi işlemi sonucunda sayfa yüklendiğinde JavaScript etkinliği tetiklenmez; yalnızca sayfa ilk yüklendiğinde tetiklenir.

Birisi bana bu sorunu çözen örnek bir çapraz tarayıcı koduna (Firefox, Opera, Safari, IE,…) işaret edebilir mi? Firefox'un pageshowetkinliğine aşinayım ama ne yazık ki ne Opera ne de Safari bunu uyguluyor.


6
Bu bir sorun değildir - kullanıcı Geri düğmesine bastığında web sayfasının hızla yüklenmesini sağlar. Ayrıntılar için aşağıdaki cevabıma bakın. Burada önerilen geçici çözümler, web sayfasını kullanıcı için daha can sıkıcı hale getirir, çünkü geri / ileri gitme daha yavaştır.
Nickolay

2
@romkyns: yorumunuz bu soru ile ilgili değil. Tarayıcılar JS / DOM durumunu geri yüklemediğinde, load olayını başlatır.
Nickolay

iOS 5+ geçmişi geri düğmesi burada çözüldü stackoverflow.com/a/12652160/1090395
Mladen Janjetovic

Yanıtlar:


117

Çocuklar, JQuery'nin sadece bir etkisi olduğunu buldum: geri düğmesine basıldığında sayfa yeniden yüklenir. Bunun " hazır " ile bir ilgisi yok .

Bu nasıl çalışıyor? JQuery bir onunload olay dinleyicisi ekliyor .

// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...

Varsayılan olarak hiçbir şey yapmaz. Ancak bir şekilde bu, olay işleyicinin içeriği ne olursa olsun Safari, Opera ve Mozilla'da yeniden yüklemeyi tetikliyor gibi görünüyor.

[ edit (Nickolay) : işte neden böyle çalışıyor: webkit.org , developer.mozilla.org . Lütfen bu makaleleri okuyun (veya aşağıdaki ayrı bir yanıtta özetimi) ve bunu gerçekten yapmanız gerekip gerekmediğini düşünün ve sayfanızın kullanıcılarınız için daha yavaş yüklenmesini sağlayın.]

İnanamıyor musunuz? Bunu dene:

<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

JQuery kullanırken benzer sonuçlar göreceksiniz.

Bunu onun yüklemesi olmadan karşılaştırmak isteyebilirsiniz

<body><!-- Will not reload on back button -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

1
Çok güzel .. rağmen bu belgesiz bir özellik / hata olsa da, ve sadece tarayıcının gelecekteki sürümlerinde çalışmayı durdurabilir, ama yine de ilginç.
Wadih M.

3
Bu da işe yarar (onunload = "" bölümünü unutmayın, aksi takdirde ff3 üzerinde çalışmaz): <body onload = "alert ('onload');" onunload = "">
Wadih M.

3
Bunun nedeni, tarayıcının bir onunloadişleyici varsa sayfanın önbelleğe alınamayacağını varsaymasıdır (sayfa her şeyi zaten yok etmiştir; neden önbelleğe alıyor?).
Casey Chu

14
Yanıt modern tarayıcılarda çalışmıyor gibi görünüyor - en son Chrome ve Opera'da kontrol edildi
Andrew

10
iPad
safari'de

74

Bazı modern tarayıcılar (Firefox, Safari ve Opera, ancak Chrome değil), kullanıcı Geri gittiğinde dahil olan özel "geri / ileri" önbelleği (Mozilla tarafından icat edilen bir terim olan bfcache olarak adlandıracağım) destekler. Normal (HTTP) önbelleğin aksine, sayfanın tüm durumunu (JS, DOM durumu dahil) yakalar. Bu, sayfayı daha hızlı ve kullanıcının bıraktığı gibi yeniden yüklemesini sağlar.

loadSayfası bu bfcache gelen yüklendiğinde olay yangın olmaması gerekir. Örneğin, kullanıcı arayüzünüzü "load" işleyicisinde oluşturduysanız ve "load" olayı ilk yüklemede bir kez tetiklendiğinde ve sayfanın bfcache'den yeniden yüklendiği ikinci seferde sayfa sona erer yinelenen kullanıcı arabirimi öğeleri.

"Boşaltma" işleyicisinin eklenmesi, sayfanın bfcache'de depolanmasını durdurur (böylece geri dönmeyi yavaşlatır) - boşaltma işleyicisi, sayfayı işlenemez durumda bırakabilecek temizleme görevleri gerçekleştirebilir.

Ne zaman uzağa / geriye gittiklerini bilmeleri gereken sayfalar için Firefox 1.5+ ve Safari sürümü hata 28758 düzeltmesi ile "sayfa gösterisi" ve "sayfa gizleme" adı verilen özel etkinlikleri destekler.

Referanslar:


Çok güzel. Şu anda dom manipülasyonlarım bfcache'de kaydedilmiş gibi görünmeyen bir durumdayım. Bunu bekleyebileceğiniz durumlar var mı?
Benson

1
@Benson: Firefox'un sayfanızı bfcache'ye kaydetmemesinin olası nedenleri, bağlandığım dev.mo sayfasında listeleniyor. Sayfayı bfcache'e kaydetmenin mümkün olduğunu düşünmüyorum, ancak belirli DOM durumları kaydedilmedi.
Nickolay

Nickolay, yeniden yüklemeyi zorlamak ve bfcache tarafından yapılan iyi işleri geri almak için isteksizliğinizi alıyorum, ancak bfcache'deki sayfanın domunu güncellemenin başka bir yolu var mı? Örneğin, bunlardan birine mesaj listesi olan bir sayfadan gittiğim ve "geri" gittiğimde, okunan / okunmayan göstergenin değişmesini istiyorum. Bu, sayfayı yeniden yüklemeden nasıl yapılabilir?
Greg

@Greg: sayfayı kontrol eden bir geliştirici mi demek istiyorsun? 'Pageshow' dinleyicisinden bir ajax isteği başlatın.
Nickolay

JQuery VE hızlı bfcache desteği almak hakkında herhangi bir fikir?
Alex Black

31

Kullanıcı geri veya ileri tıkladığında benim js yürütme bir sorunla karşılaştı. İlk olarak tarayıcının önbelleğe alınmasını durdurmak için yola çıktım, ancak bu sorun değildi. Javascript tüm kütüphaneler vs. yüklendikten sonra çalıştırılacak şekilde ayarlandı. Bunları readyStateChange olayıyla kontrol ettim.

Bazı testlerden sonra, bir sayfadaki geri tıklanan öğenin readyState öğesinin 'yüklü' değil 'tamamlanmış' olduğunu öğrendim. || element.readyState == 'complete'Koşullu ifademe eklemek sorunlarımı çözdü.

Sadece bulgularımı paylaşacağımı düşündüm, umarım başka birine yardım ederler.

Tamlık için düzenleyin

Kodum aşağıdaki gibi görünüyordu:

script.onreadystatechange(function(){ 
   if(script.readyState == 'loaded' || script.readyState == 'complete') {
      // call code to execute here.
   } 
});

Yukarıdaki kod örneğinde kod değişkeni, DOM'a eklenmiş yeni oluşturulan bir komut öğesi idi.


7
Bunu nereye ekledin? Kullanıcı geri döndükten sonra nasıl bir şey yaktınız? Lütfen bize bir kod gösterin!
Keerigan

"Koşullu ifadem" dediğinde ne demek istiyorsun?
Phillip Senn

1
@Phillip Koşullu bir ifade bir if deyimidir.
Brian Heese

22

Tamam, işte ckramer'in ilk çözümüne ve Opera dahil tüm tarayıcılarda çalışan solgunluk örneğine dayanan son bir çözüm. History.navigationMode öğesini 'uyumlu' olarak ayarlarsanız, jQuery'nin hazır işlevi Opera'daki ve diğer ana tarayıcılardaki Geri düğmesi işlemlerinde etkinleşir.

Bu sayfada daha fazla bilgi var .

Misal:

history.navigationMode = 'compatible';
$(document).ready(function(){
  alert('test');
});

Bunu Opera 9.5, IE7, FF3 ve Safari'de test ettim ve hepsinde çalışıyor.


2
Açıkçası bir süredir (yaklaşık 5.5 yıl) ama bağlantınızın öldüğünü belirtmek gerekir.
Jeff

2
Bu çözüm benim için işe yaramıyor. Bu sorunu en son Firefox'ta aldım (45.0.1)
Armin

6

Yukarıdaki örnekleri çalıştıramadım. Geri düğmesine basarak sayfaya geri döndüğünüzde, bazı değiştirilmiş div alanlarının yenilenmesini tetiklemek istedim. Kullandığım hileler, div alanları orijinalden değiştiği anda gizli bir girdi alanı ("kirli bit" olarak adlandırılır) 1 olarak ayarlamaktı. Gizli girdi alanı aslında geri tıkladığımda değerini koruyor, bu yüzden onload bu biti kontrol edebilirim. Ayarlanmışsa, sayfayı yenilerim (veya yalnızca div'ları yenilerim). Ancak orijinal yükte bit ayarlanmadı, bu yüzden sayfayı iki kez yüklemek için zaman kaybetmiyorum.

<input type='hidden' id='dirty'>

<script>
$(document).ready(function() {
  if ($('#dirty').val()) {
    // ... reload the page or specific divs only
  }
  // when something modifies a div that needs to be refreshed, set dirty=1
  $('#dirty').val('1');
});
</script>

Ve geri düğmesine her tıkladığımda düzgün tetiklenir.


3
Bu Firefox'ta çalışmadığı halde, gizli alanın kalıcılığının çok yararlı olduğu IE / Chrome'daki durumu ele almanın kurnaz bir yolu olduğunu düşünüyorum. Senin hile ve "sayfa gösterisi" etkinliğini kullandım, bu yüzden tüm ana tarayıcıları kapsar.
Magnus Smith

Hangi tarayıcı bunun gösterdiği sayfa gösterisi ile çalışmaz?
Justin

4

Doğru hatırlıyorsam, bir unload () olayı eklemek sayfanın önbelleğe alınamayacağı (ileri / geri önbellekte) anlamına gelir - çünkü kullanıcı uzaklaştığında durum değişir / değişebilir. Bu nedenle, geçmiş nesnesinde gezinerek sayfaya geri dönerken sayfanın son ikinci durumunu geri yüklemek güvenli değildir.


4

Bunun "load" için olduğunu düşündüm, sayfa yükleme için değil, çünkü "Back" tuşuna basarken bir olayı tetiklemekten bahsetmiyoruz mu? $ document.ready (), söz konusu sayfaya nasıl ulaşırsanız bakın (ör. yönlendirin, tarayıcıyı doğrudan URL'ye açın, vb.), "Geri" düğmesini tıklattığınızda değil, sayfa yüklemesinde istenen etkinlikler içindir tekrar yüklendiğinde önceki sayfada ne tetikleneceği hakkında. Ve $ document.ready () dahil edildiğinde bile, Javascripts'in hala olduğunu bulduğumdan sayfanın önbelleğe alınmadığından emin değilim. Bu etkinliğe sahip scriptlerimizi her değiştirdiğimizde düzenlerken Ctrl + F5 tuşlarına basmak zorunda kaldık ve sonuçları sayfalarımızda test etmek istiyoruz.

$(window).unload(function(){ alert('do unload stuff here'); }); 

"Geri" tuşuna basarken ve geçerli sayfayı kaldırırken onunload olayı için istediğiniz şeydir ve kullanıcı tarayıcı penceresini kapattığında da tetiklenir. Bu, $ document.ready () yanıtlarıyla sayıca fazla olmasam bile, istenen gibi görünüyordu. Temel olarak, geçerli sayfa kapanırken tetiklenen bir etkinlikle yüklenirken "Geri" tıklandığında yüklenen bir etkinlik arasındaki farktır. IE 7'de test edildi, nerede olduğumuza izin verilmediği için diğer tarayıcılar için konuşamıyor. Ancak bu başka bir seçenek olabilir.


4

Ckramer'ı jQuery'nin hazır etkinliğinin IE ve FireFox'ta çalıştığını doğrulayabilirim. İşte bir örnek:

<html>
<head>
    <title>Test Page</title>
    <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
    <script type="text/javascript">
            $(document).ready(function () {
               var d = new Date();
               $('#test').html( "Hi at " + d.toString() );
            });
    </script>
</head>
<body>
    <div id="test"></div>
    <div>
        <a href="http://www.google.com">Go!</a>
    </div>
</body>
</html>

4

Bütün jquery kütüphanesini kullanmak istemeyenler için ayrı kodda uygulamayı çıkardım. Sadece 0,4 KB büyüklüğünde.

Kodu, bu wiki'de bir Almanca eğitimi ile birlikte bulabilirsiniz: http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html


1
Yalnız bağlantı zayıf bir cevap olarak kabul edilir ( sss'e bakın ) çünkü kendiliğinden anlamsızdır ve hedef kaynağın gelecekte hayatta olacağı garanti edilmez . Cevabın temel bölümlerini buraya dahil etmek ve referans için bağlantı sağlamak tercih edilir.
j0k

3

jQuery'nin hazır etkinliği sadece bu tür bir sorun için yaratıldı. Kapakların altında neler olup bittiğini görmek için uygulamayı incelemek isteyebilirsiniz.


6
Uzun bir süre sonra, readyGeri düğmesini kullanırken Firefox'ta tetiklenmiş gibi görünmüyor. Ayrıca bkz . Nickolay'ın cevabı .
Arjan

2

Bill, sorunuzu cevaplamaya cesaret ediyorum, ancak tahminlerimden% 100 emin değilim. Ben geçmişte bir sayfaya kullanıcı alırken diğer IE tarayıcılar sadece sayfa ve kaynaklarını önbellekten yüklemek değil, aynı zamanda bunun için tüm DOM (okuma oturumu) durumunu geri yükleyeceğini düşünüyorum. IE, DOM geri yüklemesi yapmaz (veya kiralamada yapmaz) ve dolayısıyla onload olayı, sayfanın uygun şekilde yeniden başlatılması için gerekli görünmektedir.


2

Ben çözüm $ (belge) kullanarak Bill denedim. Zaten ... ama ilk başta işe yaramadı. Komut dosyası html bölümünden sonra yerleştirilirse, işe yaramayacağını keşfettim. Kafa bölümü ise, sadece IE'de çalışacaktır. Komut dosyası Firefox'ta çalışmıyor.


1

Tamam, bunu denedim ve Firefox 3, Safari 3.1.1 ve IE7'de çalışıyor, ancak Opera 9.52'de çalışmıyor .
Aşağıda gösterilen örneği (soluk atı örneğine göre) kullanırsanız, sayfa ilk yüklendiğinde bir uyarı kutusu açılır penceresi görüntülenir. Ancak daha sonra başka bir URL'ye gidip bu sayfaya geri dönmek için Geri düğmesine basarsanız, Opera'da bir uyarı kutusu açılır penceresi almazsınız (ancak diğer tarayıcılarda yaparsınız).

Her neyse, bunun şimdilik yeterince yakın olduğunu düşünüyorum. Herkese teşekkürler!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta http-equiv="expires" content="0">
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready( 
                    function(){
                      alert('test');
                    }
                 );
</script>
</head>
<body>
<h1>Test of the page load event and the Back button using jQuery</h1>
</body>
</html>

1

Unload olay IE 9 üzerinde iyi çalışmıyor. Ben load olay (onload ()) ile denedim, IE 9 ve FF5 üzerinde iyi çalışıyor .

Misal:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    jQuery(window).bind("load", function() {
        $("[name=customerName]").val('');
    });
</script>
</head>
<body>
    <h1>body.jsp</h1>
    <form action="success.jsp">
        <div id="myDiv">

        Your Full Name: <input name="yourName" id="fullName"
            value="Your Full Name" /><br> <br> <input type="submit"><br>

        </div>

    </form>
</body>
</html>

0

Bir html şablonu kullandım. Bu şablonun custom.js dosyasında şöyle bir işlev vardı:

    jQuery(document).ready(function($) {

       $(window).on('load', function() {
          //...
       });

    });

Ancak başka bir sayfaya gittikten sonra geri döndüğümde bu işlev çalışmadı.

Yani, bunu denedim ve işe yaradı:

    jQuery(document).ready(function($) {
       //...
    });

   //Window Load Start
   window.addEventListener('load', function() {
       jQuery(document).ready(function($) {
          //...
       });
   });

Şimdi, 2 "hazır" fonksiyonum var ama herhangi bir hata vermiyor ve sayfa çok iyi çalışıyor.

Yine de, Windows 10 - Opera v53 ve Edge v42'de test edildiğini, ancak başka tarayıcılarda olmadığını beyan etmeliyim. Bunu aklınızda bulundurun ...

Not: jquery sürümü 3.3.1 ve geçiş sürümü 3.0.0 idi

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.