前端打开新的独立标签页面,并且指定标签页的大小,管理新标签页面的打开和关闭(包含源码和使用文档)

WindowManager 窗口管理器

一个用于管理浏览器新标签页面的完整解决方案,提供窗口的打开、关闭、监控和管理功能。

功能特性

  • ✅ 打开新窗口并自动管理
  • ✅ 关闭指定窗口或所有窗口
  • ✅ 获取窗口信息和状态
  • ✅ 窗口聚焦和切换
  • ✅ 批量窗口管理
  • ✅ 自动清理已关闭的窗口记录
  • ✅ 窗口状态监控
  • ✅ 错误处理和验证

主要方法

1. 打开窗口

openNewWindow(url, windowName, width, height, options)

打开一个新窗口并自动添加到管理器中。

参数:

  • url (string): 要打开的URL
  • windowName (string): 窗口名称,用作窗口ID
  • width (number): 窗口宽度,默认800
  • height (number): 窗口高度,默认600
  • options (object): 窗口选项

选项:

javascript 复制代码
{
  scrollbars: true,    // 是否显示滚动条
  resizable: true,     // 是否可调整大小
  toolbar: false,      // 是否显示工具栏
  menubar: false,      // 是否显示菜单栏
  location: false,     // 是否显示地址栏
  status: false,       // 是否显示状态栏
  directories: false,  // 是否显示目录按钮
  copyhistory: false   // 是否复制历史记录
}

示例:

javascript 复制代码
import { openNewWindow } from '@/utils/windowManager'

const newWindow = openNewWindow(
  'https://www.example.com',
  'my_window',
  1000,
  700,
  { toolbar: true, location: true }
)
openCenteredWindow(url, width, height)

打开一个居中的简化窗口。

示例:

javascript 复制代码
import { openCenteredWindow } from '@/utils/windowManager'

const window = openCenteredWindow('https://www.example.com', 900, 600)

2. 关闭窗口

closeWindow(windowId)

关闭指定的窗口。

参数:

  • windowId (string): 窗口ID

返回值:

  • boolean: 是否成功关闭

示例:

javascript 复制代码
import { closeWindow } from '@/utils/windowManager'

const success = closeWindow('my_window')
if (success) {
  console.log('窗口已关闭')
}
closeAllWindows()

关闭所有已打开的窗口。

返回值:

  • number: 成功关闭的窗口数量

示例:

javascript 复制代码
import { closeAllWindows } from '@/utils/windowManager'

const closedCount = closeAllWindows()
console.log(`已关闭 ${closedCount} 个窗口`)

3. 获取窗口信息

getWindowInfo(windowId)

获取指定窗口的详细信息。

返回值:

javascript 复制代码
{
  window: Window,      // 窗口对象
  url: string,         // 窗口URL
  name: string,        // 窗口名称
  openedAt: Date,      // 打开时间
  width: number,       // 窗口宽度
  height: number,      // 窗口高度
  isClosed: boolean,   // 是否已关闭
  isActive: boolean    // 是否处于活跃状态
}
getAllWindows()

获取所有已打开窗口的列表。

getActiveWindowCount()

获取当前活跃窗口的数量。

4. 窗口操作

focusWindow(windowId)

聚焦到指定窗口。

isWindowOpen(windowId)

检查窗口是否存在且未关闭。

5. 管理功能

cleanupClosedWindows()

清理已关闭的窗口记录。

getManagerStatus()

获取窗口管理器的完整状态。

返回值:

javascript 复制代码
{
  totalWindows: number,    // 总窗口数
  activeWindows: number,   // 活跃窗口数
  closedWindows: number,   // 已关闭窗口数
  windows: Array          // 所有窗口信息数组
}

使用示例

基本使用

javascript 复制代码
import { 
  openNewWindow, 
  closeWindow, 
  getAllWindows 
} from '@/utils/windowManager'

// 打开窗口
const window = openNewWindow('https://www.example.com', 'test_window')

// 获取所有窗口
const allWindows = getAllWindows()
console.log('当前窗口:', allWindows)

// 关闭窗口
closeWindow('test_window')

批量管理

javascript 复制代码
import { 
  openNewWindow, 
  closeAllWindows, 
  getActiveWindowCount 
} from '@/utils/windowManager'

// 打开多个窗口
const urls = ['https://google.com', 'https://github.com', 'https://stackoverflow.com']
urls.forEach((url, index) => {
  openNewWindow(url, `window_${index}`)
})

// 检查窗口数量
console.log('活跃窗口数量:', getActiveWindowCount())

// 关闭所有窗口
closeAllWindows()

状态监控

javascript 复制代码
import { 
  openNewWindow, 
  getManagerStatus, 
  cleanupClosedWindows 
} from '@/utils/windowManager'

// 打开测试窗口
openNewWindow('https://www.example.com', 'monitor_window')

// 定期检查状态
const interval = setInterval(() => {
  const status = getManagerStatus()
  console.log('管理器状态:', status)
  
  // 清理已关闭的窗口
  if (status.closedWindows > 0) {
    cleanupClosedWindows()
  }
  
  // 如果没有活跃窗口,停止监控
  if (status.activeWindows === 0) {
    clearInterval(interval)
  }
}, 2000)

注意事项

  1. 浏览器限制: 某些浏览器可能会阻止弹出窗口,需要用户授权。

  2. 跨域限制: 无法操作不同域名的窗口。

  3. 窗口关闭检测: 当用户手动关闭窗口时,管理器会自动清理相关记录。

  4. 内存管理 : 建议定期调用 cleanupClosedWindows() 清理已关闭的窗口记录。

  5. 错误处理: 所有方法都包含错误处理,失败时会返回相应的错误信息。

在Vue组件中使用

vue 复制代码
<template>
  <div>
    <button @click="openWindow">打开窗口</button>
    <button @click="closeAll">关闭所有</button>
    <div>活跃窗口: {{ activeCount }}</div>
  </div>
</template>

<script>
import { 
  openNewWindow, 
  closeAllWindows, 
  getActiveWindowCount 
} from '@/utils/windowManager'

export default {
  data() {
    return {
      activeCount: 0
    }
  },
  methods: {
    openWindow() {
      openNewWindow('https://www.example.com', 'vue_window')
      this.updateCount()
    },
    closeAll() {
      closeAllWindows()
      this.updateCount()
    },
    updateCount() {
      this.activeCount = getActiveWindowCount()
    }
  },
  mounted() {
    this.updateCount()
  }
}
</script>

源码

javascript 复制代码
/**
 * 窗口管理器 - 管理新标签页面的打开和关闭
 */

// 存储已打开的窗口
const openedWindows = new Map()

/**
 * 弹出新窗口并设置窗口大小
 * @param {string} url - 要打开的URL
 * @param {string} windowName - 窗口名称
 * @param {number} width - 窗口宽度
 * @param {number} height - 窗口高度
 * @param {boolean} scrollbars - 是否显示滚动条
 * @param {boolean} resizable - 是否可调整大小
 * @param {boolean} toolbar - 是否显示工具栏
 * @param {boolean} menubar - 是否显示菜单栏
 * @param {boolean} location - 是否显示地址栏
 * @param {boolean} status - 是否显示状态栏
 * @param {boolean} directories - 是否显示目录按钮
 * @param {boolean} copyhistory - 是否复制历史记录
 * @returns {Window|null} 返回新窗口对象,如果打开失败则返回null
 */
