如何编写代码将HTML文档显示窗口调整至屏幕右上角并占1/4区域
问题描述
我正在开发一个带HTML文档展示的演示程序,需要把显示该HTML的窗口固定在屏幕右上角,占四分之一屏幕区域。试过用批处理调用IE、WinForms,但都依赖IE,我的HTML文件在IE里无法正常运行;也试过写批处理调整Edge/Chrome窗口大小,同样失败。怀疑是JavaScript不兼容IE,而且因为安全限制不能使用AutoHotKey和浏览器扩展。想问有没有可行方案?要不要修改JS适配IE,或者其他解决办法?
可行解决方案
方案1:用Electron打包成独立桌面窗口(推荐)
Electron可以将HTML/CSS/JS打包成原生桌面应用,完全脱离IE依赖,还能精准控制窗口的位置和尺寸:
- 安装Node.js,然后在项目目录执行初始化命令:
npm init -y - 安装Electron依赖:
npm install electron --save-dev - 创建主入口文件
main.js:const { app, BrowserWindow } = require('electron'); const path = require('path'); function createWindow() { // 获取屏幕分辨率 const { screen } = require('electron'); const display = screen.getPrimaryDisplay(); const screenWidth = display.bounds.width; const screenHeight = display.bounds.height; // 计算右上角四分之一区域的参数 const winWidth = Math.floor(screenWidth / 2); const winHeight = Math.floor(screenHeight / 2); const winX = screenWidth - winWidth; const winY = 0; const mainWindow = new BrowserWindow({ width: winWidth, height: winHeight, x: winX, y: winY, webPreferences: { nodeIntegration: false, contextIsolation: true } }); // 加载本地HTML文件 mainWindow.loadFile('index.html'); // 隐藏菜单栏(可选) mainWindow.setMenuBarVisibility(false); } app.whenReady().then(() => { createWindow(); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); - 修改
package.json的启动脚本:"scripts": { "start": "electron .", "package": "electron-packager . LADDemo --platform=win32 --arch=x64" } - 测试运行:
npm start;打包成可执行文件:npm run package
方案2:用PowerShell精准控制Edge/Chrome窗口
之前的批处理失败大概率是窗口识别不准确,用PowerShell调用Windows API可以解决这个问题:
创建launch-and-position.ps1文件:
# 启动Edge的无工具栏应用模式,加载本地HTML $htmlFullPath = (Get-Item .\index.html).FullName Start-Process msedge.exe "--app=$htmlFullPath" # 等待窗口加载完成 Start-Sleep -Seconds 2 # 导入Windows API用于窗口操作 Add-Type @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); } "@ # 根据HTML标题查找Edge窗口(--app模式下窗口标题等于HTML的<title>内容) $windowHandle = [Win32]::FindWindow("Chrome_WidgetWin_1", "LAD Touchscreen Demo") if ($windowHandle -ne [IntPtr]::Zero) { $screenWidth = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width $screenHeight = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height $winWidth = $screenWidth / 2 $winHeight = $screenHeight / 2 $winX = $screenWidth - $winWidth $winY = 0 # 调整窗口到右上角四分之一区域 [Win32]::SetWindowPos($windowHandle, [IntPtr]::Zero, $winX, $winY, $winWidth, $winHeight, 0x0040) }
运行命令:
powershell -ExecutionPolicy Bypass -File launch-and-position.ps1
方案3:修改JS/CSS适配IE(不推荐)
如果必须依赖IE,你的代码存在多处兼容性问题,修改如下:
兼容版JavaScript
// 兼容IE的DOM加载完成事件 function domReady(callback) { if (document.readyState === "complete" || document.readyState === "interactive") { setTimeout(callback, 1); } else { if (document.addEventListener) { document.addEventListener('DOMContentLoaded', callback); } else { document.attachEvent('onreadystatechange', callback); } } } domReady(function () { var selectedOption = null; var displays = { ALT: document.getElementById('alt-display'), HDG: document.getElementById('hdg-display'), VOR: document.getElementById('vor-display'), SPD: document.getElementById('spd-display') }; // 兼容IE的选择器 var elements = document.querySelectorAll ? document.querySelectorAll('.clickable') : document.getElementsByClassName('clickable'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; // 兼容IE的事件绑定 if (element.addEventListener) { element.addEventListener('click', handleClick); } else { element.attachEvent('onclick', handleClick); } function handleClick() { var value = this.getAttribute('data-value'); if (value === 'CLEAR') { if (selectedOption) { displays[selectedOption].innerText = '00000'; } } else if (value === 'ALT' || value === 'HDG' || value === 'VOR' || value === 'SPD') { selectedOption = value; } else if (selectedOption) { var currentValue = displays[selectedOption].innerText; var newValue = currentValue === '00000' ? value : currentValue + value; displays[selectedOption].innerText = newValue.slice(-5); } } } });
兼容版CSS(替换aspect-ratio)
body { display: flex; flex-direction: column; align-items: center; justify-content: center; background-color: black; color: green; font-family: 'Roboto Mono', Courier, monospace; height: 100vh; margin: 0; } .image-container { position: relative; width: 80%; max-width: 800px; margin: auto; } /* 用padding-top模拟aspect-ratio,IE不支持原生属性 */ .image-container::before { content: ''; display: block; padding-top: 100%; /* 实现1:1比例 */ } #interactiveImage { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .clickable { position: absolute; width: 25%; height: 25%; pointer-events: auto; } .clickable:hover { background-color: rgba(0, 255, 0, 0.3); cursor: pointer; } .display { position: absolute; width: 10%; text-align: center; font-size: 3vw; pointer-events: none; }
注意:IE已被微软停止支持,即使修改后也可能存在其他兼容性问题,不建议采用此方案。
原始代码
HTML文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>LAD Touchscreen Demo</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="image-container"> <img src="image.png" alt="Interactive Image" id="interactiveImage"> <div class="overlay"> <div class="clickable" data-value="1" style="top: 0%; left: 0%;"></div> <div class="clickable" data-value="2" style="top: 0%; left: 25%;"></div> <div class="clickable" data-value="3" style="top: 0%; left: 50%;"></div> <div class="clickable" data-value="4" style="top: 25%; left: 0%;"></div> <div class="clickable" data-value="5" style="top: 25%; left: 25%;"></div> <div class="clickable" data-value="6" style="top: 25%; left: 50%;"></div> <div class="clickable" data-value="7" style="top: 50%; left: 0%;"></div> <div class="clickable" data-value="8" style="top: 50%; left: 25%;"></div> <div class="clickable" data-value="9" style="top: 50%; left: 50%;"></div> <div class="clickable" data-value="0" style="top: 75%; left: 25%;"></div> <div class="clickable" data-value="CLEAR" style="top: 75%; left: 0%;"></div> <div class="clickable" data-value="ALT" style="top: 0%; left: 75%;"></div> <div class="clickable" data-value="HDG" style="top: 25%; left: 75%;"></div> <div class="clickable" data-value="VOR" style="top: 50%; left: 75%;"></div> <div class="clickable" data-value="SPD" style="top: 75%; left: 75%;"></div> <div id="alt-display" class="display" style="top: 10%; left: 75%;">00000</div> <div id="hdg-display" class="display" style="top: 35%; left: 75%;">00000</div> <div id="vor-display" class="display" style="top: 60%; left: 75%;">00000</div> <div id="spd-display" class="display" style="top: 85%; left: 75%;">00000</div> </div> </div> <script src="script.js"></script> </body> </html>
CSS文件
body { display: flex; flex-direction: column; align-items: center; justify-content: center; background-color: black; color: green; font-family: 'Roboto Mono', Courier, monospace; height: 100vh; margin: 0; } .image-container { position: relative; width: 80%; max-width: 800px; aspect-ratio: 1 / 1; /* Adjust this ratio based on your image's aspect ratio */ margin: auto; } #interactiveImage { display: block; width: 100%; height: 100%; object-fit: cover; } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .clickable { position: absolute; width: 25%; height: 25%; pointer-events: auto; } .clickable:hover { background-color: rgba(0, 255, 0, 0.3); cursor: pointer; } .display { position: absolute; width: 10%; text-align: center; font-size: 3vw; pointer-events: none; }
JavaScript文件
document.addEventListener('DOMContentLoaded', function () { var selectedOption = null; var displays = { ALT: document.getElementById('alt-display'), HDG: document.getElementById('hdg-display'), VOR: document.getElementById('vor-display'), SPD: document.getElementById('spd-display') }; var elements = document.querySelectorAll('.clickable'); for (var i = 0; i < elements.length; i++) { elements[i].addEventListener('click', (function (element) { return function () { var value = element.getAttribute('data-value'); if (value === 'CLEAR') { if (selectedOption) { displays[selectedOption].innerText = '00000'; } } else if (value === 'ALT' || value === 'HDG' || value === 'VOR' || value === 'SPD') { selectedOption = value; } else if (selectedOption) { var currentValue = displays[selectedOption].innerText; var newValue = currentValue === '00000' ? value : currentValue + value; displays[selectedOption].innerText = newValue.slice(-5); // keep only the last 5 digits } }; })(elements[i])); } });
批处理文件
@echo off for /f "tokens=1,2" %%a in ('powershell -ExecutionPolicy Bypass -File get_resolution.ps1') do ( set SCREEN_WIDTH=%%a set SCREEN_HEIGHT=%%b ) set /a WINDOW_WIDTH=%SCREEN_WIDTH% / 2 set /a WINDOW_HEIGHT=%SCREEN_HEIGHT% / 2 set POS_X=0 set POS_Y=0 echo Set IE = CreateObject("InternetExplorer.Application") > set_window.vbs echo IE.Visible = True >> set_window.vbs echo IE.Navigate "index.html" >> set_window.vbs echo WScript.Sleep 2000 >> set_window.vbs echo IE.Left = %POS_X% >> set_window.vbs echo IE.Top = %POS_Y% >> set_window.vbs echo IE.Width = %WINDOW_WIDTH% >> set_window.vbs echo IE.Height = %WINDOW_HEIGHT% >> set_window.vbs cscript set_window.vbs del set_window.vbs
内容的提问来源于stack exchange,提问作者chalrac
相关产品推荐
相关产品推荐

