JS событие на другой вкладке

244
13 октября 2017, 18:34

Открываю страницу mysite.com/1.php в браузере со следующим кодом:

window.addEventListener('storage', function(e) { alert(1); } )

Далее открываю в новой вкладу вторую страницу mysite.com/2.php со следующим кодом:

localStorage.setItem('name', 42);

По задумке нужно что бы открытии mysite.com/2.php на странице mysite.com/1.php сработал алерт, но он не срабатывает.
Раньше никогда не работал с storage.
Подскажите что не так, если можно, приведите рабочий пример.

Answer 1

Событие срабатывает только при изменении. Т. е. когда ты впервые откроешь вторую страницу, если в этот момент открыта первая, то на ней выполнится подписчик и (при условии, что браузер не блокирует alert'ы с неактивных вкладок) сработает alert.

При последующих записях событие не выполнится, поскольку изменения значения не происходит - ты записываешь то, что там находится.

Если ты хочешь alert на каждое обновление страницы, замени свои 42 на Math.ramdom().

Проверял в хроме на таком коде:

const http = require('http');
const hostname = '0.0.0.0';
const port = 3000;
http.createServer((req, res) => {
  var url = req.url.substr(1);
  var script = "";
  switch (url) {
    case '1':
      script = "window.addEventListener('storage', function(e) { alert(1); } )";
      break;
    case '2':
      script = "localStorage.setItem('name', Math.random());";
      break;
    default:
      res.writeHead(404);
      res.end();
  }
  res.writeHead(200, { 'content-type': 'text/html' });
  res.end(`<!doctype html>
    <title>Page #${url}</title>
    <script>${script}</script>
    <h1>${url}</h1>
  `);
}).listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Скринвидео (41 секунда): https://cloud.mail.ru/public/Be2J/o5T7ZhHgU
Если скачать оригинал, то 1.03 MB, кодек h264.

Answer 2

Логично, что window.addEventListener просматривает событие в пределах одного окна/таба, а по работе с storage, я так понимаю страница должна быть одна и та же, то есть если открыть две одинаковые страницы, то предложенный вариант с window.addEventListener будет работать. А если без window.addEventListener можно реализовать след. образом:

1.php

var storageParam = "name";
var defaultStorageVal = localStorage.getItem(storageParam);
setInterval(function() {
    var val = localStorage.getItem(storageParam);
    if (val != defaultStorageVal) {
        alert(1);
        defaultStorageVal = val;
        // если alert один раз только должен сработать, убейте интервал
    }
}, 500); // тут уже сами смотрите

Если в 2.php выполнить код ниже, то на 1.php выполнится alert

localStorage.setItem("name", 12);
READ ALSO
Создание элементов с помощью js

Создание элементов с помощью js

Как создать элемент с помощью ``- такой строки чтобы передать переменные, при createElement создается просто пустой div

243
Yii - добавление значений в dropDownList

Yii - добавление значений в dropDownList

Модель отправляет в dropDownList массив из таблицы БД, нужно сделать возможность добавлять новые значения в эту таблицуКак сделать добавление...

210