export function openNewWindow(url, windowName = '_blank', width = 800, height = 600, options = {}) {
    // 默认选项
    const defaultOptions = {
      scrollbars: true,
      resizable: true,
      toolbar: false,
      menubar: false,
      location: false,
      status: false,
      directories: false,
      copyhistory: false
    }
    
    // 合并用户选项和默认选项
    const finalOptions = { ...defaultOptions, ...options }
    
    // 计算窗口位置,使其居中显示
    const left = (window.screen.width - width) / 2
    const top = (window.screen.height - height) / 2
    
    // 构建窗口特性字符串
    const features = [
      `width=${width}`,
      `height=${height}`,
      `left=${left}`,
      `top=${top}`,
      `scrollbars=${finalOptions.scrollbars ? 'yes' : 'no'}`,
      `resizable=${finalOptions.resizable ? 'yes' : 'no'}`,
      `toolbar=${finalOptions.toolbar ? 'yes' : 'no'}`,
      `menubar=${finalOptions.menubar ? 'yes' : 'no'}`,
      `location=${finalOptions.location ? 'yes' : 'no'}`,
      `status=${finalOptions.status ? 'yes' : 'no'}`,
      `directories=${finalOptions.directories ? 'yes' : 'no'}`,
      `copyhistory=${finalOptions.copyhistory ? 'yes' : 'no'}`
    ].join(',')
    
    try {
      // 打开新窗口
      const newWindow = window.open(url, windowName, features)
      
      // 检查窗口是否成功打开
      if (newWindow) {
        // 如果新窗口被阻止,尝试使用默认方式打开
        if (newWindow.closed || typeof newWindow.closed === 'undefined') {
          console.warn('新窗口可能被浏览器阻止,尝试使用默认方式打开')
          return window.open(url, windowName)
        }
        
        // 将新窗口添加到管理器中
        const windowId = windowName || `window_${Date.now()}`
        openedWindows.set(windowId, {
          window: newWindow,
          url: url,
          name: windowName,
          openedAt: new Date(),
          width: width,
          height: height
        })
        
        // 监听窗口关闭事件
        newWindow.addEventListener('beforeunload', () => {
          removeWindow(windowId)
        })
        
        return newWindow
      } else {
        console.error('无法打开新窗口,可能被浏览器阻止')
        return null
      }
    } catch (error) {
      console.error('打开新窗口时发生错误:', error)
      return null
    }
  }
  
  /**
   * 打开一个居中的新窗口(简化版本)
   * @param {string} url - 要打开的URL
   * @param {number} width - 窗口宽度
   * @param {number} height - 窗口高度
   * @returns {Window|null} 返回新窗口对象
   */
  export function openCenteredWindow(url, width = 800, height = 600) {
    return openNewWindow(url, '_blank', width, height)
  }

/**
 * 关闭指定的窗口
 * @param {string} windowId - 窗口ID
 * @returns {boolean} 是否成功关闭
 */
export function closeWindow(windowId) {
  const windowInfo = openedWindows.get(windowId)
  if (windowInfo && windowInfo.window) {
    try {
      windowInfo.window.close()
      openedWindows.delete(windowId)
      console.log(`窗口 ${windowId} 已关闭`)
      return true
    } catch (error) {
      console.error(`关闭窗口 ${windowId} 时发生错误:`, error)
      return false
    }
  }
  console.warn(`未找到窗口 ${windowId}`)
  return false
}

/**
 * 关闭所有已打开的窗口
 * @returns {number} 成功关闭的窗口数量
 */
export function closeAllWindows() {
  let closedCount = 0
  const windowIds = Array.from(openedWindows.keys())
  
  windowIds.forEach(windowId => {
    if (closeWindow(windowId)) {
      closedCount++
    }
  })
  
  console.log(`已关闭 ${closedCount} 个窗口`)
  return closedCount
}

/**
 * 获取指定窗口的信息
 * @param {string} windowId - 窗口ID
 * @returns {Object|null} 窗口信息对象
 */
export function getWindowInfo(windowId) {
  const windowInfo = openedWindows.get(windowId)
  if (windowInfo) {
    return {
      ...windowInfo,
      isClosed: windowInfo.window.closed,
      isActive: !windowInfo.window.closed && windowInfo.window.document.hasFocus()
    }
  }
  return null
}

/**
 * 获取所有已打开窗口的列表
 * @returns {Array} 窗口信息数组
 */
export function getAllWindows() {
  const windows = []
  openedWindows.forEach((windowInfo, windowId) => {
    windows.push({
      id: windowId,
      ...windowInfo,
      isClosed: windowInfo.window.closed,
      isActive: !windowInfo.window.closed && windowInfo.window.document.hasFocus()
    })
  })
  return windows
}

/**
 * 获取活跃窗口的数量
 * @returns {number} 活跃窗口数量
 */
export function getActiveWindowCount() {
  let count = 0
  openedWindows.forEach((windowInfo) => {
    if (!windowInfo.window.closed) {
      count++
    }
  })
  return count
}

