Отключение кнопки "История" HTML5

Я пишу одностраничное приложение javascript, используя API истории HTML5. Приложение загружает контент через Ajax и внутренне поддерживает информацию состояния на экране переднего плана, используя стек стека.

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

Несколько быстрых бит информации:

  • Пользователь должен только когда-либо вернуться, никогда не пересылать
  • Нажатие кнопки "Назад назад" закрывает текущий экран, на котором пользователь включен и перезагружает предыдущий.
  • Проект ориентирован только на самую последнюю версию Chrome, поэтому другие версии браузеров не важны.
  • Я использую только собственный JavaScript и jQuery, я хотел бы сделать это без History.js

Когда я загружаю новый экран, я запускаю следующую строку:

history.pushState(screenData, window.document.title, "#");

Я связываюсь с событием popstate через jQuery:

$(window).bind("popstate", function(event) {
    if (event.originalEvent.state != null) {
        // Logic that loads the previous screen using my screen stack
    }
}); 

Управление моей историей приложений работает, однако, когда я возвращаюсь, кнопка "вперед" включена. Мне нужно выяснить, как удалить данные из history в событии popstate.

Могу ли я сделать это с помощью replaceState? Я не уверен, как это сделать...

Ответ 1

Плохая часть

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

Хорошая часть

Это немного сложно, но я думаю, это может сработать, если вы хотите сделать обычную историю. Вы можете просто использовать pushState в событии popstate, чтобы сделать вашу фактическую страницу самой последней записью истории. Я предполагаю, что вы обрабатываете свою историю, ваше окно никогда не выгрузится. Это позволяет вам самостоятельно отслеживать историю пользователей:

var customHistory = [];

Нажимайте каждую загружаемую страницу history.pushState(screenData, window.document.title, "#");, как и раньше. Только вы добавляете состояние в свою собственную историю:

history.pushState(screenData, window.document.title, "#");
customHistory.push({data: screenData, title: window.document.title, location: '#'});

теперь, если у вас есть событие popstate, вы просто добавляете свою собственную историю и нажимаете ее на самую верхнюю запись:

window.onpopstate = function(e) { 
  var lastEntry = customHistory.pop();
  history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
  // load the last entry
}

Или в jQuery

$(window).on('popstate', function(e) {
  var lastEntry = customHistory.pop();
  history.pushState(lastEntry.data, lastEntry.title, lastEntry.location);
  // load the last entry
});

Ответ 2

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

Вот как можно решить вопрос "кнопка перемотки вперед" и избежать "повторной" проблемы с кнопкой "назад".

//setup the popstate EventListener that reacts to browser history events
window.addEventListener("popstate",function(event){
     // In order to remove any "forward"-history (i.e. disable forward 
     // button), this popstate event history state (having been navigated 
     // back to) must be insert _again_ as a new history state, thereby 
     // making it the new most forwad history state. 
     // This leaves the problem that to have this popstate event history
     // state to become the new top, it would now be multiple in the history
     //
     // Effectively history would be:
     //  * [states before..] ->
     //  * [popstate event.state] -> 
     //  * [*newly pushed _duplicate_ of popstate event.state ]
     // 
     // To remove the annoyance/confusion for the user to have duplicate
     // history states, meaning it has to be clicked at least twice to go 
     // back, we pursue the strategy of marking the current history state
     // as "obsolete", as it has been inserted _again_ as to be the most
     // forward history entry. 
     // 
     // the popstate EventListener will hence have to distinguish 2 cases:
     //
     // case A) "popstate event is _not_ an obsolete duplicate"...
     if( typeof event.state == "object" 
         && event.state.obsolete !== true)
     {
         //...so we _firstly_ mark this state as to from now on "obsolete",
         // which can be done using the history API replaceState method
         history.replaceState({"obsolete":true},"");
         // and _secondly_ push this state _one_more_time_ to the history
         // which will solve the OP desired "disable forward button" issue
         history.pushState(event.state,"");
     }

     // case B: there is the other case that the user clicked "back" and
     // encounters one of the duplicate history event entries that are 
     // "obsolete" now.
     if( typeof event.state == "object" 
         && event.state.obsolete === true)
     {
         //...in which case we simply go "back" once more 
         history.back() 
         // by this resolving the issue/problem that the user would
         // be counter-intuively needing to click back multiple times.
         // > we skip over the obsolete duplicates, that have been the
         // the result of necessarily pushing a history state to "disable
         // forward navigation"
     }

},false);

Ответ 3

Просто используйте следующий jquery, чтобы отключить кнопку вперед:

  $( document ).ready( function(){
    history.pushState(null,  document.title, location.href);        
   });

Ответ 4

История переходов удаляется при каждом переходе пользователя. Чтобы отключить форвардную историю, вы можете имитировать эту навигацию, загружая URL-адрес в скрытый iframe (например, "about: blank" ), когда загружается страница.

var rurl = "about:blank?e=" + Math.random();
window.open(rurl, "clear_fw");//being "clear_fw" the name of the iframe

Надеюсь, что это поможет.

Изменить: Это добавит запись в history.back... В моем случае это не проблема, но учтите ее.

Ответ 5

Примечание:

  • Этот код был протестирован и работал нормально, без каких-либо проблем, однако Я бы побудил разработчиков еще раз протестировать его перед тем, как приступить к работе с кодом.
  • Если HTML5 history.replaceState() используется где-либо в вашем приложении, приведенный ниже код теперь может работать.

Я создал пользовательскую функцию, чтобы отключить кнопку вперед.

Вот код (он не работает со стратегией маршрутизации хэша):

  <script>
    (function() {
      // function called after the DOM has loaded
      disableForwardButton();
    })();

    function disableForwardButton() {
      var flag, loop = false;
      window.addEventListener('popstate', function(event) {
        if (flag) {
          if (history.state && history.state.hasOwnProperty('page')) {
            loop = true;
            history.go(-1);
          } else {
            loop = false;
            history.go(-1);
          }
        } else {
          history.pushState({
              page: true
            },
            null,
            null
          );
        }
        flag = loop ? true : !flag;
      });

      window.onclick = function(event) {
        flag = false;
      };
    }
  </script>

Как отметил Редриф в комментариях к принятому ответу, проблема в том, что вам нужно дважды щелкнуть кнопку "Назад", чтобы вернуться на страницу, которая утомительна и непрактична.

Объяснение кода: каждый раз, когда вы нажимаете кнопку "назад", вам нужно создать дополнительный элемент истории, чтобы текущая страница, на которой вы находитесь, была указывает на вновь созданную страницу истории. Таким образом, нет страницы для перехода вперед, поскольку pushState является последним состоянием (представьте его как последний элемент в массиве), поэтому ваша кнопка вперед всегда будет отключена.

Причина, по которой было необходимо ввести переменную цикла, заключается в том, что у вас может быть сценарий, при котором вы возвращаетесь на определенную страницу, и появляется код pushState, который создает последний элемент истории, и вместо этого, возвращаясь назад, вы выбираете щелчок по некоторому снова и снова переходите по ссылке назад на предыдущую страницу, которая теперь создает дополнительный элемент истории. Другими словами, у вас есть что-то вроде этого:

[page1, page2, page2, page2]

Теперь, когда вы включите page2 (элемент index 3) и снова нажмете кнопку "Назад", вы снова попадете в page2 элемент index 1, и вам это не нужно. Помните, что у вас может быть массив элементов x page2, поэтому для разрешения этого конкретного случая была введена переменная цикла false, с помощью которой вы переходите от page2 к странице 1 независимо от того, сколько элементов page2 их в массиве.