Как мне сделать действие JavaScript, которое может иметь некоторые эффекты на текущей странице, но также изменит URL-адрес в браузере, чтобы, если пользователь нажимает перезагрузку или закладку, используется новый URL-адрес?
Также было бы неплохо, если бы кнопка «Назад» перезагружала исходный URL.
Я пытаюсь записать состояние JavaScript в URL-адресе.
Примерное хорошее использование pushState: for(i=1;i<50;i++){var txt = "..................................................";txt=txt.slice(0,i)+"HTML5"+txt.slice(i,txt.length);history.pushState({}, "html5", txt);}
пример этого эффекта в действии: dujour.com
Пример этого эффекта: facebook.com (при открытии изображений в лайтбоксе)
Это хороший вопрос. однако это печальная ситуация в том смысле, что, если бы этот вопрос был задан таким образом сегодня, он был бы отвергнут и вызван тем, что «это не тот сайт, на котором вы заставляете людей писать весь ваш код за вас».



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я бы сильно подозревал, что это невозможно, потому что в противном случае это было бы невероятной проблемой безопасности. Например, я мог бы сделать страницу, похожую на страницу входа в банк, и сделать так, чтобы URL-адрес в адресной строке выглядел как как настоящий банк!
Возможно, если вы объясните, почему вы хотите это сделать, люди смогут предложить альтернативные подходы ...
[Изменить в 2011 году: с тех пор, как я написал этот ответ в 2008 году, появилась дополнительная информация о Техника HTML5, который позволяет изменять URL-адрес, если он из того же источника]
Не было бы большой проблемы, если бы изменения, не связанные с перезагрузкой, были ограничены путем, строкой запроса и фрагментом - i.s. не авторитет (домен и тому подобное).
Вы можете изменить только location.hash (все после #), как отмечает Мэтью Чамли в принятом ответе.
Ты используешь Фейсбук? Facebook изменяет URL-адрес перезагрузки без, используя history.pushState().
Пол Диксон, вы должны заметить почтовый ящик facebook, когда вы нажимаете на имена с левой стороны, изменяется только URL-адрес, и в окно чата загружается новый чат, страница не обновляется. также есть много других сайтов на WebGL, они делают то же самое
Если вы хотите, чтобы он работал в браузерах, которые еще не поддерживают history.pushState и history.popState, «старый» способ - установить идентификатор фрагмента, который не приведет к перезагрузке страницы.
Основная идея состоит в том, чтобы установить для свойства window.location.hash значение, содержащее любую информацию о состоянии, которая вам нужна, а затем либо использовать событие window.onhashchange, либо для старых браузеров, которые не поддерживают onhashchange (IE <8, Firefox <3.6), периодически проверять, чтобы увидеть если хеш изменился (например, с помощью setInterval) и обновите страницу. Вам также необходимо будет проверить значение хеш-функции при загрузке страницы, чтобы настроить исходное содержимое.
Если вы используете jQuery, есть плагин hashchange, который будет использовать любой метод, поддерживаемый браузером. Я уверен, что есть плагины и для других библиотек.
Следует остерегаться столкновения с идентификаторами на странице, потому что браузер будет прокручивать до любого элемента с совпадающим идентификатором.
Разве поисковые системы не игнорируют эти внутренние ссылки (хеши)? В моем сценарии я хочу, чтобы пауки тоже перехватывали эти ссылки.
@Drew, насколько мне известно, поисковые системы не могут рассматривать часть страницы как отдельный результат.
Теперь есть предложение, чтобы поисковые системы видели хеши: googlewebmastercentral.blogspot.com/2009/10/…
Вместо использования setInterval для проверки document.location.hash можно использовать событие hashchange, поскольку оно гораздо более распространено. Проверьте здесь, какие браузеры поддерживают каждый стандарт.. Мой текущий подход - использовать push / popState в браузерах, которые его поддерживают. На остальных я установил хеш и смотрю только hashchange в поддерживающих браузерах. Это оставляет IE <= 7 без поддержки истории, но с полезной постоянной ссылкой. Но кого волнует история IE <= 7?
Взгляните на эту демонстрацию использования window.location.hash: jsbin.com/ezopap/5#Hello%20World
Если вы ajax запрашиваете новую страницу и повторно реализуете тег javascript, который Google предоставляет вам для аналитики Google, не получит ли он информацию о хэштеге и не зарегистрирует это как новое посещение страницы?
@gabeDel Да, хотя я не думаю, что Analytics записывает хэш, поэтому у него будет тот же URL. Лучшим способом было бы вручную вызвать _trackPageview с «реальным» URL-адресом новой страницы.
Настройки безопасности браузера не позволяют людям напрямую изменять отображаемый URL. Вы можете себе представить, какие фишинговые уязвимости могут возникнуть.
Единственный надежный способ изменить URL-адрес без изменения страниц - использовать внутреннюю ссылку или хеш. например: http://site.com/page.html становится http://site.com/page.html#item1. Этот метод часто используется в hijax (AJAX + сохраняет историю).
При этом я часто просто использую ссылки для действий с хешем в качестве href, а затем добавляю события щелчка с помощью jquery, которые используют запрошенный хеш для определения и делегирования действия.
Надеюсь, это наставит вас на правильный путь.
Извините, но ваш ответ неверен. Да, вы можете изменить URL-адрес.
Да, вы можете использовать api истории html5, но это не кроссбраузерно, хотя вы можете использовать поли-заливку, которая будет использовать хеш-адреса.
window.location.href содержит текущий URL. Вы можете читать из него, вы можете добавлять к нему или заменять его, что может вызвать перезагрузку страницы.
Если, как это звучит, вы хотите записать состояние javascript в URL-адрес, чтобы его можно было добавить в закладки, без перезагрузки страницы, добавьте его к текущему URL-адресу после # и пусть фрагмент javascript, вызванный событием onload, проанализирует текущий URL-адрес, чтобы узнать, содержит ли он сохраненное состояние.
Если вы используете? вместо # вы вызовете принудительную перезагрузку страницы, но поскольку вы будете анализировать сохраненное состояние при загрузке, это может не быть проблемой; и это заставит кнопки вперед и назад работать правильно.
запись состояния javascript в URL-адрес - это именно то, что я пытаюсь сделать
Существует компонент Yahoo YUI (диспетчер истории браузера), который может справиться с этим: http://developer.yahoo.com/yui/history/
Мне было интересно, возможно ли это, если родительский путь на странице такой же, только к нему добавляется что-то новое.
Допустим, пользователь находится на странице: http://domain.com/site/page.html.
Тогда браузер может позволить мне сделать location.append = new.html
и страница становится: http://domain.com/site/page.htmlnew.html, и браузер не меняет ее.
Или просто позвольте человеку изменить параметр получения, так что давайте location.get = me=1&page=1.
Таким образом, исходная страница становится http://domain.com/site/page.html?me=1&page=1 и не обновляется.
Проблема с # в том, что данные не кэшируются (по крайней мере, я так не думаю) при изменении хеша. Это похоже на загрузку новой страницы, тогда как кнопки «назад» и «вперед» на странице, отличной от Аякс, могут кэшировать данные и не тратить время на повторную загрузку данных.
Из того, что я видел, история Yahoo уже загружает все данные сразу. Похоже, он не выполняет никаких запросов Ajax. Поэтому, когда div используется для обработки различных методов сверхурочно, эти данные не сохраняются для каждого состояния истории.
В HTML 5 используйте history.pushState функция. Например:
<script type = "text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>
и href:
<a href = "#" id='click'>Click to change url to bar.html</a>
Если вы хотите изменить URL-адрес без добавления записи в список кнопок «Назад», используйте вместо этого history.replaceState.
Вы правы, в прошлый раз я экспериментировал с Chrome. Я только что пробовал с Firefox 3.6 на моем Ubuntu, это не сработало. Думаю, нам придется подождать, пока HTML5 не будет полностью поддерживаться в FF.
Пример кода вырезан и вставлен из developer.mozilla.org/en/DOM/Manipulating_the_browser_histor y. Что на самом деле затрудняет объяснение того, что означают foo и bar в данном случае.
Foo и bar ничего не значат, это произвольно определенный объект состояния, к которому вы можете вернуться позже.
@Paul: да, в статье выше есть эта информация.
В момент публикации этого комментария он работает на Firefox Chrome и Safari. Хотя с мобильным сафари на ipad или iphone не повезло :(
благодарю за ответ. Я думаю, что replaceState будет лучшим выбором: history.replaceState({"test":"test}, document.title, "bar.html");
Я до сих пор не могу на 100% понять, какова / была первоначальная цель объекта состояния (после прочтения связанной статьи (статей). Как наилучшим образом использовать ее?
Фотогалерея Facebook делает это с помощью #hash в URL-адресе. Вот несколько примеров URL-адресов:
Перед тем, как нажать «Далее»:
/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507
После нажатия кнопки «Далее»:
/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507
Обратите внимание на знак решетки (#!), Сразу за которым следует новый URL.
Есть плагин jquery http://www.asual.com/jquery/address/
Думаю, это то, что вам нужно.
jQuery имеет отличный плагин для изменения URL-адреса браузеров, который называется jQuery-толкатель.
JavaScript pushState и jQuery можно использовать вместе, например:
history.pushState(null, null, $(this).attr('href'));
Пример:
$('a').click(function (event) {
// Prevent default click action
event.preventDefault();
// Detect if pushState is available
if (history.pushState) {
history.pushState(null, null, $(this).attr('href'));
}
return false;
});
Использование только JavaScripthistory.pushState(), который изменяет реферер, который используется в заголовке HTTP для объектов XMLHttpRequest, созданных после изменения состояния.
Пример:
window.history.pushState("object", "Your New Title", "/new-url");
Метод pushState ():
pushState() принимает три параметра: объект состояния, заголовок (который в настоящее время игнорируется) и (необязательно) URL-адрес. Давайте рассмотрим каждый из этих трех параметров более подробно:
государственный объект - объект состояния - это объект JavaScript, связанный с новой записью истории, созданной pushState(). Каждый раз, когда пользователь переходит в новое состояние, запускается событие popstate, а свойство state события содержит копию объекта состояния записи истории.
Объект состояния может быть чем угодно, что может быть сериализовано. Поскольку Firefox сохраняет объекты состояния на диск пользователя, чтобы их можно было восстановить после перезапуска пользователем своего браузера, мы накладываем ограничение на размер в 640 тыс. Символов для сериализованного представления объекта состояния. Если вы передадите объект состояния, сериализованное представление которого больше этого, в pushState(), метод вызовет исключение. Если вам нужно больше места, рекомендуется использовать sessionStorage и / или localStorage.
заглавие - Firefox в настоящее время игнорирует этот параметр, хотя может использовать его в будущем. Передача здесь пустой строки должна быть защищена от будущих изменений метода. В качестве альтернативы вы можете передать короткое название состояния, в которое вы переходите.
URL - URL новой записи истории задается этим параметром. Обратите внимание, что браузер не будет пытаться загрузить этот URL-адрес после вызова pushState(), но он может попытаться загрузить URL-адрес позже, например, после того, как пользователь перезапустит свой браузер. Новый URL не обязательно должен быть абсолютным; если он относительный, он разрешается относительно текущего URL-адреса. Новый URL-адрес должен иметь то же происхождение, что и текущий URL-адрес; в противном случае pushState() вызовет исключение. Этот параметр не является обязательным; если он не указан, устанавливается текущий URL-адрес документа.
мой код:
//change address bar
function setLocation(curLoc){
try {
history.pushState(null, null, curLoc);
return false;
} catch(e) {}
location.hash = '#' + curLoc;
}
и действие:
setLocation('http://example.com/your-url-here');
и пример
$(document).ready(function(){
$('nav li a').on('click', function(){
if ($(this).hasClass('active')) {
} else {
setLocation($(this).attr('href'));
}
return false;
});
});
Это все :)
Я добился успеха с:
location.hash = "myValue";
Он просто добавляет #myValue к текущему URL-адресу. Если вам нужно инициировать событие на странице Load, вы можете использовать тот же location.hash для проверки соответствующего значения. Просто не забудьте удалить # из значения, возвращаемого location.hash, например.
var articleId = window.location.hash.replace("#","");
У меня работает - функция history.replaceState(), которая выглядит следующим образом -
history.replaceState(data,"Title of page"[,'url-of-the-page']);
Это не приведет к перезагрузке страницы, вы можете использовать ее с событием javascript.
Я представляю более простой ответ,
window.history.pushState(null, null, "/abc")
это добавит /abc после имени домена в URL-адресе браузера. Просто скопируйте этот код и вставьте его в консоль браузера, и вы увидите, как URL-адрес изменится на «https://stackoverflow.com/abc».
Это было бы так хорошо. Конечно, это будет ограничено модификациями в одном домене. Но некоторый клиентский контроль пути (а не только хеша) является логичным шагом сейчас, когда перезагрузка страницы является своего рода «последним средством» для многих приложений.