1

If a person has more than one tab open, it will show an alert that says they can only have one open at a time. I attempted looking at the window object but it doesn't access all the URLs from other tabs. Can u store a cookie or a session? would that work

Digital Pain
  • 37
  • 1
  • 7
  • There's no reliable way to do that as far as I know, however, you may feel interested in this: https://stackoverflow.com/questions/42513836/detect-multiple-tabs-or-windows-of-the-same-session-in-a-web-application – nick Jun 11 '20 at 07:33
  • that was a feature i was looking at using, thanks – Digital Pain Jun 11 '20 at 07:50

1 Answers1

1

enter image description here

const openedPages = document.getElementById('opened-pages')


const readTabs = (value) => {
  let tabs = value || localStorage.getItem('openedPages')
  try {
    tabs = JSON.parse(tabs)
  } catch (e) {
    tabs = []
  }
  return Array.isArray(tabs) ? tabs : []
}

const writeTabs = (tabs) => {
  localStorage.setItem('openedPages', JSON.stringify(tabs))
}

const deleteTabs = (tabs, dt) => {
  for (let i = 0; i < dt.length; ++i) {
    let x = tabs.indexOf(dt[i])
    if (x !== -1) {
      tabs.splice(x, 1)
    }
  }
  writeTabs(tabs)
}

// Test uniqTabUrl
const testOpen = async (tabs) => {
  const success = []
  const error = []
  for (let tab of tabs) {
    try {
      let res = await fetch(tab)
      let url = await res.text()
      success.push(url)
    } catch (e) {
      error.push(tab)
    }
  }
  return { success, error }
}

const testTabs = async (tabs) => {
  const { success, error } = await testOpen(tabs)
  if (error.length) {
    deleteTabs(tabs, error)
  }
  const mess = new Map(/* { url: count<number> } */)
  for (let u of success) {
    let count = mess.get(u)
    mess.set(u, (count ? ++count : 1))
  }
  openedPages.textContent = [...mess.entries()].map(([u, c]) => `"${u}": ${c}`).join('\n')
}

void function () {
  // Когда страница удалена - uniqTabUrl будет автоматически уничтожен
  // When the page is deleted - uniqTabUrl will be automatically destroyed
  const uniqTabUrl = URL.createObjectURL(
    new Blob([document.location.href], { type: 'text/plain' })
  )
  const tabs = [...(new Set([uniqTabUrl, ...readTabs()])).values()]
  testTabs(tabs)
  writeTabs(tabs)

  // Отслеживаем новые tabs | Track new tabs
  window.addEventListener('storage', ({ key, oldValue, newValue }) => {
    if (key === 'openedPages' && oldValue !== newValue) {
      tabs.splice(0)
      tabs.push(...readTabs(newValue))
      // Если кто-то удалил | If someone deleted
      if (!tabs.includes(uniqTabUrl)) {
        tabs.push(uniqTabUrl)
        writeTabs(tabs)
      }
      testTabs(tabs)
    }
  })

  // Даже если это не сработает | Even if it doesn’t work => testOpen()
  window.onunload = () => {
    deleteTabs(tabs, [uniqTabUrl])
  }
}()

HTML

<!-- index.html -->
<h1>Opened Pages</h1>
<ul>
  <li><a href="/a.html">Page A</a></li>
  <li><a href="/b.html">Page B</a></li>
</ul>
<pre id="opened-pages"></pre>
<script src="app.js"></script>

<!-- a.html -->
<h1>Opened Pages | Page A</h1>
<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/b.html">Page B</a></li>
</ul>
<pre id="opened-pages"></pre>
<script src="app.js"></script>

<!-- b.html -->
<h1>Opened Pages | Page B</h1>
<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/a.html">Page A</a></li>
</ul>
<pre id="opened-pages"></pre>
<script src="app.js"></script>