You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写代码将HTML文档显示窗口调整至屏幕右上角并占1/4区域

问题描述

我正在开发一个带HTML文档展示的演示程序,需要把显示该HTML的窗口固定在屏幕右上角,占四分之一屏幕区域。试过用批处理调用IE、WinForms,但都依赖IE,我的HTML文件在IE里无法正常运行;也试过写批处理调整Edge/Chrome窗口大小,同样失败。怀疑是JavaScript不兼容IE,而且因为安全限制不能使用AutoHotKey和浏览器扩展。想问有没有可行方案?要不要修改JS适配IE,或者其他解决办法?

可行解决方案

方案1:用Electron打包成独立桌面窗口(推荐)

Electron可以将HTML/CSS/JS打包成原生桌面应用,完全脱离IE依赖,还能精准控制窗口的位置和尺寸:

  1. 安装Node.js,然后在项目目录执行初始化命令:
    npm init -y
    
  2. 安装Electron依赖:
    npm install electron --save-dev
    
  3. 创建主入口文件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();
    });
    
  4. 修改package.json的启动脚本:
    "scripts": {
      "start": "electron .",
      "package": "electron-packager . LADDemo --platform=win32 --arch=x64"
    }
    
  5. 测试运行: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:38:11