ตรวจสอบว่าหน้าได้รับการโหลดซ้ำหรือรีเฟรชใน JavaScript


186

ฉันต้องการตรวจสอบเมื่อมีคนพยายามรีเฟรชหน้า

ตัวอย่างเช่นเมื่อฉันเปิดหน้าไม่มีอะไรเกิดขึ้น แต่เมื่อฉันรีเฟรชหน้ามันควรจะแสดงการแจ้งเตือน


1
เป็นไปไม่ได้จริงๆหากไม่มีรหัสฝั่งเซิร์ฟเวอร์ คุณต้องการอะไร บางทีถ้าคุณให้ภาพที่ใหญ่ขึ้นเราสามารถแนะนำทางเลือกที่ดีกว่า
Shadow Wizard คือ Ear For You

บางทีคุณอาจจะทำเช่นกับคุกกี้ ... เช่นจัดเก็บเวลาและโหลดซ้ำเปรียบเทียบความแตกต่างของเวลา
เฟลิกซ์ลิ่ง

ฉันต้องการที่จะทำเช่นลิงค์ Facebook จะเป็น #! / whate ฉันต้องการลบ #! เมื่อโหลดหน้าซ้ำเท่านั้น
Ahmed

1
@ อาเหม็ดฉันพยายามทำสิ่งเดียวกัน วิธีแก้ปัญหาด้านล่างใช้ได้กับคุณหรือไม่?
พอลฟิตซ์เจอรัลด์

3
⚠️⚠️⚠️ window.performance.navigation.typeเลิกกรุณาดูคำตอบของฉัน
ИльяЗеленько

คำตอบ:


221

⚠️⚠️⚠️ window.performance.navigation.typeเลิกใช้แล้วโปรดดูคำตอบของИльяЗеленько


วิธีที่ดีกว่าที่จะทราบว่าเพจนั้นถูกโหลดใหม่จริงๆคือการใช้วัตถุนำทางที่ได้รับการสนับสนุนโดยเบราว์เซอร์ที่ทันสมัยที่สุด

จะใช้ระยะเวลา API

//check for Navigation Timing API support
if (window.performance) {
  console.info("window.performance works fine on this browser");
}
  if (performance.navigation.type == 1) {
    console.info( "This page is reloaded" );
  } else {
    console.info( "This page is not reloaded");
  }

แหล่งที่มา: https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API


1
ขอบคุณเพื่อนนี่เป็นวิธีที่แม่นยำในการตรวจสอบว่าหน้าถูกโหลดจากคลิกขวา / รีเฟรชจากเบราว์เซอร์หรือโหลดโดย url
Roque Mejos

4
โปรดทราบ Chrome เพิ่งเปลี่ยนพฤติกรรมนี้ เมื่อผู้ใช้คลิกที่แถบที่อยู่ปัจจุบันและกด Enter ค่าของ performance.navigation.type จะเป็น 1 ซึ่งควรเป็น 0 ฉันทดสอบในเวอร์ชัน 56 ไม่แน่ใจว่าทำไม
Jackwin tung

1
วิธีการทำงานเป็นไปตามที่คาดไว้การโต้ตอบใด ๆ กับเพจที่บังคับให้สถานะการนำทางใหม่ไปยังหน้าเดียวกันนั้นถือเป็นการรีเฟรช ดังนั้นขึ้นอยู่กับโค้ดของคุณซึ่งมีประโยชน์อย่างมากไม่ว่าจะลงทะเบียนทุกครั้งที่หน้าเว็บรีเฟรชรีโหลดหรือการตอบกลับ ajax ฉันสามารถใช้ประโยชน์มากมายสำหรับฟังก์ชันและการวิเคราะห์นี้
raphie

27
performance.navigation.type == performance.navigation.TYPE_RELOAD== 1ง่ายต่อการอ่านแทน นอกจากนี้ถ้าคุณตรวจสอบperformance.navigationคุณจะพบว่ามี 4 ประเภทที่แตกต่างกันเช่นนำทางTYPE_BACK_FORWARD,TYPE_NAVIGATE
Vitalij Kornijenko

5
⚠️⚠️⚠️ window.performance.navigation.typeเลิกกรุณาดูคำตอบของฉัน
ИльяЗеленько

37

ขั้นแรกคือการตรวจสอบsessionStorageค่าที่กำหนดไว้ล่วงหน้าและหากมีผู้ใช้แจ้งเตือนอยู่:

if (sessionStorage.getItem("is_reloaded")) alert('Reloaded!');

ขั้นตอนที่สองคือตั้งค่าsessionStorageเป็นบางค่า (ตัวอย่างtrue):

sessionStorage.setItem("is_reloaded", true);

ค่าเซสชันถูกเก็บไว้จนกว่าจะปิดหน้าดังนั้นมันจะทำงานเฉพาะเมื่อหน้าโหลดซ้ำในแท็บใหม่กับไซต์ คุณยังสามารถนับจำนวนการโหลดซ้ำได้เช่นเดียวกัน


