如何确保一个窗口只使用一个标签页

问题描述 投票:1回答:1

如果一个人打开了一个以上的标签页,它会显示一个警告,说他们一次只能打开一个。我试图查看窗口对象,但它不能访问其他标签页的所有URL。你可以存储一个cookie或一个会话吗? 那会有用吗?

javascript browser
1个回答
0
投票

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>
© www.soinside.com 2019 - 2024. All rights reserved.