Дорожка, когда пользователь поражает кнопку "Назад" в браузер

Во время недавнего опыта написания JS-переводчика я много боролся с внутренней работой дат ECMA / JS. Итак, я полагаю, что я брошу свои 2 цента здесь. Надеемся, что совместное использование этого материала поможет другим с любыми вопросами о различиях между браузерами в том, как они обрабатывают даты.

Сторона входа

Все реализации хранят свои значения даты внутри себя как 64-разрядные номера которые представляют собой миллисекунды с 01.01.1970 UTC (GMT - это то же самое, что и UTC). Даты, возникающие после 1/1/1970 00:00:00, являются положительными числами, а даты предшествуют отрицательным.

Поэтому следующий код дает точный результат во всех браузерах.

Date.parse('1/1/1970');

В моей временной зоне ( EST), результат составляет 18000000, потому что это то, сколько мс составляет 5 часов (это всего 4 часа в летние месяцы). Значение будет отличаться в разных часовых поясах. Все основные браузеры делают это одинаково.

Вот и все. Несмотря на то, что в форматах входных строк есть некоторые отклонения, которые основные браузеры будут анализировать как даты, они по существу интерпретируют их одинаково с часовыми поясами и летней экономией. Один из них - формат ISO 8601. Это единственный формат, специально описанный в спецификации ECMA-262 v.5. Для всех других строковых форматов интерпретация зависит от реализации. По иронии судьбы, это формат, в котором браузеры могут отличаться. Ниже приведен сравнительный вывод Chrome vs Firefox для 1/1/1970 на моей машине с использованием формата строки ISO 8601.

Date.parse('1970-01-01T00:00:00Z');       // Chrome: 0         FF: 0
Date.parse('1970-01-01T00:00:00-0500');   // Chrome: 18000000  FF: 18000000
Date.parse('1970-01-01T00:00:00');        // Chrome: 0         FF: 18000000
  • Спецификатор «Z» указывает, что вход уже находится в UTC и не требует смещения перед хранением.
  • Спецификатор «-0500» указывает, что вход находится в GMT-05: 00, поэтому оба браузера интерпретируют ввод как находящийся в моем локальном часовом поясе. Это означает, что значение будет преобразовано в UTC перед сохранением. В моем случае это означает добавление 18000000 мс к внутреннему значению даты, что требует сдвига -18000000 мс (-05: 00), чтобы вернуть меня в локальное время.
  • Однако, когда спецификатор отсутствует, FF обрабатывает ввод в качестве локального времени, в то время как Chrome рассматривает его как время UTC. Для меня это создает 5-часовую разницу в сохраненной стоимости, что является проблематичным. В моей реализации я оказался на стороне FF здесь, потому что мне нравится вывод toString для соответствия моему входному значению, если я не укажу альтернативный часовой пояс, который я никогда не делаю. Отсутствие спецификатора должно предполагать местный вход времени.

Но здесь ситуация ухудшается, FF обрабатывает краткую форму формата ISO 8601 («YYYY -MM-DD ") по-разному, чем обрабатывает длинную форму (« YYYY-MM-DDTHH: mm: ss: sssZ ») без каких-либо логических причин. Вот результат из FF с длинными и короткими форматами даты ISO без спецификатора часового пояса.

Date.parse('1970-01-01T00:00:00');       // 18000000
Date.parse('1970-01-01');                // 0

Итак, чтобы ответить на вопрос первоначального вопросчика, "YYYY-MM-DD" - это короткая форма ISO 8601 "YYYY-MM-DDTHH:mm:ss:sssZ". Таким образом, это интерпретируется как время UTC, тогда как другое интерпретируется как локальное. Вот почему,

Это не jive:

console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08")).toString());

Это делает:

console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());

Нижняя строка - это строка синтаксического анализа. Единственная строка ISO 8601, которую вы можете безопасно анализировать в браузерах, - это длинная форма. И ВСЕГДА используйте спецификатор «Z». Если вы это сделаете, вы можете спокойно перемещаться между локальным и UTC.

Это работает в браузерах (после IE9):

console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());

К счастью, большинство современных браузеров другие форматы ввода одинаково, включая наиболее часто используемые форматы «1/1/1970» и «1/1/1970 00:00:00 AM». Все следующие форматы (и другие) рассматриваются как локальный ввод времени во всех браузерах и конвертируются в UTC перед хранением. Таким образом, они совместимы с кросс-браузером. Выходной код этого кода во всех браузерах в моем часовом поясе одинаковый.