28
สองสิ่งที่ควรระวัง: 1) คุณสามารถเก็บค่าสตริงในเซสชั่นและการจัดเก็บในท้องถิ่น ดังนั้นจะถูกแปลงเป็นtrue "true"2) ที่จัดเก็บเซสชันยังคงอยู่จนกว่าผู้ใช้จะปิดหน้าต่างเบราว์เซอร์ดังนั้นคุณจึงไม่สามารถบอกความแตกต่างระหว่างการโหลดหน้าซ้ำและการนำทางออกจากและกลับไปยังไซต์ของคุณภายในเซสชันเบราว์เซอร์เดียวกัน
เฮ็กเตอร์

35

ใหม่มาตรฐาน 2018 ตอนนี้ (PerformanceNavigationTiming)

window.performance.navigationคุณสมบัติเลิกใช้แล้วในข้อมูลจำเพาะการนำทางระดับที่ 2 กรุณาใช้PerformanceNavigationTimingส่วนต่อประสานแทน

PerformanceNavigationTiming.type

นี่คือเทคโนโลยีทดลองเทคโนโลยีการทดลอง

ตรวจสอบตารางความเข้ากันได้ของเบราว์เซอร์อย่างรอบคอบก่อนที่จะใช้สิ่งนี้ในการผลิต

สนับสนุนปี 2019-07-08

คุณสมบัติ type read-only จะส่งคืนสตริงที่แทนชนิดของการนำทาง ค่าต้องเป็นอย่างใดอย่างหนึ่งต่อไปนี้:

  • การนำทาง - การนำทางเริ่มต้นโดยการคลิกที่ลิงค์ป้อน URL ในแถบที่อยู่ของเบราว์เซอร์การส่งแบบฟอร์มหรือการเริ่มต้นผ่านการดำเนินการของสคริปต์นอกเหนือจากการโหลดซ้ำและย้อนกลับไปข้างหน้าตามที่แสดงด้านล่าง

  • โหลด - location.reload()นำร่องคือผ่านการดำเนินการโหลดเบราว์เซอร์หรือ

  • back_forward - การนำทางผ่านการดำเนินการสำรวจเส้นทางของเบราว์เซอร์

  • Prerender - นำร่องจะเริ่มด้วยคำใบ้ Prerender

คุณสมบัตินี้เป็นแบบอ่านอย่างเดียว

ตัวอย่างต่อไปนี้แสดงการใช้งานของคุณสมบัตินี้

function print_nav_timing_data() {
  // Use getEntriesByType() to just get the "navigation" events
  var perfEntries = performance.getEntriesByType("navigation");

  for (var i=0; i < perfEntries.length; i++) {
    console.log("= Navigation entry[" + i + "]");
    var p = perfEntries[i];
    // dom Properties
    console.log("DOM content loaded = " + (p.domContentLoadedEventEnd - p.domContentLoadedEventStart));
    console.log("DOM complete = " + p.domComplete);
    console.log("DOM interactive = " + p.interactive);

    // document load and unload time
    console.log("document load = " + (p.loadEventEnd - p.loadEventStart));
    console.log("document unload = " + (p.unloadEventEnd - p.unloadEventStart));

    // other properties
    console.log("type = " + p.type);
    console.log("redirectCount = " + p.redirectCount);
  }
}

4
+1 สำหรับการชี้ API ที่เลิกใช้แล้ว แต่ -100 ถึง Apple สำหรับการขาดการสนับสนุนใน iOS ยังคงเป็น 2020
kinakuta

14

จัดเก็บคุกกี้ในครั้งแรกที่มีคนเยี่ยมชมหน้าเว็บ ในการรีเฟรชตรวจสอบว่ามีคุกกี้ของคุณอยู่หรือไม่

function checkFirstVisit() {
  if(document.cookie.indexOf('mycookie')==-1) {
    // cookie doesn't exist, create it now
    document.cookie = 'mycookie=1';
  }
  else {
    // not first visit, so alert
    alert('You refreshed!');
  }
}

และในแท็กร่างกายของคุณ:

<body onload="checkFirstVisit()">

9
สิ่งที่เกี่ยวกับผู้ใช้ที่กลับมา?
Red Taz

5
เช่นเดียวกับ @ Rob2211 บอกว่านี่เป็นการตรวจสอบเพียงว่าหน้าได้รับการเยี่ยมชมและสามารถให้บวกปลอมตราบใดที่มีการเข้าชมหน้าเมื่อคุกกี้ยังคงมีชีวิตอยู่ อย่าใช้สิ่งนี้เพื่อตรวจสอบการรีเฟรช
Brannon

@Brannon - คุกกี้ถูกสร้างขึ้นโดยไม่มีค่าหมดอายุและจะถูกทำลายเมื่อปิดเบราว์เซอร์
techfoobar

1
@ techfoobar จับดี สิ่งนี้จะยังคงเป็นปัญหาหรือไม่หากผู้ใช้เยี่ยมชมไซต์ก่อนที่คุกกี้นั้นจะถูกทำลาย?
Brannon