/**
 * 聚焦到指定窗口
 * @param {string} windowId - 窗口ID
 * @returns {boolean} 是否成功聚焦
 */
export function focusWindow(windowId) {
  const windowInfo = openedWindows.get(windowId)
  if (windowInfo && !windowInfo.window.closed) {
    try {
      windowInfo.window.focus()
      return true
    } catch (error) {
      console.error(`聚焦窗口 ${windowId} 时发生错误:`, error)
      return false
    }
  }
  return false
}

/**
 * 从管理器中移除窗口(不关闭窗口)
 * @param {string} windowId - 窗口ID
 * @returns {boolean} 是否成功移除
 */
export function removeWindow(windowId) {
  const removed = openedWindows.delete(windowId)
  if (removed) {
    console.log(`窗口 ${windowId} 已从管理器中移除`)
  }
  return removed
}

/**
 * 清理已关闭的窗口记录
 * @returns {number} 清理的窗口数量
 */
export function cleanupClosedWindows() {
  let cleanedCount = 0
  const windowIds = Array.from(openedWindows.keys())
  
  windowIds.forEach(windowId => {
    const windowInfo = openedWindows.get(windowId)
    if (windowInfo && windowInfo.window.closed) {
      openedWindows.delete(windowId)
      cleanedCount++
    }
  })
  
  console.log(`清理了 ${cleanedCount} 个已关闭的窗口记录`)
  return cleanedCount
}

/**
 * 检查窗口是否存在且未关闭
 * @param {string} windowId - 窗口ID
 * @returns {boolean} 窗口是否存在且未关闭
 */
export function isWindowOpen(windowId) {
  const windowInfo = openedWindows.get(windowId)
  return windowInfo && !windowInfo.window.closed
}

/**
 * 获取窗口管理器状态
 * @returns {Object} 管理器状态信息
 */
export function getManagerStatus() {
  const totalWindows = openedWindows.size
  const activeWindows = getActiveWindowCount()
  const closedWindows = totalWindows - activeWindows
  
  return {
    totalWindows,
    activeWindows,
    closedWindows,
    windows: getAllWindows()
  }
}

使用实例

javascript 复制代码
/**
 * windowManager 使用示例
 * 展示如何使用窗口管理器的各种功能
 */

import {
  openNewWindow,
  openCenteredWindow,
  closeWindow,
  closeAllWindows,
  getWindowInfo,
  getAllWindows,
  getActiveWindowCount,
  focusWindow,
  cleanupClosedWindows,
  isWindowOpen,
  getManagerStatus
} from './windowManager.js'

// 示例1: 打开新窗口并管理
export function exampleOpenAndManageWindow() {
  console.log('=== 示例1: 打开新窗口并管理 ===')
  
  // 打开一个新窗口
  const newWindow = openNewWindow(
    'https://www.example.com',
    'example_window',
    1000,
    700,
    {
      toolbar: true,
      location: true
    }
  )
  
  if (newWindow) {
    console.log('新窗口已打开')
    
    // 获取窗口信息
    const windowInfo = getWindowInfo('example_window')
    console.log('窗口信息:', windowInfo)
    
    // 检查窗口状态
    console.log('窗口是否打开:', isWindowOpen('example_window'))
    
    // 聚焦到窗口
    focusWindow('example_window')
    
    // 3秒后关闭窗口
    setTimeout(() => {
      closeWindow('example_window')
    }, 3000)
  }
}

// 示例2: 批量管理多个窗口
export function exampleBatchWindowManagement() {
  console.log('=== 示例2: 批量管理多个窗口 ===')
  
  const urls = [
    'https://www.google.com',
    'https://www.github.com',
    'https://www.stackoverflow.com'
  ]
  
  const windowIds = []
  
  // 打开多个窗口
  urls.forEach((url, index) => {
    const windowId = `window_${index}`
    const newWindow = openNewWindow(url, windowId, 800, 600)
    if (newWindow) {
      windowIds.push(windowId)
    }
  })
  
  console.log('已打开窗口数量:', getActiveWindowCount())
  console.log('所有窗口列表:', getAllWindows())
  
  // 5秒后关闭所有窗口
  setTimeout(() => {
    const closedCount = closeAllWindows()
    console.log(`已关闭 ${closedCount} 个窗口`)
  }, 5000)
}

