Предотвратить распространение истории в родительское окно

У меня есть 2 простые html-страницы: родительская и дочерняя. Родитель хранит дочерний элемент внутри iframe.
Parent.html:

<html>
<head></head>
<body>

<input type="text" id="text" />
<input type="button" value="change hash" onclick="javascript:changeHash()" />

<iframe src="Child.html"></iframe>

<script type="text/javascript">
    function changeHash () {
        window.location.hash = document.getElementById('text').value;
    }
</script>

</body>
</html>

И Child.html:

<html>
<head></head>
<body>

<input type="button" value="go back" onclick="javascript:goBack()" />

<script type="text/javascript">
    function goBack () {
        this.history.back();
    }
</script>

</body>
</html>

Я использую кнопку change hash, чтобы добавить несколько хэшей в историю. И когда я нажимаю кнопку назад внутри iframe - меняется хэш Родительской страницы. И кажется, что это поведение спецификация.

Итак, вопрос: можно ли предотвратить распространение возврата из iframe на его родительскую страницу? Поэтому я хотел бы, чтобы iframe не менял историю/хеш родителя.

Примечание. такое же поведение и для функции go (на самом деле go(-1) совпадает с back()).


person Kiril    schedule 30.07.2014    source источник
comment
если iframe может общаться с родителем, разве вы не можете просто восстановить потерянный хэш? это будет так быстро, что никто не заметит.   -  person vsync    schedule 03.08.2014
comment
@vsync, проблема в том, что внешняя страница хэширует hashchange подписку на событие, и именно так осуществляется навигация. Таким образом, приложение вернет пользователя обратно.   -  person Kiril    schedule 03.08.2014
comment
Попробуйте реализовать стек history navigation самостоятельно (например, используя localStorage) и измените свою функцию goBack, чтобы она не зависела от window.history.   -  person php-dev    schedule 05.08.2014
comment
@php-dev, конечно, это решение. Но это просто интересное поведение и теперь это просто своего рода вызов.   -  person Kiril    schedule 05.08.2014


Ответы (1)


Я думаю, что это невозможно сделать без использования фреймворка, но у меня есть решение, которое может (частично) решить эту проблему.

Сначала я подумал изменить объект history и переопределить его, но это невозможно, так как это свойство внутри окна недоступно для записи. но мы можем переопределить функции внутри history.

Именно это привело меня к переопределению функции back(), и вместо того, чтобы позволить объекту history выполнять свою работу, мы должны найти предыдущий URL и изменить местоположение документа (дочернего).

Если вы Child.html, переопределите функцию back() следующим образом:

history.back = function ()
{
    document.location = document.referrer;
}

Проблема, с которой мы сталкиваемся в этой функции, заключается в том, что после загрузки родительского документа и загрузки iframe (дочернего) document.referrer дочернего элемента возвращает URL-адрес родителя.

Итак, прежде чем менять document.location, давайте проверим, отличается ли document.referrer от родительского URL (без привязки)

history.back = function ()
{
    var url = window.parent.document.location.href.split("#")[0];
    if(document.referrer!=url)
        document.location = document.referrer;
}

Наконец, это решение, которое я нашел, и, к сожалению, у него есть проблема: вы не можете переопределить функцию forward(), которая позволяет вам перейти к следующему URL-адресу, невозможно найти следующий URL-адрес, а document.referrer возвращает URL-адрес страница, с которой вы пришли, это может быть предыдущая страница или следующая страница. но все же вы можете перемещаться внутри iframe без изменения родительского местоположения.

person Khalid    schedule 02.08.2014
comment
Спасибо за ваш ответ! Но это сработает только для спины. Есть еще одна возможность вернуться - history.go(-1). На самом деле, функцию go можно переопределить, но она может вернуться на 2,3,... шага назад. В случае 2+ шагов назад document.referrer не сработает. - person Kiril; 04.08.2014
comment
да, вы правы, но не забывайте, что history.go меняет URL-адрес родительского окна - person Khalid; 04.08.2014