Я строю пользовательский виджет чата в JavaScript (аналогично мессенджеру на странице). Виджет прикрепляет как фиксированную панель с липким заголовком, прокручиваемым потоком сообщений и композитором внизу.
Проблема возникает на мобильном телефоне, когда клавиатура открывается:
on Android Chrome:
Paneling Shroinks, когда клавиша opens opens. Pers. Pr/Pr/Prinks Paneling. Страница становится видимой за панелью.
Если адресная полоска анимирует (верхняя/внизу), высота панели прыгает. Animate.
Иногда композитор перебирает или недооценивает клавиатуру.
Что я попробовал
100 В, 100dvh, 100svh → панель по -прежнему сжимается на клавиатуре. Запасная сторона: < /p>
const vv = window.visualViewport;
const large = vv.height + (vv.offsetTop || 0);
panel.style.setProperty('--lvh', (large/100) + 'px');
Прокрутка страницы блокировки, когда виджет, открыт. /> На сафари для iOS заголовок иногда перестает быть липкой, а панель все еще дрожит. /> должен работать как на Android Chrome (Address Bar Top/снизу), так и в iOS Safari (новые и старые версии).
Вопрос
Какой самый надежный рисунок (CSS + JS), чтобы сохранить фиксированную ширину чата:
Полная высота. /> с липким заголовком и нижним композитором, которые правильно приспосабливаются, < /p>
как на Android Chrome, так и на Safari IOS, < /p>
, не полагаясь на ua-sniff chacks?
OAT Clinic
css
Copy code
:root {
/* Large viewport height (JS sets this var) */
--lvh: 1vh;
/* Keyboard overlap (JS sets this var) */
--kb: 0px;
}
/* Fullscreen panel that should NOT shrink when keyboard opens */
.panel {
position: fixed;
inset: 0;
height: calc(var(--lvh) * 100); /* prefer LVH when available */
display: flex;
flex-direction: column;
background: #f7f8fb;
overflow: hidden;
}
.head {
position: sticky;
top: 0;
z-index: 1;
padding: 9px 13px;
background: white;
border-bottom: 1px solid #e5e7eb;
}
.stream {
flex: 1 1 auto;
min-height: 0; /* critical for mobile scrolling */
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.composer {
position: sticky; /* stays at bottom of panel */
bottom: 0;
border-top: 1px solid #e5e7eb;
background: #f7f8fb;
/* Lift above keyboard (JS sets --kb) */
transform: translateY(calc(-1 * var(--kb)));
}
textarea {
width: 100%;
min-height: 54px;
max-height: 120px;
border: 1px solid #E1E1E1;
border-radius: 12px;
margin: 8px;
padding: 8px 10px;
resize: none;
}
js
Copy code
// Robust LVH + keyboard offset calculation
(function () {
const panel = document.getElementById('panel');
const composer = document.getElementById('composer');
const msg = document.getElementById('msg');
// Use Large Viewport Height when supported; JS fallback otherwise.
function setLVH() {
const vv = window.visualViewport;
const large = vv ? (vv.height + (vv.offsetTop || 0)) : window.innerHeight;
// Extra fallback using physical screen size for iOS quirks
const alt = (window.screen && window.screen.height && window.devicePixelRatio)
? (window.screen.height / window.devicePixelRatio)
: large;
const lvh = Math.max(large, alt) / 100; // 1% unit
panel.style.setProperty('--lvh', lvh + 'px');
}
let baseVVH = null; // visible height baseline (without keyboard)
function setBaseVVH() {
const vv = window.visualViewport;
baseVVH = vv ? vv.height : window.innerHeight;
}
function computeKeyboardOffset() {
const vv = window.visualViewport;
let kb = 0;
if (vv) {
// How much of the window is occluded by the keyboard / chrome
const occluded = Math.max(0, Math.round(window.innerHeight - vv.height - (vv.offsetTop || 0)));
// Is the composer currently below the visible bottom?
const visBottom = vv.height + (vv.offsetTop || 0);
const compBottom = composer.getBoundingClientRect().bottom;
const overlap = Math.max(0, Math.round(compBottom - visBottom));
// Visible height delta vs baseline (helps with iOS “jiggle”)
const delta = Math.max(0, Math.round((baseVVH || vv.height) - vv.height));
kb = Math.max(occluded, overlap, delta);
}
// Thresholds to ignore small URL bar animations
const IS_IOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
const THRESH = IS_IOS ? 120 : 80;
if (kb < THRESH) kb = 0;
// Cap to prevent overshoot
const maxKb = Math.max(0, Math.round(panel.getBoundingClientRect().height - 56));
kb = Math.min(kb, maxKb);
panel.style.setProperty('--kb', kb + 'px');
}
function relayout() {
setLVH();
computeKeyboardOffset();
}
// Init
setBaseVVH();
setLVH();
// Recalculate on viewport changes (keyboard / URL bar animation)
if (window.visualViewport) {
let timer = null;
const onVV = () => {
clearTimeout(timer);
// Debounce to avoid rapid jiggle
timer = setTimeout(() => {
relayout();
}, 50);
};
visualViewport.addEventListener('resize', onVV);
visualViewport.addEventListener('scroll', onVV);
}
window.addEventListener('resize', relayout);
window.addEventListener('orientationchange', () => setTimeout(relayout, 250));
// Update baseline around focus/blur to track keyboard state changes
msg.addEventListener('focus', () => { setBaseVVH(); computeKeyboardOffset(); });
msg.addEventListener('blur', () => {
panel.style.setProperty('--kb', '0px');
setBaseVVH();
});
})();
Подробнее здесь: https://stackoverflow.com/questions/797 ... yboard-ope
Панель виджета мобильного чата сжимается, а заголовок/композитор Misaligns, когда открывается клавиатура (iOS Safari & A ⇐ Javascript
Форум по Javascript
1756559862
Anonymous
Я строю пользовательский виджет чата в JavaScript (аналогично мессенджеру на странице). Виджет прикрепляет как фиксированную панель с липким заголовком, прокручиваемым потоком сообщений и композитором внизу.
Проблема возникает на мобильном телефоне, когда клавиатура открывается:
[b] on Android Chrome: [/b]
Paneling Shroinks, когда клавиша opens opens. Pers. Pr/Pr/Prinks Paneling. Страница становится видимой за панелью.
Если адресная полоска анимирует (верхняя/внизу), высота панели прыгает. Animate.
Иногда композитор перебирает или недооценивает клавиатуру.
[b] Что я попробовал [/b]
100 В, 100dvh, 100svh → панель по -прежнему сжимается на клавиатуре. Запасная сторона: < /p>
const vv = window.visualViewport;
const large = vv.height + (vv.offsetTop || 0);
panel.style.setProperty('--lvh', (large/100) + 'px');
Прокрутка страницы блокировки, когда виджет, открыт. /> На сафари для iOS заголовок иногда перестает быть липкой, а панель все еще дрожит. /> должен работать как на Android Chrome (Address Bar Top/снизу), так и в iOS Safari (новые и старые версии).
[b] Вопрос [/b]
Какой самый надежный рисунок (CSS + JS), чтобы сохранить фиксированную ширину чата:
Полная высота. /> с липким заголовком и нижним композитором, которые правильно приспосабливаются, < /p>
как на Android Chrome, так и на Safari IOS, < /p>
, не полагаясь на ua-sniff chacks?
OAT Clinic
css
Copy code
:root {
/* Large viewport height (JS sets this var) */
--lvh: 1vh;
/* Keyboard overlap (JS sets this var) */
--kb: 0px;
}
/* Fullscreen panel that should NOT shrink when keyboard opens */
.panel {
position: fixed;
inset: 0;
height: calc(var(--lvh) * 100); /* prefer LVH when available */
display: flex;
flex-direction: column;
background: #f7f8fb;
overflow: hidden;
}
.head {
position: sticky;
top: 0;
z-index: 1;
padding: 9px 13px;
background: white;
border-bottom: 1px solid #e5e7eb;
}
.stream {
flex: 1 1 auto;
min-height: 0; /* critical for mobile scrolling */
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.composer {
position: sticky; /* stays at bottom of panel */
bottom: 0;
border-top: 1px solid #e5e7eb;
background: #f7f8fb;
/* Lift above keyboard (JS sets --kb) */
transform: translateY(calc(-1 * var(--kb)));
}
textarea {
width: 100%;
min-height: 54px;
max-height: 120px;
border: 1px solid #E1E1E1;
border-radius: 12px;
margin: 8px;
padding: 8px 10px;
resize: none;
}
js
Copy code
// Robust LVH + keyboard offset calculation
(function () {
const panel = document.getElementById('panel');
const composer = document.getElementById('composer');
const msg = document.getElementById('msg');
// Use Large Viewport Height when supported; JS fallback otherwise.
function setLVH() {
const vv = window.visualViewport;
const large = vv ? (vv.height + (vv.offsetTop || 0)) : window.innerHeight;
// Extra fallback using physical screen size for iOS quirks
const alt = (window.screen && window.screen.height && window.devicePixelRatio)
? (window.screen.height / window.devicePixelRatio)
: large;
const lvh = Math.max(large, alt) / 100; // 1% unit
panel.style.setProperty('--lvh', lvh + 'px');
}
let baseVVH = null; // visible height baseline (without keyboard)
function setBaseVVH() {
const vv = window.visualViewport;
baseVVH = vv ? vv.height : window.innerHeight;
}
function computeKeyboardOffset() {
const vv = window.visualViewport;
let kb = 0;
if (vv) {
// How much of the window is occluded by the keyboard / chrome
const occluded = Math.max(0, Math.round(window.innerHeight - vv.height - (vv.offsetTop || 0)));
// Is the composer currently below the visible bottom?
const visBottom = vv.height + (vv.offsetTop || 0);
const compBottom = composer.getBoundingClientRect().bottom;
const overlap = Math.max(0, Math.round(compBottom - visBottom));
// Visible height delta vs baseline (helps with iOS “jiggle”)
const delta = Math.max(0, Math.round((baseVVH || vv.height) - vv.height));
kb = Math.max(occluded, overlap, delta);
}
// Thresholds to ignore small URL bar animations
const IS_IOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
const THRESH = IS_IOS ? 120 : 80;
if (kb < THRESH) kb = 0;
// Cap to prevent overshoot
const maxKb = Math.max(0, Math.round(panel.getBoundingClientRect().height - 56));
kb = Math.min(kb, maxKb);
panel.style.setProperty('--kb', kb + 'px');
}
function relayout() {
setLVH();
computeKeyboardOffset();
}
// Init
setBaseVVH();
setLVH();
// Recalculate on viewport changes (keyboard / URL bar animation)
if (window.visualViewport) {
let timer = null;
const onVV = () => {
clearTimeout(timer);
// Debounce to avoid rapid jiggle
timer = setTimeout(() => {
relayout();
}, 50);
};
visualViewport.addEventListener('resize', onVV);
visualViewport.addEventListener('scroll', onVV);
}
window.addEventListener('resize', relayout);
window.addEventListener('orientationchange', () => setTimeout(relayout, 250));
// Update baseline around focus/blur to track keyboard state changes
msg.addEventListener('focus', () => { setBaseVVH(); computeKeyboardOffset(); });
msg.addEventListener('blur', () => {
panel.style.setProperty('--kb', '0px');
setBaseVVH();
});
})();
Подробнее здесь: [url]https://stackoverflow.com/questions/79751159/mobile-chat-widget-panel-shrinks-and-header-composer-misaligns-when-keyboard-ope[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия