2010-08-19 39 views
27

Bir nokta için location.href değiştiren bir site için bir Greasemonkey komut dosyası yazıyorum.window.location.href değiştiğinde olay

Bir sayfada window.location.href değişiklik olduğunda (window.addEventListener aracılığıyla veya benzer bir şekilde) bir olayı nasıl edinebilirim? Yeni/değiştirilmiş URL'ye işaret eden belgenin DOM'sine de erişmem gerekiyor.

Zaman aşımları ve yoklama içeren başka çözümler gördüm, ancak eğer mümkünse bunu önlemek isterim.

cevap

31

popstate event:

popstate olay aktif tarih girdisi değişiklikleri ateşlenir. [...] popstate olay sadece popstate olaya dinleme ve bir gönderme

Yani böyle geri düğmesini tıklama gibi bir tarayıcı işlemi yaparken (ya JavaScript) (history.back çağırarak) tarafından tetiklenir history.pushState() kullanarak popstate olay href değişikliği harekete geçmeye yeterli olacaktır:

window.addEventListener('popstate', listener); 

const pushUrl = (href) => { 
    history.pushState({}, '', href); 
    window.dispatchEvent(new Event('popstate')); 
}; 
+0

Ancak içerik yüklenmeden önce popstate ateş edecek mi? – user2782001

14

Yoklamadan kaçınamazsınız, href değişimi için herhangi bir olay yoktur.

Aralıkları kullanmak, aşırı gitmezseniz, oldukça hafiftir. Her 50 ms'de bir hrefin kontrol edilmesi, bunun için endişeleniyorsanız performans üzerinde önemli bir etkiye sahip olmayacaktır.

+10

Zebra iyi değil –

+1

@AlexanderMills: Neyse ki bu yeni popstate çözümleri ve hashchange'ler var. –

6

Daha önce denemediniz mi? Bu olay, sayfa bir gezinme isteğine yanıt vermeden hemen önce tetiklenir ve bu, href'in değiştirilmesini içermelidir.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> 
    <HTML> 
    <HEAD> 
    <TITLE></TITLE> 
    <META NAME="Generator" CONTENT="TextPad 4.6"> 
    <META NAME="Author" CONTENT="?"> 
    <META NAME="Keywords" CONTENT="?"> 
    <META NAME="Description" CONTENT="?"> 
    </HEAD> 

     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script> 
      <script type="text/javascript"> 
      $(document).ready(function(){ 
       $(window).unload(
         function(event) { 
          alert("navigating"); 
         } 
       ); 
       $("#theButton").click(
        function(event){ 
         alert("Starting navigation"); 
         window.location.href = "http://www.bbc.co.uk"; 
        } 
       ); 

      }); 
      </script> 


    <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?"> 

     <button id="theButton">Click to navigate</button> 

     <a href="http://www.google.co.uk"> Google</a> 
    </BODY> 
    </HTML> 

bu çünkü script, ya birileri bir bağlantıyı tıklayarak, ister sayfadan ayrılmayın her etkinlik ateş edeceğini, ancak, dikkatli olun. Gerçek meydan okuma, olayın tetiklenmesinin farklı nedenlerini tespit ediyor. (Bu mantığa önemli ise)

+0

Bunun işe yarayıp yaramayacağından emin değilim, çünkü karma değişiklikleri genellikle bir sayfanın yeniden yüklenmesini gerektirmez. – samandmoore

+0

Yeni DOM'a da erişmem gerekiyor, bunu açıklığa kavuşturmak için bu sorunu güncelledim. –

+0

Tamam - 'hash' durumunu dikkate almadı - bunu düşünecek. Yeni DOM'a erişebilmek için, yeni DOM yüklendikten önce olay tetikleneceğinden (bu olayın bir olay işleyicisinden yararlandığı sürece) şanstan yoksun kalırsınız. Mantığı yeni sayfanın asload olayıyla birleştirebilirsiniz, ancak o sayfanın her bir yükü için mantığı yürütmeniz gerekip gerekmediğini belirlemekle ilgili aynı sorunları olabilir. Sayfa akışı dahil, elde etmeye çalıştığınız şeyler hakkında daha fazla bilgi verebilir misiniz? – belugabob

2

kullanabileceğiniz bir varsayılan onhashchange olay yoktur.tarayıcı oldURL desteklemez ve newURL Böyle bağlamak durumunda

function locationHashChanged(e) { 
    console.log(location.hash); 
    console.log(e.oldURL, e.newURL); 
    if (location.hash === "#pageX") { 
     pageX(); 
    } 
} 

window.onhashchange = locationHashChanged; 

:

//let this snippet run before your hashChange event binding code 
if(!window.HashChangeEvent)(function() { 
    let lastURL = document.URL; 
    window.addEventListener("hashchange", function(event) { 
     Object.defineProperty(event, "oldURL", { enumerable: true, configurable: true, value: lastURL }); 
     Object.defineProperty(event, "newURL", { enumerable: true, configurable: true, value: document.URL }); 
     lastURL = document.URL; 
    }); 
}()); 
1

bunu kullanmaktan

Documented HERE

Ve

bu gibi kullanılabilir "Herhangi Bir Medyayı Kestir" komut dosyası ve iyi çalışıyor ( youtube case gibi)

var oldHref = document.location.href; 

window.onload = function() { 

    var 
     bodyList = document.querySelector("body") 

     ,observer = new MutationObserver(function(mutations) { 

      mutations.forEach(function(mutation) { 

       if (oldHref != document.location.href) { 

        oldHref = document.location.href; 

        /* Changed ! your code here */ 

       } 

      }); 

     }); 

    var config = { 
     childList: true, 
     subtree: true 
    }; 

    observer.observe(bodyList, config); 

};