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 findHeader() {
- 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 adjustHeaderStyles(el) {
- 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 updateHeaderOnKeyboard() {
- 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 onFocusIn(event) {
- function onFocusOut(event) {
- window.requestAnimationFrame(() => {
- if (header) header.style.transform = '';
- });
- window.requestAnimationFrame(() => {
- }
- function onFocusOut(event) {
- function init() {
- header = findHeader();
- if (!header) {
- console.warn('UserScript header element (.row) not found.');
- return;
- }
- adjustHeaderStyles(header);
- function init() {
- 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));
- }
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
- })();