Office.js сводит на нет функции истории браузера, нарушая использование истории
Официальная версия office.js доступна здесь:
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
Он содержит следующие строки в коде:
window.history.replaceState = null;
window.history.pushState = null;
Это нарушает некоторые функции истории в моих надстройках Excel (я использую react
а также react-router
)
Почему office.js сводит на нет эти функции истории? Я не могу найти какое-либо объяснение в документации.
1 ответ
Это работает для меня - кэшируйте объекты до того, как office-js удалит их:
<script type="text/javascript">
// Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them
window._historyCache = {
replaceState: window.history.replaceState,
pushState: window.history.pushState
};
</script>
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script type="text/javascript">
// Office js deletes window.history.pushState and window.history.replaceState. Restore them
window.history.replaceState = window._historyCache.replaceState;
window.history.pushState = window._historyCache.pushState;
</script>
Элемент управления браузера, используемый в Excel, не поддерживает API истории, если не были бы аннулированы replaceState и pushState, они могли бы реагировать, но всегда вызывали исключение при вызове. Пока не станет доступен новый элемент управления браузера, вам нужно будет переключиться на маршрутизацию на основе хеш-функции или использовать полизаполнение для History API. https://github.com/devote/HTML5-History-API кажется, работает, если вы включите ссылку на скрипт после office.js.
Моя версия Windows 10 Pro, браузер по умолчанию Edge 42.17134.1.0 . Но правая боковая панель, где Outlook запускает надстройку, использует старый механизм IE10;( (IE10 как браузер также есть в Windows). Я не знаю, это верно для всех Windows или это какой-то особый случай для моей версии. IE10 опоры history.replaceState
а также history.pushState
, но в Outlook у меня есть проблемы с этими методами, поэтому простое восстановление не работает для меня.
Простое решение с кешем history.replaceState
а также history.pushState
не работает передо мной В Outlook с IE10 внутри у меня есть неожиданная ошибка, когда мой код вызова history.replaceState
или же history.pushState
, Но я нашел одну интересную вещь. Если подавить ошибку, они делают свою работу.
Итак, мой обходной путь:
function isIE10 () {
return !!document.documentMode
}
// Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them
// Also there is an issue in Windows Outlook with `pushState` and `replaceState`. They throw an error but in the same time do their expected work
// So I suppress errors for IE10 (we use it inside Window Outlook)
window._historyCache = {
replaceState: function (originalReplaceState) {
return function () {
try {
return originalReplaceState.apply(window.history, arguments)
} catch (e) {
if (isIE10()) {
console.warn("Unexpected error in 'window.history.replaceState', but we can continue to work :)");
return false;
}
throw(e);
}
}
}(window.history.replaceState),
pushState: function (originalFunction) {
return function () {
try {
return originalFunction.apply(window.history, arguments)
} catch (e) {
if (isIE10()) {
console.warn("Unexpected error in 'window.history.pushState', but we can continue to work :)");
return false;
}
throw(e);
}
}
}(window.history.pushState)
};
// In Window Outlook we have issue with 'replaceState' and 'pushState. So replaced it by wrapped version.
window.history.replaceState = window._historyCache.replaceState;
window.history.pushState = window._historyCache.pushState;
//include the main code with react-router
//include Office.js
Office.initialize = function () {
// Office js deletes window.history.pushState and window.history.replaceState. Restore them
window.history.replaceState = window._historyCache.replaceState;
window.history.pushState = window._historyCache.pushState;
// Now you can start initialize&&run your application
....
}
Примечание: я должен заменить history.replaceState
а также history.pushState
перед запуском любого кода, который работает с этим API. В моем случае это реакция-роутер.