3
@Brannon - ใช่ถ้าเบราว์เซอร์เปิดทิ้งไว้และผู้ใช้เข้าชมอีกครั้งหลังจากนั้นจะไม่ถือว่าเป็นการเข้าชมครั้งใหม่
techfoobar

7

ถ้า

event.currentTarget.performance.navigation.type

ผลตอบแทน

0 => ผู้ใช้เพิ่งพิมพ์ Url
1 => โหลดหน้าซ้ำ
2 => ปุ่มย้อนกลับคลิก


ฉันพบข้อผิดพลาดนี้คุณช่วยอธิบายเพิ่มเติมได้ไหม Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'currentTarget' ของที่ไม่ได้กำหนด
Janatbek Sharsheyev

2 => TYPE_BACK_FORWARD หน้าถูกเข้าถึงโดยไปที่ประวัติ developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigation
Tiago Freitas Leal

performance.navigation.typeจะเลิกกรุณาดูคำตอบของฉัน
ИльяЗеленько

6

ผมพบว่าข้อมูลบางอย่างที่นี่Javascript ตรวจจับหน้ารีเฟรช คำแนะนำแรกของเขาคือการใช้เขตข้อมูลที่ซ่อนอยู่ซึ่งมีแนวโน้มที่จะถูกเก็บไว้ผ่านการรีเฟรชหน้า

function checkRefresh() {
    if (document.refreshForm.visited.value == "") {
        // This is a fresh page load
        document.refreshForm.visited.value = "1";
        // You may want to add code here special for
        // fresh page loads
    } else {
        // This is a page refresh
        // Insert code here representing what to do on
        // a refresh
    }
}
<html>

<body onLoad="JavaScript:checkRefresh();">
    <form name="refreshForm">
        <input type="hidden" name="visited" value="" />
    </form>

</body>

</html>


นอกจากนี้เรายังสามารถตรวจสอบได้โดยการตรวจสอบRefererคุณสมบัติและแก้ไขการตอบสนองของเซิร์ฟเวอร์ตามคุณสมบัตินี้
Adeel

หมายเหตุด้านข้าง: วิธีแรกที่แสดงรายการในหน้านั้นจะล้มเหลวเนื่องจากรหัสกำลังทำงานก่อนที่จะมีการแยกวิเคราะห์ DOM การย้าย<script>องค์ประกอบไปที่ด้านล่างจะใช้งานได้ - แต่ก็ยังไม่ใช่โซลูชันที่รับประกันได้ (และไม่ใช่วิธีคุกกี้)
Andy E

1
@Adeel: การตรวจสอบRefererไม่น่าเชื่อถืออย่างใดอย่างหนึ่ง; พร็อกซีและส่วนขยายเบราว์เซอร์จำนวนมากตัดออกจากคำขอ
Andy E

@VoronoiPotato โปรดลองสรุปข้อมูลแทนการโพสต์ลิงค์เท่านั้น
Dallin

1
สำหรับฉันมันจะดำเนินการ "ถ้า" เงื่อนไขและไม่เคยดำเนินการส่วน "อื่น" ไม่สำคัญว่าฉันได้โหลดหน้าเว็บหรือรีเฟรชหน้า
Parth Vora

6

ฉันได้เขียนฟังก์ชันนี้เพื่อตรวจสอบทั้งสองวิธีโดยใช้วิธีเก่าwindow.performance.navigationและใหม่performance.getEntriesByType("navigation")ในเวลาเดียวกัน:

function navigationType(){

    var result;
    var p;

    if (window.performance.navigation) {
        result=window.performance.navigation;
        if (result==255){result=4} // 4 is my invention!
    }

    if (window.performance.getEntriesByType("navigation")){
       p=window.performance.getEntriesByType("navigation")[0].type;

       if (p=='navigate'){result=0}
       if (p=='reload'){result=1}
       if (p=='back_forward'){result=2}
       if (p=='prerender'){result=3} //3 is my invention!
    }
    return result;
}

คำอธิบายผลลัพธ์:

0:คลิกลิงก์การป้อน URL ในแถบที่อยู่ของเบราว์เซอร์การส่งแบบฟอร์มการคลิกบุ๊กมาร์กการเริ่มต้นการทำงานของสคริปต์

1:คลิกปุ่มโหลดใหม่หรือใช้งานLocation.reload()

2:การทำงานกับประวัติการเรียกดู (Bakc and Forward)

3:กิจกรรมแสดงผลล่วงหน้าเช่น<link rel="prerender" href="https://stackoverflow.com//example.com/next-page.html">

4:วิธีอื่นใด


1

ฉันพบข้อมูลบางอย่างที่นี่ Javascript Detecting Page Refresh

function UnLoadWindow() {
    return 'We strongly recommends NOT closing this window yet.'
}

window.onbeforeunload = UnLoadWindow;

3
ที่นี่ที่ไหน" ? คุณลืมลิงค์หรือไม่
ᴄʀᴏᴢᴇᴛ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.