วิธีตรวจจับเหตุการณ์ปุ่มย้อนกลับของเบราว์เซอร์ - เบราว์เซอร์ข้าม


219

คุณจะตรวจสอบอย่างชัดเจนว่าผู้ใช้กดปุ่มย้อนกลับในเบราว์เซอร์อย่างไรหรือไม่?

คุณบังคับใช้ปุ่มย้อนกลับในหน้าภายในเว็บแอปพลิเคชันหน้าเดียวโดยใช้#URLระบบได้อย่างไร

ทำไมบนโลกไม่เบราว์เซอร์ปุ่มย้อนกลับยิงเหตุการณ์ของตัวเอง!?


2
ฉันต้องการเพิ่มกิจกรรมการนำทาง (ย้อนกลับ / ไปข้างหน้า) ในบางครั้ง จนถึงตอนนี้สิ่งที่อยู่ในผลงานdeveloper.mozilla.org/en-US/docs/Web/API/ …
llaaalu

คำตอบ:


184

(หมายเหตุ: ตามข้อเสนอแนะของ Sharky ฉันได้รวมรหัสเพื่อตรวจหา backspaces)

ดังนั้นฉันจึงเห็นคำถามเหล่านี้บ่อยๆเกี่ยวกับ SO และเมื่อเร็ว ๆ นี้พบปัญหาในการควบคุมการทำงานของปุ่มย้อนกลับด้วยตัวเอง หลังจากสองสามวันของการค้นหาทางออกที่ดีที่สุดสำหรับแอปพลิเคชันของฉัน (Single-Page ด้วยการนำทางแฮช) ฉันมาพร้อมกับเบราว์เซอร์ที่เรียบง่ายและระบบที่ไม่มีไลบรารีเพื่อตรวจหาปุ่มย้อนกลับ

คนส่วนใหญ่แนะนำให้ใช้:

window.onhashchange = function() {
 //blah blah blah
}

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

เพื่อให้เค้าร่างทั่วไปของระบบของฉันฉันกำลังเติมอาเรย์ด้วยแฮชก่อนหน้านี้เมื่อผู้ใช้ของฉันเลื่อนผ่านอินเทอร์เฟซ ดูเหมือนว่า:

function updateHistory(curr) {
    window.location.lasthash.push(window.location.hash);
    window.location.hash = curr;
}

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

ฉันยังใช้ปุ่มย้อนกลับในหน้าซึ่งจะย้ายผู้ใช้ระหว่างหน้าเว็บที่ใช้lasthashอาร์เรย์ ดูเหมือนว่านี้:

function goBack() {
    window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
    //blah blah blah
    window.location.lasthash.pop();
}

ดังนั้นสิ่งนี้จะย้ายผู้ใช้กลับไปที่แฮชสุดท้ายและลบแฮชสุดท้ายออกจากอาร์เรย์ (ฉันไม่มีปุ่มไปข้างหน้าในขณะนี้)

ดังนั้น. ฉันจะตรวจสอบว่าผู้ใช้ใช้ปุ่มย้อนกลับในหน้าของฉันหรือปุ่มเบราว์เซอร์ได้อย่างไร

ตอนแรกฉันดูที่window.onbeforeunloadแต่ไม่มีประโยชน์ - ที่เรียกว่าเฉพาะเมื่อผู้ใช้จะเปลี่ยนหน้า สิ่งนี้ไม่ได้เกิดขึ้นในแอปพลิเคชันหน้าเดียวโดยใช้การนำทางแฮช

ดังนั้นหลังจากการขุดเพิ่มเติมฉันเห็นคำแนะนำสำหรับการพยายามตั้งค่าตัวแปรธง ปัญหาของเรื่องนี้ในกรณีของฉันคือฉันจะพยายามตั้งค่า แต่ทุกอย่างไม่ตรงกันมันจะไม่ถูกตั้งเวลาเสมอสำหรับคำสั่ง if ในการเปลี่ยนแปลงแฮช .onMouseDownไม่ได้ถูกเรียกใช้เสมอในการคลิกและการเพิ่มลงใน onclick จะไม่ทำให้มันเร็วพอ

นี่คือเมื่อผมเริ่มที่จะมองไปที่ความแตกต่างระหว่างและdocument windowทางออกสุดท้ายของฉันคือการตั้งธงใช้และปิดการใช้งานโดยใช้document.onmouseoverdocument.onmouseleave