// 示例3: 窗口状态监控
export function exampleWindowStatusMonitoring() {
  console.log('=== 示例3: 窗口状态监控 ===')
  
  // 打开一个测试窗口
  openNewWindow('https://www.example.com', 'monitor_window', 600, 400)
  
  // 定期检查窗口状态
  const statusInterval = setInterval(() => {
    const status = getManagerStatus()
    console.log('管理器状态:', status)
    
    // 如果窗口被手动关闭,清理记录
    if (status.closedWindows > 0) {
      cleanupClosedWindows()
    }
    
    // 如果没有活跃窗口,停止监控
    if (status.activeWindows === 0) {
      clearInterval(statusInterval)
      console.log('所有窗口已关闭,停止监控')
    }
  }, 2000)
}

// 示例4: 简化的窗口操作
export function exampleSimpleWindowOperations() {
  console.log('=== 示例4: 简化的窗口操作 ===')
  
  // 使用简化方法打开居中窗口
  const simpleWindow = openCenteredWindow('https://www.example.com', 900, 600)
  
  if (simpleWindow) {
    console.log('简化窗口已打开')
    
    // 获取所有窗口信息
    const allWindows = getAllWindows()
    console.log('当前所有窗口:', allWindows)
    
    // 10秒后关闭
    setTimeout(() => {
      closeAllWindows()
    }, 10000)
  }
}

// 示例5: 错误处理和验证
export function exampleErrorHandling() {
  console.log('=== 示例5: 错误处理和验证 ===')
  
  // 尝试关闭不存在的窗口
  const result = closeWindow('non_existent_window')
  console.log('关闭不存在窗口的结果:', result)
  
  // 尝试聚焦不存在的窗口
  const focusResult = focusWindow('non_existent_window')
  console.log('聚焦不存在窗口的结果:', focusResult)
  
  // 检查不存在的窗口状态
  const exists = isWindowOpen('non_existent_window')
  console.log('不存在窗口的状态:', exists)
}

// 导出所有示例函数
export const examples = {
  exampleOpenAndManageWindow,
  exampleBatchWindowManagement,
  exampleWindowStatusMonitoring,
  exampleSimpleWindowOperations,
  exampleErrorHandling
}

// 使用说明
export const usageGuide = {
  openWindow: '使用 openNewWindow(url, windowName, width, height, options) 打开新窗口',
  closeWindow: '使用 closeWindow(windowId) 关闭指定窗口',
  closeAll: '使用 closeAllWindows() 关闭所有窗口',
  getInfo: '使用 getWindowInfo(windowId) 获取窗口信息',
  getAll: '使用 getAllWindows() 获取所有窗口列表',
  focus: '使用 focusWindow(windowId) 聚焦到指定窗口',
  cleanup: '使用 cleanupClosedWindows() 清理已关闭的窗口记录',
  checkStatus: '使用 isWindowOpen(windowId) 检查窗口是否打开',
  getStatus: '使用 getManagerStatus() 获取管理器状态'
}
相关推荐
布列瑟农的星空7 分钟前
大话设计模式——关注点分离原则下的事件处理
前端·后端·架构
山有木兮木有枝_10 分钟前
node文章生成器
javascript·node.js
yvvvy26 分钟前
前端必懂的 Cache 缓存机制详解
前端
北海几经夏41 分钟前
React自定义Hook
前端·react.js
龙在天1 小时前
从代码到屏幕,浏览器渲染网页做了什么❓
前端
TimelessHaze1 小时前
【performance面试考点】让面试官眼前一亮的performance性能优化
前端·性能优化·trae
yes or ok1 小时前
前端工程师面试题-vue
前端·javascript·vue.js
我要成为前端高手1 小时前
给不支持摇树的三方库(phaser) tree-shake?
前端·javascript
Noxi_lumors1 小时前
VITE BALABALA require balabla not supported
前端·vite
周胜22 小时前
node-sass
前端