iPhoneアプリのporterでヘッダーを上部に固定する
Cosenseを扱うブラウザがSafari以外ならヘッダー位置を調整する。なのでおそらくSafari以外のブラウザを使うと変な挙動になると思われる。
code:script.js
// ====== Choiyaki 用 Cosense UserScript(header: .row + Safari判定) ======
(() => {
'use strict';
// Safari純正ブラウザかどうか判定
function isSafari() {
const ua = navigator.userAgent;
return /Safari/.test(ua) && /Version\//.test(ua);
}
// Safariなら何もしない
if (isSafari()) {
console.log('UserScript Safari detected → 補正スクリプト無効化'); return;
}
const headerSelector = '.navbar'; // ヘッダー要素のクラス
let header = null;
function findHeader() {
if (!document.body) return null;
return document.querySelector(headerSelector);
}
function adjustHeaderStyles(el) {
el.style.position = 'fixed';
el.style.top = '0';
el.style.left = '0';
el.style.right = '0';
el.style.zIndex = '10000';
el.style.transition = 'transform 150ms ease-out';
}
function updateHeaderOnKeyboard() {
const vv = window.visualViewport;
if (!vv) {
header.style.transform = '';
return;
}
const offsetTop = vv.offsetTop || 0;
const translateY = Math.max(0, offsetTop);
header.style.transform = translateY(${translateY}px);
}
function onFocusIn(event) {
const t = event.target;
if (!t) return;
const tag = t.tagName;
const isInput = (tag === 'INPUT' || tag === 'TEXTAREA' || t.isContentEditable === true);
if (!isInput) return;
window.requestAnimationFrame(updateHeaderOnKeyboard);
}
function onFocusOut(event) {
window.requestAnimationFrame(() => {
if (header) header.style.transform = '';
});
}
function init() {
header = findHeader();
if (!header) {
console.warn('UserScript header element (.row) not found.'); return;
}
adjustHeaderStyles(header);
if (window.visualViewport) {
window.visualViewport.addEventListener('resize', updateHeaderOnKeyboard, { passive: true });
window.visualViewport.addEventListener('scroll', updateHeaderOnKeyboard, { passive: true });
} else {
window.addEventListener('resize', updateHeaderOnKeyboard, { passive: true });
}
document.addEventListener('focusin', onFocusIn, true);
document.addEventListener('focusout', onFocusOut, true);
}
if (document.readyState === 'complete' || document.readyState === 'interactive') {
setTimeout(init, 50);
} else {
document.addEventListener('DOMContentLoaded', () => setTimeout(init, 50));
}
})();