สิ่งที่เกิดขึ้นคือในขณะที่เมาส์ของผู้ใช้ที่อยู่ภายในพื้นที่เอกสาร (อ่าน: แสดงผลหน้า แต่ไม่รวมกรอบเบราว์เซอร์), trueบูลของฉันมีการตั้งค่า falseเร็วที่สุดเท่าที่เมาส์ออกจากพื้นที่เอกสารบูลพลิกไป

ด้วยวิธีนี้ฉันสามารถเปลี่ยนwindow.onhashchangeเป็น:

window.onhashchange = function() {
    if (window.innerDocClick) {
        window.innerDocClick = false;
    } else {
        if (window.location.hash != '#undefined') {
            goBack();
        } else {
            history.pushState("", document.title, window.location.pathname);
            location.reload();
        }
    }
}

#undefinedคุณจะได้ทราบการตรวจสอบสำหรับ นี่เป็นเพราะหากไม่มีประวัติในอาร์เรย์ของฉันมันจะกลับundefinedมา ฉันใช้สิ่งนี้เพื่อถามผู้ใช้ว่าพวกเขาต้องการออกจากwindow.onbeforeunloadกิจกรรมหรือไม่

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

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

และคุณมีมัน วิธีที่ง่ายและสามส่วนในการตรวจสอบการใช้ปุ่มย้อนกลับเทียบกับองค์ประกอบในหน้าเกี่ยวกับการนำทางแฮช

แก้ไข:

เพื่อให้แน่ใจว่าผู้ใช้ไม่ได้ใช้ backspace เพื่อทริกเกอร์เหตุการณ์ย้อนกลับคุณสามารถรวมสิ่งต่อไปนี้ (ขอบคุณ @thetoolman ในคำถามนี้ ):

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

5
1 ความคิดที่ดี แต่ผมคิดว่าเรื่องนี้จะล้มเหลวถ้าใช้ผู้ใช้สิ่งที่แป้นพิมพ์ลัดสำหรับ "ย้อนกลับ" (ปุ่ม Backspace บน Firefox) ในขณะที่เมาส์ของเขาเป็นหน้าต่างเบราว์เซอร์ภายใน
Sharky

3
จะทำอย่างไร - ฉันอยู่ในออฟฟิศแล้วตอนนี้ :) (แก้ไข: เสร็จแล้ว)
Xarus

7
แล้วมือถือ (เช่น ipad)
basarat

5
สิ่งที่เกี่ยวกับการปัดเหตุการณ์จาก trackpad ใน MAC อาจถูกจับเช่นกัน?
Sriganesh Navaneethakrishnan

6
ฉันจะแยกความแตกต่างของปุ่มไปข้างหน้าและข้างหลังได้อย่างไร
Mr_Perfect

79

คุณสามารถลองใช้popstateตัวจัดการเหตุการณ์เช่น:

window.addEventListener('popstate', function(event) {
    // The popstate event is fired each time when the current history entry changes.

    var r = confirm("You pressed a Back button! Are you sure?!");

    if (r == true) {
        // Call Back button programmatically as per user confirmation.
        history.back();
        // Uncomment below line to redirect to the previous page instead.
        // window.location = document.referrer // Note: IE11 is not supporting this.
    } else {
        // Stay on the current page.
        history.pushState(null, null, window.location.pathname);
    }

    history.pushState(null, null, window.location.pathname);

}, false);

หมายเหตุ: เพื่อให้ได้ผลลัพธ์ที่ดีที่สุดคุณควรโหลดโค้ดนี้เฉพาะหน้าเว็บที่คุณต้องการใช้ตรรกะเพื่อหลีกเลี่ยงปัญหาอื่น ๆ ที่ไม่คาดคิด

เหตุการณ์ popstate จะเริ่มทำงานในแต่ละครั้งเมื่อรายการประวัติปัจจุบันเปลี่ยนไป (ผู้ใช้นำทางไปยังสถานะใหม่) ที่เกิดขึ้นเมื่อผู้ใช้คลิกกลับ / ปุ่มไปข้างหน้าเบราว์เซอร์หรือเมื่อhistory.back(), history.forward(), history.go()วิธีการที่เรียกว่า programatically

event.stateเป็นทรัพย์สินของเหตุการณ์ที่เกิดขึ้นจะมีค่าเท่ากับรัฐวัตถุประวัติศาสตร์

สำหรับไวยากรณ์ jQuery ให้ล้อมรอบ (เพื่อเพิ่มฟังคู่หลังจากเอกสารพร้อม):

(function($) {
  // Above code here.
})(jQuery);

ดูเพิ่มเติมที่: window.onpopstate เมื่อโหลดหน้าเว็บ


ดูยังมีตัวอย่างในหน้าเดียวปพลิเคชันและ HTML5 pushStateหน้านี้:

<script>
// jQuery
$(window).on('popstate', function (e) {
    var state = e.originalEvent.state;
    if (state !== null) {
        //load content with ajax
    }
});

// Vanilla javascript
window.addEventListener('popstate', function (e) {
    var state = e.state;
    if (state !== null) {
        //load content with ajax
    }
});
</script>

สิ่งนี้ควรเข้ากันได้กับ Chrome 5+, Firefox 4+, IE 10+, Safari 6+, Opera 11.5+ และที่คล้ายกัน


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

1
โพสต์ที่ดีในการปพลิเคชันหน้าเดียวและ HTML5 pushState สมบูรณ์แบบสำหรับ "เค้าโครงหน้าเดียว" หรือ "แอปหน้าเดียว" ที่ทันสมัย ขอบคุณสำหรับลิงค์และคำตอบของคุณ!
lowtechsun

1
e.state ดูเหมือนไม่ได้กำหนดไว้เสมอในเบราว์เซอร์ที่ทันสมัย
FAjir

ฉันขอแนะนำให้คุณใส่รหัสของคุณในตัวอย่างเพื่อให้คุณสามารถเรียกใช้โดยตรงที่นี่
FourCinnamon0

16

ฉันดิ้นรนกับข้อกำหนดนี้มาระยะหนึ่งแล้วใช้วิธีแก้ปัญหาข้างต้นเพื่อนำไปใช้ อย่างไรก็ตามฉันสะดุดในการสังเกตและดูเหมือนว่าจะทำงานกับเบราว์เซอร์ Chrome, Firefox และ Safari + Android และ iPhone

การโหลดหน้าเว็บ:

window.history.pushState({page: 1}, "", "");

window.onpopstate = function(event) {

  // "event" object seems to contain value only when the back button is clicked
  // and if the pop state event fires due to clicks on a button
  // or a link it comes up as "undefined" 

  if(event){
    // Code to handle back button or prevent from navigation
  }
  else{
    // Continue user action through link or button
  }
}

แจ้งให้เราทราบหากสิ่งนี้ช่วยได้ หากฉันพลาดบางสิ่งฉันก็ยินดีที่จะเข้าใจ


1
ไม่จริง. eventมีค่าแม้สำหรับปุ่มไปข้างหน้า
Daniel Birowsky Popeski

14

ในจาวาสคริปต์ประเภทการนำทาง2หมายถึงการคลิกปุ่มย้อนกลับหรือไปข้างหน้าของเบราว์เซอร์และเบราว์เซอร์กำลังนำเนื้อหาจากแคช

if(performance.navigation.type == 2)
{
    //Do your code here
}

1
ไม่สามารถใช้งานได้ในแอปพลิเคชันหน้าเดียวผลที่ได้คือ 1 เสมอ (ซึ่งหมายถึงการโหลดซ้ำ) ยิ่งไปกว่านั้นมันไม่ได้สร้างความแตกต่างระหว่างปุ่มย้อนกลับและไปข้างหน้าซึ่งโชคร้ายมาก
papillon

"นอกจากนี้ก็ไม่ได้ทำให้ความแตกต่างระหว่างกลับและปุ่มไปข้างหน้าซึ่งเป็นโชคร้ายมาก." ใช่เพราะเมื่อใดก็ตามที่ข้อมูลจะถูกดึงข้อมูลจากแคชว่าเวลา performance.navigation.type คือ 2
ฮะซัน Badshah

ไม่รับประกันว่าจะสามารถใช้งานได้ในเบราว์เซอร์ทั้งหมด! ดังนั้นคุณควรเขียนดังนี้: if (window.performance) {// รหัสที่เกี่ยวข้องกับประสิทธิภาพของคุณ} นอกจากนี้ควรใช้ TYPE_BACK_FORWARD แทนการใช้ 2 เพื่อความสะดวกในการอ่าน
blank94

7

สิ่งนี้จะใช้ได้จริง (สำหรับการตรวจจับคลิกปุ่มย้อนกลับ)

$(window).on('popstate', function(event) {
 alert("pop");
});

6

ดูนี่:

history.pushState(null, null, location.href);
    window.onpopstate = function () {
        history.go(1);
    };

มันใช้งานได้ดี ...


ไม่ทำงานใน Chrome 78.0.3904.70 (รุ่นเป็นทางการ) (64 บิต)
Jeffz

ยืนยันการทำงานกับ Brave v1.3.118 >> Chromium: 80.0.3987.116 (Official Build) (64-bit)
ZeroThe2nd

ไม่ทำงานหากคุณเข้ามาที่หน้าเว็บจากไซต์ภายนอก
Milan Vlach

5
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
  alert('hello world');
}

นี่เป็นทางออกเดียวที่ได้ผลสำหรับฉัน (ไม่ใช่เว็บไซต์ onepage) มันทำงานร่วมกับ Chrome, Firefox และ Safari


1
window.performance.navigation ได้ถูกคัดค้าน นี่คือ docs developer.mozilla.org/en-US/docs/Web/API/Performance/navigation
llaaalu

สิ่งนี้ใช้ได้กับฉันในหน้า. cshtml ของฉัน ทำงานได้สำเร็จบน Chrome และ IE ขอบคุณ
Justjyde

5

คำตอบที่ถูกต้องมีอยู่แล้วเพื่อตอบคำถาม ฉันต้องการที่จะพูดถึงใหม่ JavaScript API PerformanceNavigationTimingก็เปลี่ยนเลิกperformance.navigation

รหัสต่อไปนี้จะเข้าสู่ระบบคอนโซล "back_forward" หากผู้ใช้ลงบนหน้าของคุณโดยใช้ปุ่มย้อนกลับหรือไปข้างหน้า ดูตารางความเข้ากันได้ก่อนที่จะใช้ในโครงการของคุณ

var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
    console.log(perfEntries[i].type);
}

นี่ไม่ใช่วิธีที่จะบอกได้ว่าคลิกปุ่มย้อนกลับในหน้านี้หรือไม่ มันบอกว่าถ้ามันถูกคลิกในหน้าสุดท้าย
Seph Reed

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

1
นี่อาจไม่ตอบคำถาม แต่สิ่งที่ฉันต้องการ! เป็นคนที่ดี - ฉันไม่รู้เรื่องนี้ ...
Hogsmill

4

เบราว์เซอร์: https://jsfiddle.net/Limitlessisa/axt1Lqoz/

สำหรับการควบคุมอุปกรณ์เคลื่อนที่: https://jsfiddle.net/Limitlessisa/axt1Lqoz/show/

$(document).ready(function() {
  $('body').on('click touch', '#share', function(e) {
    $('.share').fadeIn();
  });
});

// geri butonunu yakalama
window.onhashchange = function(e) {
  var oldURL = e.oldURL.split('#')[1];
  var newURL = e.newURL.split('#')[1];

  if (oldURL == 'share') {
    $('.share').fadeOut();
    e.preventDefault();
    return false;
  }
  //console.log('old:'+oldURL+' new:'+newURL);
}
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
<!DOCTYPE html>
<html>

<head>
    <title>Back Button Example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>

<body style="text-align:center; padding:0;">
    <a href="#share" id="share">Share</a>
    <div class="share" style="">
        <h1>Test Page</h1>
        <p> Back button press please for control.</p>
    </div>
</body>

</html>


สิ่งนี้ไม่ตอบคำถามที่ถาม คำถามนี้เกี่ยวกับการตรวจสอบการใช้ปุ่มย้อนกลับในหน้าและปุ่มย้อนกลับดั้งเดิมของเบราว์เซอร์
Xarus

2
คำถามถูกติดแท็ก javascript ไม่ใช่ jquery
skwny

3

นี่คือสิ่งที่ฉันทำ สมมติฐานคือเมื่อ URL เปลี่ยนแปลง แต่ไม่มีการคลิกภายในสิ่งที่documentตรวจพบมันเป็นเบราว์เซอร์กลับมา (ใช่หรือส่งต่อ) การคลิกของผู้ใช้จะถูกรีเซ็ตหลังจาก 2 วินาทีเพื่อให้ทำงานบนหน้าเว็บที่โหลดเนื้อหาผ่าน Ajax:

