Как определить событие кнопки браузера назад-Кросс-браузер

Как вы окончательно определяете, нажал ли пользователь кнопку "Назад" в браузере?

Как вы применяете использование кнопки "назад" на странице внутри одностраничного веб-приложения с помощью

9 ответов


(примечание: согласно отзывам Шарки, я включил код для обнаружения backspaces)

Итак, я часто видел эти вопросы на SO и недавно столкнулся с проблемой управления функциональностью кнопки "Назад". После нескольких дней поиска лучшего решения для моего приложения (одностраничная с хеш-навигацией) я придумал простую, кросс-браузерную, без библиотеки систему для обнаружения кнопки "Назад".

большинство людей рекомендуют использование:

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.onmouseover и снять его с помощью document.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
    }
}

и вот оно. простой, трехкомпонентный способ обнаружения использования кнопки "назад" против элементов на странице в отношении хэш-навигации.

EDIT:

чтобы убедиться, что пользователь не использует backspace для запуска события back, вы также можете включить следующее (Благодаря @thetoolman on этот вопрос):

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

вы можете попробовать 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() методы вызываются программно.

The event.state свойство события равно объекту состояния истории.

для синтаксиса jQuery оберните его (чтобы добавить даже прослушиватель после того, как документ готов):

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

Читайте также:


Я боролся с этим требованием довольно долго и принял некоторые из решений выше, чтобы реализовать его. Тем не менее, я наткнулся на наблюдение, и, похоже, он работает в браузерах 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
  }
}

Дайте мне знать, если это помогает. Если я что-то упускаю, я буду счастлив понять.


браузер: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>

вот мой взгляд на это. Предположение, когда 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);

документ.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.


я решил это, отслеживая исходное событие, которое вызвало 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)
}

 <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

        }
    });

Я пытался выше вариантов, но ни один из них не работает для меня. Вот решение

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-Event-Handli дополнительные детали