update at 2026-03-03 16:58:41

This commit is contained in:
douboer@gmail.com
2026-03-03 16:58:41 +08:00
parent 79656bace2
commit e3cb56714c
3 changed files with 52 additions and 5 deletions

View File

@@ -20,6 +20,8 @@ body {
.xterm { .xterm {
.xterm-viewport { .xterm-viewport {
overflow-y: hidden; overscroll-behavior-y: contain !important;
-webkit-overflow-scrolling: touch !important;
will-change: transform, scroll-position;
} }
} }

View File

@@ -8,7 +8,7 @@ import { disconnect } from './wetty/disconnect';
import { overlay } from './wetty/disconnect/elements'; import { overlay } from './wetty/disconnect/elements';
import { verifyPrompt } from './wetty/disconnect/verify'; import { verifyPrompt } from './wetty/disconnect/verify';
import { FileDownloader } from './wetty/download'; import { FileDownloader } from './wetty/download';
import { mobileKeyboard } from './wetty/mobile'; import { mobileKeyboard, initMobileViewport } from './wetty/mobile';
import { socket } from './wetty/socket'; import { socket } from './wetty/socket';
import { terminal, Term } from './wetty/term'; import { terminal, Term } from './wetty/term';
@@ -33,6 +33,7 @@ if (_.isUndefined(term)) {
term.resizeTerm(); term.resizeTerm();
term.focus(); term.focus();
mobileKeyboard(); mobileKeyboard();
initMobileViewport(term);
const fileDownloader = new FileDownloader(); const fileDownloader = new FileDownloader();
socket socket

View File

@@ -8,7 +8,51 @@ export function mobileKeyboard(): void {
screen.setAttribute('autocorrect', 'false'); screen.setAttribute('autocorrect', 'false');
screen.setAttribute('autocomplete', 'false'); screen.setAttribute('autocomplete', 'false');
screen.setAttribute('autocapitalize', 'false'); screen.setAttribute('autocapitalize', 'false');
/* }
term.scrollPort_.screen_.setAttribute('contenteditable', 'false');
*/ export function initMobileViewport(term: any): void {
// Safari/iOS 上阻止页面随着键盘弹出连带回弹上卷
document.body.style.position = 'fixed';
document.body.style.width = '100%';
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
// 劫持容器,阻止橡皮筋翻页穿透
document.addEventListener('touchmove', (e) => {
if (!(e.target as Element).closest('.xterm-viewport')) {
e.preventDefault();
}
}, { passive: false });
if (window.visualViewport) {
const handleResize = () => {
// 计算键盘弹起遮挡区域(针对不同平台浏览器处理)
let bottomInset = 0;
if (window.visualViewport) {
bottomInset = Math.max(
0,
window.innerHeight - (window.visualViewport.height + window.visualViewport.offsetTop)
);
}
const termWrapper = document.getElementById('terminal'); // 或获取最近的包装器
if (termWrapper) {
if (bottomInset > 0) {
termWrapper.style.paddingBottom = `${bottomInset}px`;
} else {
termWrapper.style.paddingBottom = '0px';
}
}
// 调整完包裹层高度后,通知 xterm 重新按新的可用高度进行行列计算
setTimeout(() => {
if (term && term.fitAddon) {
term.fitAddon.fit();
}
}, 50);
};
window.visualViewport.addEventListener('resize', handleResize);
window.visualViewport.addEventListener('scroll', handleResize);
}
} }