(function(window, $) {
  var anyClick, consoleLog, debug, delay;
  delay = function(sec, func) {
    return setTimeout(func, sec * 1000);
  };
  debug = true;
  anyClick = false;
  consoleLog = function(type, message) {
    if (debug) {
      return console[type](message);
    }
  };
  $(window.document).click(function() {
    anyClick = true;
    consoleLog("info", "clicked");
    return delay(2, function() {
      consoleLog("info", "reset click state");
      return anyClick = false;
    });
  });
  return window.addEventListener("popstate", function(e) {
    if (anyClick !== true) {
      consoleLog("info", "Back clicked");
      return window.dataLayer.push({
        event: 'analyticsEvent',
        eventCategory: 'test',
        eventAction: 'test'
      });
    }
  });
})(window, jQuery);

2

ฉันสามารถใช้คำตอบบางอย่างในชุดข้อความนี้และอื่น ๆ เพื่อให้ทำงานได้ใน IE และ Chrome / Edge history.pushStateสำหรับฉันไม่ได้รับการสนับสนุนใน IE11

if (history.pushState) {
    //Chrome and modern browsers
    history.pushState(null, document.title, location.href);
    window.addEventListener('popstate', function (event) {
        history.pushState(null, document.title, location.href);
    });
}
else {
    //IE
    history.forward();
}

เพิ่งลองใช้งานบน Chrome 78.0.3904.70 (รุ่นทางการ) (64 บิต) และมันไม่ทำงาน
Jeffz

2

ส่วนประกอบที่เต็มเปี่ยมสามารถใช้งานได้ต่อเมื่อคุณกำหนด API ใหม่ (เปลี่ยนวิธีการของวัตถุ 'ประวัติ') ฉันจะแบ่งปันคลาสที่เพิ่งเขียน ทดสอบกับ Chrome และ Mozilla Support เท่านั้น HTML5 และ ECMAScript5-6

class HistoryNavigation {
    static init()
    {
        if(HistoryNavigation.is_init===true){
            return;
        }
        HistoryNavigation.is_init=true;

        let history_stack=[];
        let n=0;
        let  current_state={timestamp:Date.now()+n};
        n++;
        let init_HNState;
        if(history.state!==null){
            current_state=history.state.HNState;
            history_stack=history.state.HNState.history_stack;
            init_HNState=history.state.HNState;
        } else {
            init_HNState={timestamp:current_state.timestamp,history_stack};
        }
        let listenerPushState=function(params){
            params=Object.assign({state:null},params);
            params.state=params.state!==null?Object.assign({},params.state):{};
            let h_state={ timestamp:Date.now()+n};
            n++;
            let key = history_stack.indexOf(current_state.timestamp);
            key=key+1;
            history_stack.splice(key);
            history_stack.push(h_state.timestamp);
            h_state.history_stack=history_stack;
            params.state.HNState=h_state;
            current_state=h_state;
            return params;
        };
        let listenerReplaceState=function(params){
            params=Object.assign({state:null},params);
            params.state=params.state!==null?Object.assign({},params.state):null;
            let h_state=Object.assign({},current_state);
            h_state.history_stack=history_stack;
            params.state.HNState=h_state;
            return params;
        };
        let desc=Object.getOwnPropertyDescriptors(History.prototype);
        delete desc.constructor;
        Object.defineProperties(History.prototype,{

            replaceState:Object.assign({},desc.replaceState,{
                value:function(state,title,url){
                    let params={state,title,url};
                    HistoryNavigation.dispatchEvent('history.state.replace',params);
                    params=Object.assign({state,title,url},params);
                    params=listenerReplaceState(params);
                    desc.replaceState.value.call(this,params.state,params.title,params.url);
                }
            }),
            pushState:Object.assign({},desc.pushState,{
                value:function(state,title,url){
                    let params={state,title,url};
                    HistoryNavigation.dispatchEvent('history.state.push',params);
                    params=Object.assign({state,title,url},params);
                    params=listenerPushState(params);
                    return desc.pushState.value.call(this, params.state, params.title, params.url);
                }
            })
        });
        HistoryNavigation.addEventListener('popstate',function(event){
            let HNState;
            if(event.state==null){
                HNState=init_HNState;
            } else {
                HNState=event.state.HNState;
            }
            let key_prev=history_stack.indexOf(current_state.timestamp);
            let key_state=history_stack.indexOf(HNState.timestamp);
            let delta=key_state-key_prev;
            let params={delta,event,state:Object.assign({},event.state)};
            delete params.state.HNState;
            HNState.history_stack=history_stack;
            if(event.state!==null){
                event.state.HNState=HNState;
            }
            current_state=HNState;
            HistoryNavigation.dispatchEvent('history.go',params);
        });

    }
    static addEventListener(...arg)
    {
        window.addEventListener(...arg);
    }
    static removeEventListener(...arg)
    {
        window.removeEventListener(...arg);
    }
    static dispatchEvent(event,params)
    {
        if(!(event instanceof Event)){
            event=new Event(event,{cancelable:true});
        }
        event.params=params;
        window.dispatchEvent(event);
    };
}
HistoryNavigation.init();