console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));

Сторона выхода

. На стороне вывода все браузеры переводили часовые пояса одинаково, но они обрабатывать строковые форматы по-разному. Вот функции toString и то, что они выводят. Обратите внимание на то, что функции toUTCString и toISOString выводят на моей машине 5:00 AM.

Конвертирует с UTC в локальное время перед печатью

 - toString
 - toDateString
 - toTimeString
 - toLocaleString
 - toLocaleDateString
 - toLocaleTimeString

Прямая печать сохраненного времени UTC

 - toUTCString
 - toISOString 

In Chrome
toString            Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString        Thu Jan 01 1970
toTimeString        00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString      1/1/1970 12:00:00 AM
toLocaleDateString  1/1/1970
toLocaleTimeString  00:00:00 AM

toUTCString         Thu, 01 Jan 1970 05:00:00 GMT
toISOString         1970-01-01T05:00:00.000Z

In Firefox
toString            Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString        Thu Jan 01 1970
toTimeString        00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString      Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString  Thursday, January 01, 1970
toLocaleTimeString  12:00:00 AM

toUTCString         Thu, 01 Jan 1970 05:00:00 GMT
toISOString         1970-01-01T05:00:00.000Z

Я обычно не используйте формат ISO для ввода строки. Единственный раз, когда использование этого формата полезно для меня, - это когда даты нужно сортировать как строки. Формат ISO можно сортировать как есть, а другие - нет. Если у вас есть совместимость с несколькими браузерами, укажите либо часовой пояс, либо используйте совместимый строковый формат.

Код new Date('12/4/2013').toString() проходит через следующее внутреннее псевдопреобразование:

  "12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"

Надеюсь, этот ответ был полезен.

23
задан ɢʀᴜɴᴛ 25 June 2017 в 10:15
поделиться

5 ответов

Существует несколько способов сделать его, хотя некоторые будут только работать в определенных браузерах. Тот, который я знаю первое, что пришло на ум, должен встроить крошечный почти невидимый iframe на странице. Когда пользователь поражает кнопку "Назад", по iframe перемещаются назад, который можно обнаружить и затем обновить страницу. Здесь другое решение.

Вы могли бы также хотеть пойти источник представления на чем-то как Gmail и видеть, как они делают это.

Вот библиотека для вида вещи, которую Вы ищете между прочим

14
ответ дан George Mauer 29 November 2019 в 01:46
поделиться

Одна из моих любимых платформ для того, чтобы сделать это менеджер по Истории Браузера Yahoo! . Вы регистрируете события, и это отзывает Вас, когда пользователь возвращается Назад к тому состоянию. И если Вы хотите изучить, как это работает, вот забавная запись в блоге о Yahoo! решений, сделанном при разработке его.

16
ответ дан Wayne Kao 29 November 2019 в 01:46
поделиться

Нет никакого способа сказать, когда пользователь нажимает кнопку "Назад" нажатий клавиша Backspace для возвращения в браузере, однако существуют другие события, которые происходят в определенном порядке, которые обнаруживаемы. Этот пример javascript имеет довольно хороший метод для обнаружения, назад управляет:

традиционный путь, однако, состоит в том, чтобы отследить пользовательское перемещение через Ваш сайт с помощью страниц ссылающегося домена или cookie. То, когда пользователь переходит к странице A, затем странице B, затем появляется на уровне страницы A снова (особенно, когда нет никакой ссылки на B к A), тогда, Вы знаете, что они возвратились - A, может обнаружить это и перенаправить их или иначе.

7
ответ дан Adam Davis 29 November 2019 в 01:46
поделиться

Библиотека Пользовательского интерфейса Yahoo, моя любимая клиентская библиотека JS, имеет превосходное менеджер по Истории Браузера , который делает точно, что Вы просите.

3
ответ дан Josh Hinman 29 November 2019 в 01:46
поделиться

Инструментарий додзе имеет функциональность для контакта с этим в JavaScript. Я не думаю, что существует любой хороший способ обработать его в чистом PHP.

Вот страница документов, которую они имеют: http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/back-button-undo

1
ответ дан Scott Swezey 29 November 2019 в 01:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: