devote / HTML5-History-API

HTML5 History API expansion for browsers not supporting pushState, replaceState
http://spb-piksel.ru
MIT License
1.02k stars 182 forks source link

Standard API return value #57

Closed istrasoft closed 10 years ago

istrasoft commented 10 years ago

Hi and thanks for the very nice history api shim !

I wonder however what is the reason to store the data in window.history.location instead of the standard way the API does, using the event object sent to the popstate event handler, that event object having a "state" property with the data associated with the state ?

devote commented 10 years ago

Sorry, I do not quite understand you (I bad with English). You ask me for what purposes need history.location? Rather, it is necessary for convenience. So you do not have to manually parse window.location.hash.

istrasoft commented 10 years ago

Давай по русски тогда :)

Стандартная API onpopstate просто меняет обект history.state из которого потом можно читать location, title и все остальное что записали туда во время pushState. Я просто не понимаю зачем нужна такая детальная информация как в history.location

devote commented 10 years ago

Давай по русски тогда :)

Хороший вариант :)

Я просто не понимаю зачем нужна такая детальная информация как в history.location

Если говорить о необходимости history.location, то конечно острой необходимости в нем нет (а точнее в его детальности, оно скорее для на всякий случай). Но это в том случае если писать подобным образом:

window.onpopstate = function(e) {
  AJAXload(e.state.lastUrl);
}
history.pushState({lastUrl: location.href}, null, 'new-url');

Но в данном примере есть один косяк, если нажать кнопку назад в браузере при первом заходе на сайт, мы получим ошибку. Так как при первом заходе на сайт объект state не определен. Конечно это можно обойти вызвав при заходе на сайт метод history.replaceState({lastUrl: location.href}).

Еще как вариант не всегда есть необходимость вообще в объекте state. Вот тут то нам и нужен location.

window.onpopstate = function() {
  var location = history.location || window.location;
  AJAXload(location.href);
}
history.pushState({lastUrl: location.href}, null, 'new-url');

Очень многие библиотеки (обертки) над History-API не используют объект state а активно используют location. По этой причине был добавлен этот объект. Хотя конечно это не причина.. Ибо библиотека родилась раньше чем эти обертки, но на сегодняшний день это уже аргумент.

istrasoft commented 10 years ago

Понятно, спасибо !

К стати на счет первого захода, я пробовал на IE9. Страница 1, 2, потом 3. Когда нажимаю Back 2 раза, location.href = http://192.168.10.50/ (=хост), a на Chrome Firefox работает нормально и выдает полное урл первой страницы. использую версию gtie8

devote commented 10 years ago

Если есть возможность привести пример кода, который на Ваш взгляд работает не правильно. Буду признателен. Спасибо!

istrasoft commented 10 years ago

Не знаю как, сложно, ето болшая аппликация на интранете :(

devote commented 10 years ago

так же не забывайте что history.location тесно связан с параметром basepath. По умолчанию basepath определен как '/' корень сайта. Если же Ваш сайт расположен в папке и его корень допустим /pathsite/ то этот путь нужно прописать в basepath

istrasoft commented 10 years ago

Обязательно да, иначе не будет работать ? у меня адрес в папке...

devote commented 10 years ago

например у меня есть основной сайт: http://mysite.com/ в нем есть подсайт на аяксе с использованием history-api по адресу http://mysite.com/other-site/ то в этом случае нужно указать параметру basepath путь к корню этого подсайта. А так как корень для подсайта это /other-site/ значит прописать:

history.redirect(null, '/other-site/');
// далее весь остальной код

Или теперь AMD:

requirejs(['html5-history-api'], function(history) {
  history.redirect(null, '/other-site/');
  // далее весь остальной код
});

Подробнее про AMD: https://github.com/devote/HTML5-History-API#amd-support

Или подключить history.js с параметром:

<script src="history.js?basepath=/other-site/"></script>
istrasoft commented 10 years ago

Ясно, спасибо !

на счет AMD я предпочетаю анонимные модули, ето recommended...

devote commented 10 years ago

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

Uncaught Error: Mismatched anonymous define() module: function () {
          return self.history;
        }
istrasoft commented 10 years ago

/blah/history.js

define([], function() { // history code here

return history; });

/random.js

$(window).on('domready', function() {

requirejs(['blah/history'], function(H) {

// call H.something here

}):

}

devote commented 10 years ago

А вот так попробуй:

<script src="/require.js"></script>
<script src="/blah/history.js"></script>

Вот с этим кодом в /blah/history.js

define([], function() {
  // history code here
  return history;
});
istrasoft commented 10 years ago

Tolko shto poproboval vot tak...

(function(root, factory){
    'use strict';

    // AMD
    if (typeof define === 'function' && define.amd){
        define(factory);
    // Browser
    } else {
        root.History = factory();
    }
}( ( typeof window === 'object' && window ) || this, function(){

    // Prevent the code from running if there is no window.history object
    if (!window.history) return;
    // symlink to document
    var document = window.document;

....

    /**
     * Replace the original methods on the wrapper
     */
    window[addEventListenerName] = addEventListener;
    window[removeEventListenerName] = removeEventListener;
    window[dispatchEventName] = dispatchEvent;

    return {
      setup: function (basepath, redirect, type) {
        settings = {
          basepath: basepath || '/',
          redirect: redirect || 0,
          type: type || '/'
        };
      }
    };

}));

i v drugom meste v /main.js:

define(['blah/history'], function(History) {

  History.setup({basepath: '/folder/'});
  $(window).on('popstate', function() {
    console.log(history.location.href);
  });

});

i eshe

<script src="require.js" data-main="main"></script>

and it runs perfect !

devote commented 10 years ago

I close this issue, if you still want to discuss it, let me know. Thank you

Я закрываю этот вопрос, если вы еще хотите обсудить это, сообщите мне. Спасибо