// exemple

HistoryNavigation.addEventListener('popstate',function(event){
    console.log('Will not start because they blocked the work');
});
HistoryNavigation.addEventListener('history.go',function(event){
    event.params.event.stopImmediatePropagation();// blocked popstate listeners
    console.log(event.params);
    // back or forward - see event.params.delta

});
HistoryNavigation.addEventListener('history.state.push',function(event){
    console.log(event);
});
HistoryNavigation.addEventListener('history.state.replace',function(event){
    console.log(event);
});
history.pushState({h:'hello'},'','');
history.pushState({h:'hello2'},'','');
history.pushState({h:'hello3'},'','');
history.back();

    ```

วิธีการที่ดี! ขอบคุณที่เพิ่มสิ่งนี้ (ฉันยังพบว่ามันน่าทึ่งที่มีการสนทนาในหัวข้อนี้หลังจากหลายปีที่ผ่านมา)
Xarus

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

1

document.mouseover ไม่สามารถใช้งานได้กับ IE และ FireFox อย่างไรก็ตามฉันได้ลอง:

$(document).ready(function () {
  setInterval(function () {
    var $sample = $("body");
    if ($sample.is(":hover")) {
      window.innerDocClick = true;
    } else {
      window.innerDocClick = false;
    }
  });

});

window.onhashchange = function () {
  if (window.innerDocClick) {
    //Your own in-page mechanism triggered the hash change
  } else {
    //Browser back or forward button was pressed
  }
};

สิ่งนี้ใช้ได้กับ Chrome และ IE ไม่ใช่ FireFox ยังคงทำงานเพื่อให้ได้ Firefox ที่ถูกต้อง วิธีง่ายๆในการตรวจสอบการคลิกปุ่มย้อนกลับ / ไปข้างหน้าของเบราว์เซอร์ยินดีต้อนรับไม่ใช่เฉพาะใน JQuery แต่ยังรวมถึง AngularJS หรือ Javascript ธรรมดา


1
 <input style="display:none" id="__pageLoaded" value=""/>


 $(document).ready(function () {
        if ($("#__pageLoaded").val() != 1) {

            $("#__pageLoaded").val(1);


        } else {
            shared.isBackLoad = true;
            $("#__pageLoaded").val(1);  

            // Call any function that handles your back event

        }
    });

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


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

0

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

var evt = null,
canGoBackToThePast = true;

$('#next-slide').on('click touch', function(e) {
    evt = e;
    canGobackToThePast = false;
    // your logic (remember to set the 'canGoBackToThePast' flag back to 'true' at the end of it)
}

-21

ฉันลองตัวเลือกด้านบน แต่ไม่มีตัวใดที่ทำงานให้ฉันได้ นี่คือทางออก

if(window.event)
   {
        if(window.event.clientX < 40 && window.event.clientY < 0)
        {
            alert("Browser back button is clicked...");
        }
        else
        {
            alert("Browser refresh button is clicked...");
        }
    }

อ้างอิงลิงค์นี้http://www.codeproject.com/Articles/696526/Solution-to-Browser-Back-Button-Click-Click-Event-Handliสำหรับรายละเอียดเพิ่มเติม


8
@unamyousuf มันค่อนข้างชัดเจนว่าทำไมโค้ดนี้ถึงใช้งานไม่ได้ มันติดตามปุ่มย้อนกลับของเบราว์เซอร์ แต่ปุ่มอยู่นอกวิวพอร์ตดังนั้นพิกัด clientX และ clientY จึงไม่ควรได้รับ สมมติว่ามันใช้งานได้แล้ว iOS เป็นอย่างไร? ปุ่มย้อนกลับอยู่ที่ด้านล่าง ... นอกจากนี้วิธีการเขียนนั้นไม่มีประสิทธิภาพอย่างยิ่งมันเป็นเงื่อนไขสำหรับทุก ๆ เหตุการณ์ที่เกิดขึ้น ... พระเจ้าเลวร้ายมากที่ฉันต้องลงคะแนนเสียง
James Wong - Reinstate Monica

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