Как определить событие кнопки "Назад" браузера - "Кросс-браузер" - программирование
Подтвердить что ты не робот

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

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

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

Почему на земле нет кнопок браузера, запускающих собственные события!?

4b9b3361

Ответ 1

(Примечание. Согласно обратной связи Sharky, я включил код для обнаружения обратных пространств)

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

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

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 mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User 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 на этот вопрос):

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

Ответ 2

Вы можете попробовать 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 запускается каждый раз, когда изменяется текущая запись истории (пользователь переходит в новое состояние). Это происходит, когда пользователь нажимает кнопки браузера Back/Forward или когда методы history.back(), history.forward(), history.go() запрограммированы.

Свойство 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+ и т.д.

Ответ 3

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

Сообщите мне, если это поможет. Если я что-то упустил, я буду рад понять.

Ответ 4

В javascript тип навигации 2 означает, что браузер нажимает кнопку "назад" или "вперед", и браузер фактически берет контент из кэша.

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

Ответ 5

Это определенно будет работать (для обнаружения нажатия кнопки назад)

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

Ответ 6

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

Ответ 7

Вот мой взгляд на это. Предполагается, что при изменении URL-адреса, но не обнаружено клика внутри обнаруженного document, это браузер назад (да или вперед). Пользовательский щелчок reset через 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);

Ответ 8

добавил этот код внизу страницы. см. эту кнопку обнаружения браузера baa

window.addEventListener("pageshow", function(e) {
  var is_back = e.persisted || (typeof window.performance !=
    "undefined" && window.performance.navigation.type === 2);
  if (is_back) {
    // do the action. 
  }
});

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

Ответ 9

Видеть это:

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

работает нормально...

Ответ 10

Правильный ответ уже есть, чтобы ответить на вопрос. Я хочу упомянуть новый 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);
}

Ответ 11

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.

Ответ 12

 <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

        }
    });

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

Ответ 13

Я смог использовать некоторые ответы в этой теме и другие, чтобы заставить его работать в 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();
}

Ответ 14

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

Ответ 15

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

Это единственное решение, которое сработало для меня (это не одностраничный сайт). Работает с Chrome, Firefox и Safari.

Ответ 16

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

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