[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fteam-documents\u002F03":3,"knowledge-related-\u002Fknowledge\u002Fteam-documents\u002F03":2157,"knowledge-series-\u002Fknowledge\u002Fteam-documents\u002F03":2183},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":17,"pinned":18,"draft":18,"body":19,"seo":2153,"stem":2154,"id":2155,"extension":2156},"\u002Fknowledge\u002Fteam-documents\u002F03","键盘弹起导致底部被顶起问题（H5 适配）","在移动端 H5 页面中，当用户聚焦 input、textarea 等可编辑元素、软键盘弹出时，常见表现包括：","团队文档",[12,13,14,15,16],"team","vue","mobile","payment","geo","2024-09-17",false,{"type":20,"value":21,"toc":2136},"minimark",[22,26,30,47,63,66,69,73,84,125,136,140,200,203,206,291,294,297,301,304,361,364,366,377,386,857,863,869,883,885,889,903,1224,1246,1248,1252,1824,1826,1830,1837,1869,1876,1878,1881,1968,1970,1973,2027,2029,2032,2133],[23,24,8],"h1",{"id":25},"键盘弹起导致底部被顶起问题h5-适配",[27,28,29],"h2",{"id":29},"问题现象",[31,32,33,34,38,39,42,43,46],"p",{},"在移动端 ",[35,36,37],"code",{},"H5"," 页面中，当用户聚焦 ",[35,40,41],{},"input","、",[35,44,45],{},"textarea"," 等可编辑元素、软键盘弹出时，常见表现包括：",[48,49,50,54,57,60],"ul",{},[51,52,53],"li",{},"底部固定按钮或操作栏被整体上推，甚至挤到视口中部；",[51,55,56],{},"页面出现大面积空白或布局错位；",[51,58,59],{},"输入框被键盘遮挡，用户需要手动滚动才能看到光标；",[51,61,62],{},"键盘收起后，底部区域位置未恢复，出现“半截按钮”或闪烁。",[31,64,65],{},"上述问题会直接影响表单提交、支付确认等关键路径，需要在设计与实现阶段单独考虑兼容。",[27,67,68],{"id":68},"成因说明",[70,71,72],"h3",{"id":72},"布局视口与视觉视口",[31,74,75,76,83],{},"移动端页面存在两个相关但不同的概念（参见 ",[77,78,82],"a",{"href":79,"rel":80},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FVisual_Viewport_API",[81],"nofollow","MDN：Visual Viewport API","）：",[85,86,87,100],"table",{},[88,89,90],"thead",{},[91,92,93,97],"tr",{},[94,95,96],"th",{},"概念",[94,98,99],{},"说明",[101,102,103,115],"tbody",{},[91,104,105,112],{},[106,107,108],"td",{},[109,110,111],"strong",{},"布局视口（Layout Viewport）",[106,113,114],{},"页面文档的布局范围，通常不因软键盘弹出而改变整体高度",[91,116,117,122],{},[106,118,119],{},[109,120,121],{},"视觉视口（Visual Viewport）",[106,123,124],{},"用户当前在屏幕上实际可见的区域",[31,126,127,128,131,132,135],{},"软键盘、系统 UI 等会",[109,129,130],{},"缩小视觉视口","，而布局视口往往保持不变。若底部栏使用 ",[35,133,134],{},"position: fixed"," 且相对于布局视口定位，在键盘弹出时就容易出现“被顶上去”或“与键盘重叠”的错觉。",[70,137,139],{"id":138},"平台差异经验归纳","平台差异（经验归纳）",[85,141,142,152],{},[88,143,144],{},[91,145,146,149],{},[94,147,148],{},"环境",[94,150,151],{},"常见表现",[101,153,154,168,190],{},[91,155,156,161],{},[106,157,158],{},[109,159,160],{},"iOS Safari \u002F WKWebView",[106,162,163,164,167],{},"常会滚动页面以保证输入框可见；部分场景下 ",[35,165,166],{},"fixed"," 元素表现相对稳定，但仍可能出现地址栏收起\u002F展开带来的高度抖动",[91,169,170,175],{},[106,171,172],{},[109,173,174],{},"Android Chrome \u002F 系统 WebView",[106,176,177,178,181,182,185,186,189],{},"键盘弹出时 ",[35,179,180],{},"window.innerHeight"," 或 ",[35,183,184],{},"visualViewport.height"," 变化更明显，",[35,187,188],{},"resize"," 更易触发",[91,191,192,197],{},[106,193,194],{},[109,195,196],{},"混合 App 内嵌 WebView",[106,198,199],{},"是否调整 WebView 高度、是否全屏等由原生容器决定，行为差异大，需与客户端联调",[31,201,202],{},"因此不能依赖单一平台的“默认行为”，而应在目标机型上做真机验证。",[27,204,205],{"id":205},"解决思路概览",[85,207,208,220],{},[88,209,210],{},[91,211,212,215,218],{},[94,213,214],{},"思路",[94,216,217],{},"适用场景",[94,219,99],{},[101,221,222,242,255,278],{},[91,223,224,229,232],{},[106,225,226],{},[109,227,228],{},"调整布局",[106,230,231],{},"可改稿、非强依赖底部悬浮",[106,233,234,235,237,238,241],{},"少用或慎用底部 ",[35,236,166],{},"，用文档流 + ",[35,239,240],{},"padding-bottom"," 预留空间",[91,243,244,249,252],{},[106,245,246],{},[109,247,248],{},"侦测高度变化，控制底部显隐",[106,250,251],{},"必须保留底部操作栏",[106,253,254],{},"键盘弹出时隐藏底部栏，收起后恢复（实现简单，兼容面广）",[91,256,257,262,265],{},[106,258,259],{},[109,260,261],{},"Visual Viewport API",[106,263,264],{},"现代浏览器、需更精确判断",[106,266,267,268,271,272,274,275,277],{},"监听 ",[35,269,270],{},"window.visualViewport"," 的 ",[35,273,188],{},"，比单纯 ",[35,276,180],{}," 更贴近“可见区域”",[91,279,280,285,288],{},[106,281,282],{},[109,283,284],{},"原生键盘事件（Hybrid）",[106,286,287],{},"App 内 H5",[106,289,290],{},"由客户端监听键盘显隐，通过 JSBridge 通知 Web 层，稳定性最好",[31,292,293],{},"以下分方案给出示例与注意点。",[295,296],"hr",{},[27,298,300],{"id":299},"方案一布局层面规避","方案一：布局层面规避",[31,302,303],{},"在不影响产品视觉的前提下，可优先尝试：",[305,306,307,324,345],"ol",{},[51,308,309,312,315,316,319,320,323],{},[109,310,311],{},"底部操作区放入文档流",[313,314],"br",{},"\n使用 ",[35,317,318],{},"position: static"," \u002F ",[35,321,322],{},"relative","，避免与键盘争抢“固定层”。",[51,325,326,329,331,332,335,336,344],{},[109,327,328],{},"为页面底部预留内边距",[313,330],{},"\n例如 ",[35,333,334],{},"padding-bottom: env(safe-area-inset-bottom, 0px)","，兼顾刘海屏与 Home 指示条（参见 ",[77,337,340,341],{"href":338,"rel":339},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Fenv",[81],"MDN：",[35,342,343],{},"env()","）。",[51,346,347,350,352,353,356,357,360],{},[109,348,349],{},"输入框聚焦时滚动到可视区域",[313,351],{},"\n在 ",[35,354,355],{},"focus"," 时对当前输入元素调用 ",[35,358,359],{},"element.scrollIntoView({ block: 'center', behavior: 'smooth' })","，减轻遮挡（注意 iOS 上可能与系统自带滚动叠加）。",[31,362,363],{},"该方案对“必须全局悬浮提交按钮”的设计约束较大，常与方案二、三组合使用。",[295,365],{},[27,367,369,370,372,373,376],{"id":368},"方案二监听-resize-innerheight通用兜底","方案二：监听 ",[35,371,188],{}," + ",[35,374,375],{},"innerHeight","（通用兜底）",[31,378,379,382,383,385],{},[109,380,381],{},"原理","：键盘弹出后，许多环境下 ",[35,384,180],{}," 会明显变小；与进入页面时记录的高度对比，超过阈值则视为键盘已打开。",[387,388,393],"pre",{"className":389,"code":390,"language":391,"meta":392,"style":392},"language-javascript shiki shiki-themes material-theme-lighter github-light github-dark","\u002F**\n * 根据视口高度变化切换底部栏显隐\n * @param {HTMLElement | null} bottomEl 底部容器\n * @param {number} threshold 高度差阈值（px），建议 50–120，需真机调优\n * @returns {() => void} 卸载函数，SPA 路由离开时必须调用\n *\u002F\nfunction bindKeyboardBottomToggle(bottomEl, threshold = 50) {\n  if (!bottomEl) return () => {};\n\n  const baseHeight = window.innerHeight;\n\n  const onResize = () => {\n    const current = window.innerHeight;\n    const keyboardLikelyOpen = baseHeight - current > threshold;\n    bottomEl.style.display = keyboardLikelyOpen ? \"none\" : \"\";\n  };\n\n  window.addEventListener(\"resize\", onResize);\n  return () => window.removeEventListener(\"resize\", onResize);\n}\n\n\u002F\u002F 使用示例\nconst bottom = document.getElementById(\"bottom\");\nconst unbind = bindKeyboardBottomToggle(bottom, 80);\n\n\u002F\u002F 页面销毁 \u002F 路由离开时\n\u002F\u002F unbind();\n","javascript","",[35,394,395,404,410,442,464,484,490,528,559,566,589,594,611,630,654,696,702,707,734,767,773,778,784,816,840,845,851],{"__ignoreMap":392},[396,397,400],"span",{"class":398,"line":399},"line",1,[396,401,403],{"class":402},"sutJx","\u002F**\n",[396,405,407],{"class":398,"line":406},2,[396,408,409],{"class":402}," * 根据视口高度变化切换底部栏显隐\n",[396,411,413,416,420,424,428,432,435,439],{"class":398,"line":412},3,[396,414,415],{"class":402}," * ",[396,417,419],{"class":418},"sVHd0","@",[396,421,423],{"class":422},"sN_3T","param",[396,425,427],{"class":426},"spbfU"," {",[396,429,431],{"class":430},"svk34","HTMLElement | null",[396,433,434],{"class":426},"}",[396,436,438],{"class":437},"sFwrP"," bottomEl",[396,440,441],{"class":402}," 底部容器\n",[396,443,445,447,449,451,453,456,458,461],{"class":398,"line":444},4,[396,446,415],{"class":402},[396,448,419],{"class":418},[396,450,423],{"class":422},[396,452,427],{"class":426},[396,454,455],{"class":430},"number",[396,457,434],{"class":426},[396,459,460],{"class":437}," threshold",[396,462,463],{"class":402}," 高度差阈值（px），建议 50–120，需真机调优\n",[396,465,467,469,471,474,476,479,481],{"class":398,"line":466},5,[396,468,415],{"class":402},[396,470,419],{"class":418},[396,472,473],{"class":422},"returns",[396,475,427],{"class":426},[396,477,478],{"class":430},"() => void",[396,480,434],{"class":426},[396,482,483],{"class":402}," 卸载函数，SPA 路由离开时必须调用\n",[396,485,487],{"class":398,"line":486},6,[396,488,489],{"class":402}," *\u002F\n",[396,491,493,497,501,505,509,512,514,518,522,525],{"class":398,"line":492},7,[396,494,496],{"class":495},"sbsja","function",[396,498,500],{"class":499},"sGLFI"," bindKeyboardBottomToggle",[396,502,504],{"class":503},"sP7_E","(",[396,506,508],{"class":507},"s99_P","bottomEl",[396,510,511],{"class":503},",",[396,513,460],{"class":507},[396,515,517],{"class":516},"smGrS"," =",[396,519,521],{"class":520},"srdBf"," 50",[396,523,524],{"class":503},")",[396,526,527],{"class":503}," {\n",[396,529,531,534,538,541,544,547,550,553,556],{"class":398,"line":530},8,[396,532,533],{"class":418},"  if",[396,535,537],{"class":536},"skxfh"," (",[396,539,540],{"class":516},"!",[396,542,508],{"class":543},"su5hD",[396,545,546],{"class":536},") ",[396,548,549],{"class":418},"return",[396,551,552],{"class":503}," ()",[396,554,555],{"class":495}," =>",[396,557,558],{"class":503}," {};\n",[396,560,562],{"class":398,"line":561},9,[396,563,565],{"emptyLinePlaceholder":564},true,"\n",[396,567,569,572,576,578,581,584,586],{"class":398,"line":568},10,[396,570,571],{"class":495},"  const",[396,573,575],{"class":574},"s_hVV"," baseHeight",[396,577,517],{"class":516},[396,579,580],{"class":543}," window",[396,582,583],{"class":503},".",[396,585,375],{"class":543},[396,587,588],{"class":503},";\n",[396,590,592],{"class":398,"line":591},11,[396,593,565],{"emptyLinePlaceholder":564},[396,595,597,599,603,605,607,609],{"class":398,"line":596},12,[396,598,571],{"class":495},[396,600,602],{"class":601},"sfCm-"," onResize",[396,604,517],{"class":516},[396,606,552],{"class":503},[396,608,555],{"class":495},[396,610,527],{"class":503},[396,612,614,617,620,622,624,626,628],{"class":398,"line":613},13,[396,615,616],{"class":495},"    const",[396,618,619],{"class":574}," current",[396,621,517],{"class":516},[396,623,580],{"class":543},[396,625,583],{"class":503},[396,627,375],{"class":543},[396,629,588],{"class":503},[396,631,633,635,638,640,642,645,647,650,652],{"class":398,"line":632},14,[396,634,616],{"class":495},[396,636,637],{"class":574}," keyboardLikelyOpen",[396,639,517],{"class":516},[396,641,575],{"class":543},[396,643,644],{"class":516}," -",[396,646,619],{"class":543},[396,648,649],{"class":516}," >",[396,651,460],{"class":543},[396,653,588],{"class":503},[396,655,657,660,662,665,667,670,672,674,677,681,685,688,691,694],{"class":398,"line":656},15,[396,658,659],{"class":543},"    bottomEl",[396,661,583],{"class":503},[396,663,664],{"class":543},"style",[396,666,583],{"class":503},[396,668,669],{"class":543},"display",[396,671,517],{"class":516},[396,673,637],{"class":543},[396,675,676],{"class":516}," ?",[396,678,680],{"class":679},"sjJ54"," \"",[396,682,684],{"class":683},"s_sjI","none",[396,686,687],{"class":679},"\"",[396,689,690],{"class":516}," :",[396,692,693],{"class":679}," \"\"",[396,695,588],{"class":503},[396,697,699],{"class":398,"line":698},16,[396,700,701],{"class":503},"  };\n",[396,703,705],{"class":398,"line":704},17,[396,706,565],{"emptyLinePlaceholder":564},[396,708,710,713,715,718,720,722,724,726,728,730,732],{"class":398,"line":709},18,[396,711,712],{"class":543},"  window",[396,714,583],{"class":503},[396,716,717],{"class":499},"addEventListener",[396,719,504],{"class":536},[396,721,687],{"class":679},[396,723,188],{"class":683},[396,725,687],{"class":679},[396,727,511],{"class":503},[396,729,602],{"class":543},[396,731,524],{"class":536},[396,733,588],{"class":503},[396,735,737,740,742,744,746,748,751,753,755,757,759,761,763,765],{"class":398,"line":736},19,[396,738,739],{"class":418},"  return",[396,741,552],{"class":503},[396,743,555],{"class":495},[396,745,580],{"class":543},[396,747,583],{"class":503},[396,749,750],{"class":499},"removeEventListener",[396,752,504],{"class":536},[396,754,687],{"class":679},[396,756,188],{"class":683},[396,758,687],{"class":679},[396,760,511],{"class":503},[396,762,602],{"class":543},[396,764,524],{"class":536},[396,766,588],{"class":503},[396,768,770],{"class":398,"line":769},20,[396,771,772],{"class":503},"}\n",[396,774,776],{"class":398,"line":775},21,[396,777,565],{"emptyLinePlaceholder":564},[396,779,781],{"class":398,"line":780},22,[396,782,783],{"class":402},"\u002F\u002F 使用示例\n",[396,785,787,790,793,795,798,800,803,805,807,810,812,814],{"class":398,"line":786},23,[396,788,789],{"class":495},"const",[396,791,792],{"class":574}," bottom",[396,794,517],{"class":516},[396,796,797],{"class":543}," document",[396,799,583],{"class":503},[396,801,802],{"class":499},"getElementById",[396,804,504],{"class":543},[396,806,687],{"class":679},[396,808,809],{"class":683},"bottom",[396,811,687],{"class":679},[396,813,524],{"class":543},[396,815,588],{"class":503},[396,817,819,821,824,826,828,831,833,836,838],{"class":398,"line":818},24,[396,820,789],{"class":495},[396,822,823],{"class":574}," unbind",[396,825,517],{"class":516},[396,827,500],{"class":499},[396,829,830],{"class":543},"(bottom",[396,832,511],{"class":503},[396,834,835],{"class":520}," 80",[396,837,524],{"class":543},[396,839,588],{"class":503},[396,841,843],{"class":398,"line":842},25,[396,844,565],{"emptyLinePlaceholder":564},[396,846,848],{"class":398,"line":847},26,[396,849,850],{"class":402},"\u002F\u002F 页面销毁 \u002F 路由离开时\n",[396,852,854],{"class":398,"line":853},27,[396,855,856],{"class":402},"\u002F\u002F unbind();\n",[31,858,859,862],{},[109,860,861],{},"效果","：键盘弹起时隐藏底部栏，收起后恢复，避免固定栏被顶到中间或压在键盘上。",[31,864,865,868],{},[109,866,867],{},"局限","：",[48,870,871,877],{},[51,872,873,874,876],{},"横竖屏切换、地址栏显隐也会改变 ",[35,875,375],{},"，可能误判；",[51,878,879,880,882],{},"部分 iOS 版本键盘弹出时 ",[35,881,375],{}," 变化较小，需降低阈值或改用方案三。",[295,884],{},[27,886,888],{"id":887},"方案三visual-viewport-api推荐","方案三：Visual Viewport API（推荐）",[31,890,891,896,897,899,900,902],{},[77,892,895],{"href":893,"rel":894},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FVisualViewport",[81],"Visual Viewport"," 直接描述“用户当前可见区域”，软键盘弹出时 ",[35,898,184],{}," 通常会减小，比单独依赖 ",[35,901,180],{}," 更贴近键盘场景（Baseline 兼容性已较广，详见 MDN 兼容性表）。",[387,904,906],{"className":389,"code":905,"language":391,"meta":392,"style":392},"function bindVisualViewportBottomToggle(bottomEl, threshold = 50) {\n  if (!bottomEl || !window.visualViewport) {\n    return bindKeyboardBottomToggle(bottomEl, threshold);\n  }\n\n  const vv = window.visualViewport;\n  const baseHeight = vv.height;\n\n  const update = () => {\n    const keyboardLikelyOpen = baseHeight - vv.height > threshold;\n    bottomEl.style.display = keyboardLikelyOpen ? \"none\" : \"\";\n  };\n\n  vv.addEventListener(\"resize\", update);\n  vv.addEventListener(\"scroll\", update);\n\n  return () => {\n    vv.removeEventListener(\"resize\", update);\n    vv.removeEventListener(\"scroll\", update);\n  };\n}\n",[35,907,908,931,960,979,984,988,1005,1022,1026,1041,1065,1095,1099,1103,1128,1153,1157,1167,1192,1216,1220],{"__ignoreMap":392},[396,909,910,912,915,917,919,921,923,925,927,929],{"class":398,"line":399},[396,911,496],{"class":495},[396,913,914],{"class":499}," bindVisualViewportBottomToggle",[396,916,504],{"class":503},[396,918,508],{"class":507},[396,920,511],{"class":503},[396,922,460],{"class":507},[396,924,517],{"class":516},[396,926,521],{"class":520},[396,928,524],{"class":503},[396,930,527],{"class":503},[396,932,933,935,937,939,941,944,947,950,952,955,957],{"class":398,"line":406},[396,934,533],{"class":418},[396,936,537],{"class":536},[396,938,540],{"class":516},[396,940,508],{"class":543},[396,942,943],{"class":516}," ||",[396,945,946],{"class":516}," !",[396,948,949],{"class":543},"window",[396,951,583],{"class":503},[396,953,954],{"class":543},"visualViewport",[396,956,546],{"class":536},[396,958,959],{"class":503},"{\n",[396,961,962,965,967,969,971,973,975,977],{"class":398,"line":412},[396,963,964],{"class":418},"    return",[396,966,500],{"class":499},[396,968,504],{"class":536},[396,970,508],{"class":543},[396,972,511],{"class":503},[396,974,460],{"class":543},[396,976,524],{"class":536},[396,978,588],{"class":503},[396,980,981],{"class":398,"line":444},[396,982,983],{"class":503},"  }\n",[396,985,986],{"class":398,"line":466},[396,987,565],{"emptyLinePlaceholder":564},[396,989,990,992,995,997,999,1001,1003],{"class":398,"line":486},[396,991,571],{"class":495},[396,993,994],{"class":574}," vv",[396,996,517],{"class":516},[396,998,580],{"class":543},[396,1000,583],{"class":503},[396,1002,954],{"class":543},[396,1004,588],{"class":503},[396,1006,1007,1009,1011,1013,1015,1017,1020],{"class":398,"line":492},[396,1008,571],{"class":495},[396,1010,575],{"class":574},[396,1012,517],{"class":516},[396,1014,994],{"class":543},[396,1016,583],{"class":503},[396,1018,1019],{"class":543},"height",[396,1021,588],{"class":503},[396,1023,1024],{"class":398,"line":530},[396,1025,565],{"emptyLinePlaceholder":564},[396,1027,1028,1030,1033,1035,1037,1039],{"class":398,"line":561},[396,1029,571],{"class":495},[396,1031,1032],{"class":601}," update",[396,1034,517],{"class":516},[396,1036,552],{"class":503},[396,1038,555],{"class":495},[396,1040,527],{"class":503},[396,1042,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1063],{"class":398,"line":568},[396,1044,616],{"class":495},[396,1046,637],{"class":574},[396,1048,517],{"class":516},[396,1050,575],{"class":543},[396,1052,644],{"class":516},[396,1054,994],{"class":543},[396,1056,583],{"class":503},[396,1058,1019],{"class":543},[396,1060,649],{"class":516},[396,1062,460],{"class":543},[396,1064,588],{"class":503},[396,1066,1067,1069,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091,1093],{"class":398,"line":591},[396,1068,659],{"class":543},[396,1070,583],{"class":503},[396,1072,664],{"class":543},[396,1074,583],{"class":503},[396,1076,669],{"class":543},[396,1078,517],{"class":516},[396,1080,637],{"class":543},[396,1082,676],{"class":516},[396,1084,680],{"class":679},[396,1086,684],{"class":683},[396,1088,687],{"class":679},[396,1090,690],{"class":516},[396,1092,693],{"class":679},[396,1094,588],{"class":503},[396,1096,1097],{"class":398,"line":596},[396,1098,701],{"class":503},[396,1100,1101],{"class":398,"line":613},[396,1102,565],{"emptyLinePlaceholder":564},[396,1104,1105,1108,1110,1112,1114,1116,1118,1120,1122,1124,1126],{"class":398,"line":632},[396,1106,1107],{"class":543},"  vv",[396,1109,583],{"class":503},[396,1111,717],{"class":499},[396,1113,504],{"class":536},[396,1115,687],{"class":679},[396,1117,188],{"class":683},[396,1119,687],{"class":679},[396,1121,511],{"class":503},[396,1123,1032],{"class":543},[396,1125,524],{"class":536},[396,1127,588],{"class":503},[396,1129,1130,1132,1134,1136,1138,1140,1143,1145,1147,1149,1151],{"class":398,"line":656},[396,1131,1107],{"class":543},[396,1133,583],{"class":503},[396,1135,717],{"class":499},[396,1137,504],{"class":536},[396,1139,687],{"class":679},[396,1141,1142],{"class":683},"scroll",[396,1144,687],{"class":679},[396,1146,511],{"class":503},[396,1148,1032],{"class":543},[396,1150,524],{"class":536},[396,1152,588],{"class":503},[396,1154,1155],{"class":398,"line":698},[396,1156,565],{"emptyLinePlaceholder":564},[396,1158,1159,1161,1163,1165],{"class":398,"line":704},[396,1160,739],{"class":418},[396,1162,552],{"class":503},[396,1164,555],{"class":495},[396,1166,527],{"class":503},[396,1168,1169,1172,1174,1176,1178,1180,1182,1184,1186,1188,1190],{"class":398,"line":709},[396,1170,1171],{"class":543},"    vv",[396,1173,583],{"class":503},[396,1175,750],{"class":499},[396,1177,504],{"class":536},[396,1179,687],{"class":679},[396,1181,188],{"class":683},[396,1183,687],{"class":679},[396,1185,511],{"class":503},[396,1187,1032],{"class":543},[396,1189,524],{"class":536},[396,1191,588],{"class":503},[396,1193,1194,1196,1198,1200,1202,1204,1206,1208,1210,1212,1214],{"class":398,"line":736},[396,1195,1171],{"class":543},[396,1197,583],{"class":503},[396,1199,750],{"class":499},[396,1201,504],{"class":536},[396,1203,687],{"class":679},[396,1205,1142],{"class":683},[396,1207,687],{"class":679},[396,1209,511],{"class":503},[396,1211,1032],{"class":543},[396,1213,524],{"class":536},[396,1215,588],{"class":503},[396,1217,1218],{"class":398,"line":769},[396,1219,701],{"class":503},[396,1221,1222],{"class":398,"line":775},[396,1223,772],{"class":503},[31,1225,1226,1227,1230,1231,42,1234,1236,1237,1240,1241,1245],{},"若需底部栏",[109,1228,1229],{},"始终贴在当前可见区域底部","（类似“贴在键盘上方”），可结合 ",[35,1232,1233],{},"visualViewport.offsetTop",[35,1235,184],{}," 用 ",[35,1238,1239],{},"transform"," 动态定位；实现成本更高，且快速滚动时可能出现轻微闪烁，需权衡（MDN 示例见 ",[77,1242,1244],{"href":79,"rel":1243},[81],"Visual Viewport 文档"," 中的 “Simulating position: device-fixed”）。",[295,1247],{},[27,1249,1251],{"id":1250},"方案四vue-3-组合式封装示例","方案四：Vue 3 组合式封装示例",[387,1253,1256],{"className":1254,"code":1255,"language":13,"meta":392,"style":392},"language-vue shiki shiki-themes material-theme-lighter github-light github-dark","\u003Cscript setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from \"vue\";\n\nconst showBottomBar = ref(true);\nlet unbind: (() => void) | undefined;\n\nonMounted(() => {\n  const bottom = document.getElementById(\"bottom\");\n  if (!bottom) return;\n\n  const vv = window.visualViewport;\n  const base = vv?.height ?? window.innerHeight;\n  const threshold = 80;\n\n  const update = () => {\n    const h = vv?.height ?? window.innerHeight;\n    showBottomBar.value = base - h \u003C= threshold;\n  };\n\n  if (vv) {\n    vv.addEventListener(\"resize\", update);\n    unbind = () => vv.removeEventListener(\"resize\", update);\n  } else {\n    window.addEventListener(\"resize\", update);\n    unbind = () => window.removeEventListener(\"resize\", update);\n  }\n});\n\nonUnmounted(() => unbind?.());\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv id=\"bottom\" v-show=\"showBottomBar\">提交\u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[35,1257,1258,1287,1321,1325,1346,1377,1381,1394,1420,1436,1440,1456,1483,1495,1499,1513,1538,1563,1567,1571,1584,1608,1641,1651,1676,1708,1712,1720,1725,1746,1756,1761,1771,1815],{"__ignoreMap":392},[396,1259,1260,1263,1267,1271,1274,1277,1279,1282,1284],{"class":398,"line":399},[396,1261,1262],{"class":503},"\u003C",[396,1264,1266],{"class":1265},"sQzsp","script",[396,1268,1270],{"class":1269},"s9AJx"," setup",[396,1272,1273],{"class":1269}," lang",[396,1275,1276],{"class":503},"=",[396,1278,687],{"class":679},[396,1280,1281],{"class":683},"ts",[396,1283,687],{"class":679},[396,1285,1286],{"class":503},">\n",[396,1288,1289,1292,1294,1297,1299,1302,1304,1307,1310,1313,1315,1317,1319],{"class":398,"line":406},[396,1290,1291],{"class":418},"import",[396,1293,427],{"class":503},[396,1295,1296],{"class":543}," onMounted",[396,1298,511],{"class":503},[396,1300,1301],{"class":543}," onUnmounted",[396,1303,511],{"class":503},[396,1305,1306],{"class":543}," ref",[396,1308,1309],{"class":503}," }",[396,1311,1312],{"class":418}," from",[396,1314,680],{"class":679},[396,1316,13],{"class":683},[396,1318,687],{"class":679},[396,1320,588],{"class":503},[396,1322,1323],{"class":398,"line":412},[396,1324,565],{"emptyLinePlaceholder":564},[396,1326,1327,1329,1332,1334,1336,1338,1342,1344],{"class":398,"line":444},[396,1328,789],{"class":495},[396,1330,1331],{"class":574}," showBottomBar",[396,1333,517],{"class":516},[396,1335,1306],{"class":499},[396,1337,504],{"class":543},[396,1339,1341],{"class":1340},"syTEX","true",[396,1343,524],{"class":543},[396,1345,588],{"class":503},[396,1347,1348,1351,1353,1356,1358,1361,1363,1367,1369,1372,1375],{"class":398,"line":466},[396,1349,1350],{"class":495},"let",[396,1352,823],{"class":543},[396,1354,1355],{"class":516},":",[396,1357,537],{"class":543},[396,1359,1360],{"class":503},"()",[396,1362,555],{"class":495},[396,1364,1366],{"class":1365},"sZMiF"," void",[396,1368,546],{"class":543},[396,1370,1371],{"class":516},"|",[396,1373,1374],{"class":1365}," undefined",[396,1376,588],{"class":503},[396,1378,1379],{"class":398,"line":486},[396,1380,565],{"emptyLinePlaceholder":564},[396,1382,1383,1386,1388,1390,1392],{"class":398,"line":492},[396,1384,1385],{"class":499},"onMounted",[396,1387,504],{"class":543},[396,1389,1360],{"class":503},[396,1391,555],{"class":495},[396,1393,527],{"class":503},[396,1395,1396,1398,1400,1402,1404,1406,1408,1410,1412,1414,1416,1418],{"class":398,"line":530},[396,1397,571],{"class":495},[396,1399,792],{"class":574},[396,1401,517],{"class":516},[396,1403,797],{"class":543},[396,1405,583],{"class":503},[396,1407,802],{"class":499},[396,1409,504],{"class":536},[396,1411,687],{"class":679},[396,1413,809],{"class":683},[396,1415,687],{"class":679},[396,1417,524],{"class":536},[396,1419,588],{"class":503},[396,1421,1422,1424,1426,1428,1430,1432,1434],{"class":398,"line":561},[396,1423,533],{"class":418},[396,1425,537],{"class":536},[396,1427,540],{"class":516},[396,1429,809],{"class":543},[396,1431,546],{"class":536},[396,1433,549],{"class":418},[396,1435,588],{"class":503},[396,1437,1438],{"class":398,"line":568},[396,1439,565],{"emptyLinePlaceholder":564},[396,1441,1442,1444,1446,1448,1450,1452,1454],{"class":398,"line":591},[396,1443,571],{"class":495},[396,1445,994],{"class":574},[396,1447,517],{"class":516},[396,1449,580],{"class":543},[396,1451,583],{"class":503},[396,1453,954],{"class":543},[396,1455,588],{"class":503},[396,1457,1458,1460,1463,1465,1467,1470,1472,1475,1477,1479,1481],{"class":398,"line":596},[396,1459,571],{"class":495},[396,1461,1462],{"class":574}," base",[396,1464,517],{"class":516},[396,1466,994],{"class":543},[396,1468,1469],{"class":503},"?.",[396,1471,1019],{"class":543},[396,1473,1474],{"class":516}," ??",[396,1476,580],{"class":543},[396,1478,583],{"class":503},[396,1480,375],{"class":543},[396,1482,588],{"class":503},[396,1484,1485,1487,1489,1491,1493],{"class":398,"line":613},[396,1486,571],{"class":495},[396,1488,460],{"class":574},[396,1490,517],{"class":516},[396,1492,835],{"class":520},[396,1494,588],{"class":503},[396,1496,1497],{"class":398,"line":632},[396,1498,565],{"emptyLinePlaceholder":564},[396,1500,1501,1503,1505,1507,1509,1511],{"class":398,"line":656},[396,1502,571],{"class":495},[396,1504,1032],{"class":601},[396,1506,517],{"class":516},[396,1508,552],{"class":503},[396,1510,555],{"class":495},[396,1512,527],{"class":503},[396,1514,1515,1517,1520,1522,1524,1526,1528,1530,1532,1534,1536],{"class":398,"line":698},[396,1516,616],{"class":495},[396,1518,1519],{"class":574}," h",[396,1521,517],{"class":516},[396,1523,994],{"class":543},[396,1525,1469],{"class":503},[396,1527,1019],{"class":543},[396,1529,1474],{"class":516},[396,1531,580],{"class":543},[396,1533,583],{"class":503},[396,1535,375],{"class":543},[396,1537,588],{"class":503},[396,1539,1540,1543,1545,1548,1550,1552,1554,1556,1559,1561],{"class":398,"line":704},[396,1541,1542],{"class":543},"    showBottomBar",[396,1544,583],{"class":503},[396,1546,1547],{"class":543},"value",[396,1549,517],{"class":516},[396,1551,1462],{"class":543},[396,1553,644],{"class":516},[396,1555,1519],{"class":543},[396,1557,1558],{"class":516}," \u003C=",[396,1560,460],{"class":543},[396,1562,588],{"class":503},[396,1564,1565],{"class":398,"line":709},[396,1566,701],{"class":503},[396,1568,1569],{"class":398,"line":736},[396,1570,565],{"emptyLinePlaceholder":564},[396,1572,1573,1575,1577,1580,1582],{"class":398,"line":769},[396,1574,533],{"class":418},[396,1576,537],{"class":536},[396,1578,1579],{"class":543},"vv",[396,1581,546],{"class":536},[396,1583,959],{"class":503},[396,1585,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606],{"class":398,"line":775},[396,1587,1171],{"class":543},[396,1589,583],{"class":503},[396,1591,717],{"class":499},[396,1593,504],{"class":536},[396,1595,687],{"class":679},[396,1597,188],{"class":683},[396,1599,687],{"class":679},[396,1601,511],{"class":503},[396,1603,1032],{"class":543},[396,1605,524],{"class":536},[396,1607,588],{"class":503},[396,1609,1610,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639],{"class":398,"line":780},[396,1611,1612],{"class":499},"    unbind",[396,1614,517],{"class":516},[396,1616,552],{"class":503},[396,1618,555],{"class":495},[396,1620,994],{"class":543},[396,1622,583],{"class":503},[396,1624,750],{"class":499},[396,1626,504],{"class":536},[396,1628,687],{"class":679},[396,1630,188],{"class":683},[396,1632,687],{"class":679},[396,1634,511],{"class":503},[396,1636,1032],{"class":543},[396,1638,524],{"class":536},[396,1640,588],{"class":503},[396,1642,1643,1646,1649],{"class":398,"line":786},[396,1644,1645],{"class":503},"  }",[396,1647,1648],{"class":418}," else",[396,1650,527],{"class":503},[396,1652,1653,1656,1658,1660,1662,1664,1666,1668,1670,1672,1674],{"class":398,"line":818},[396,1654,1655],{"class":543},"    window",[396,1657,583],{"class":503},[396,1659,717],{"class":499},[396,1661,504],{"class":536},[396,1663,687],{"class":679},[396,1665,188],{"class":683},[396,1667,687],{"class":679},[396,1669,511],{"class":503},[396,1671,1032],{"class":543},[396,1673,524],{"class":536},[396,1675,588],{"class":503},[396,1677,1678,1680,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700,1702,1704,1706],{"class":398,"line":842},[396,1679,1612],{"class":499},[396,1681,517],{"class":516},[396,1683,552],{"class":503},[396,1685,555],{"class":495},[396,1687,580],{"class":543},[396,1689,583],{"class":503},[396,1691,750],{"class":499},[396,1693,504],{"class":536},[396,1695,687],{"class":679},[396,1697,188],{"class":683},[396,1699,687],{"class":679},[396,1701,511],{"class":503},[396,1703,1032],{"class":543},[396,1705,524],{"class":536},[396,1707,588],{"class":503},[396,1709,1710],{"class":398,"line":847},[396,1711,983],{"class":503},[396,1713,1714,1716,1718],{"class":398,"line":853},[396,1715,434],{"class":503},[396,1717,524],{"class":543},[396,1719,588],{"class":503},[396,1721,1723],{"class":398,"line":1722},28,[396,1724,565],{"emptyLinePlaceholder":564},[396,1726,1728,1731,1733,1735,1737,1739,1741,1744],{"class":398,"line":1727},29,[396,1729,1730],{"class":499},"onUnmounted",[396,1732,504],{"class":543},[396,1734,1360],{"class":503},[396,1736,555],{"class":495},[396,1738,823],{"class":499},[396,1740,1469],{"class":503},[396,1742,1743],{"class":543},"())",[396,1745,588],{"class":503},[396,1747,1749,1752,1754],{"class":398,"line":1748},30,[396,1750,1751],{"class":503},"\u003C\u002F",[396,1753,1266],{"class":1265},[396,1755,1286],{"class":503},[396,1757,1759],{"class":398,"line":1758},31,[396,1760,565],{"emptyLinePlaceholder":564},[396,1762,1764,1766,1769],{"class":398,"line":1763},32,[396,1765,1262],{"class":503},[396,1767,1768],{"class":1265},"template",[396,1770,1286],{"class":503},[396,1772,1774,1777,1780,1783,1785,1787,1789,1791,1794,1796,1798,1801,1803,1806,1809,1811,1813],{"class":398,"line":1773},33,[396,1775,1776],{"class":503},"  \u003C",[396,1778,1779],{"class":1265},"div",[396,1781,1782],{"class":1269}," id",[396,1784,1276],{"class":503},[396,1786,687],{"class":679},[396,1788,809],{"class":683},[396,1790,687],{"class":679},[396,1792,1793],{"class":1269}," v-show",[396,1795,1276],{"class":503},[396,1797,687],{"class":679},[396,1799,1800],{"class":683},"showBottomBar",[396,1802,687],{"class":679},[396,1804,1805],{"class":503},">",[396,1807,1808],{"class":543},"提交",[396,1810,1751],{"class":503},[396,1812,1779],{"class":1265},[396,1814,1286],{"class":503},[396,1816,1818,1820,1822],{"class":398,"line":1817},34,[396,1819,1751],{"class":503},[396,1821,1768],{"class":1265},[396,1823,1286],{"class":503},[295,1825],{},[27,1827,1829],{"id":1828},"方案五混合-appwebview场景","方案五：混合 App（WebView）场景",[31,1831,1832,1833,1836],{},"在 React Native、Flutter 或原生 ",[35,1834,1835],{},"WebView"," 容器中，建议：",[305,1838,1839,1853,1860],{},[51,1840,1841,1842,1845,1846,319,1849,1852],{},"由客户端监听键盘显示\u002F隐藏（如 Android ",[35,1843,1844],{},"WindowInsets","、iOS ",[35,1847,1848],{},"keyboardWillShow",[35,1850,1851],{},"keyboardWillHide","）；",[51,1854,1855,1856,1859],{},"通过 JSBridge 向 H5 发送 ",[35,1857,1858],{},"{ type: 'keyboard', visible: boolean, height?: number }","；",[51,1861,1862,1863,1865,1866,1868],{},"H5 根据事件切换底部栏显隐或调整 ",[35,1864,240],{},"，避免依赖浏览器 ",[35,1867,188],{}," 的不一致行为。",[31,1870,1871,1872,1875],{},"该方式在目标 App 内通常",[109,1873,1874],{},"最稳定","，但需要客户端配合。",[295,1877],{},[27,1879,1880],{"id":1880},"实践注意点",[305,1882,1883,1891,1906,1923,1935,1960],{},[51,1884,1885,1888,1890],{},[109,1886,1887],{},"阈值需真机调优",[313,1889],{},"\n50px 仅为经验起点；全面屏、横屏、外接键盘等场景建议各测一轮，常用范围约 80–150px。",[51,1892,1893,1896,1898,1899,1901,1902,1905],{},[109,1894,1895],{},"对监听做节流",[313,1897],{},"\n键盘动画过程中 ",[35,1900,188],{}," 可能连续触发，可用 ",[35,1903,1904],{},"requestAnimationFrame"," 合并更新，或使用节流（如 100ms），减少 DOM 读写。",[51,1907,1908,1911,315,1913,1916,1917,319,1920,1922],{},[109,1909,1910],{},"SPA 必须卸载监听",[313,1912],{},[35,1914,1915],{},"keep-alive"," 时，在 ",[35,1918,1919],{},"onDeactivated",[35,1921,1730],{}," 中移除监听，防止重复绑定与内存泄漏。",[51,1924,1925,1932,1934],{},[109,1926,1927,1928,1931],{},"避免用 ",[35,1929,1930],{},"display: none"," 打断焦点",[313,1933],{},"\n若底部栏内也有可聚焦元素，隐藏前确认当前焦点在输入框上，避免可访问性与焦点陷阱问题。",[51,1936,1937,1944,1946,1947,1949,1950,1953,1954,1959],{},[109,1938,1939,1940,1943],{},"不要与 ",[35,1941,1942],{},"100vh"," 死磕",[313,1945],{},"\n移动端 ",[35,1948,1942],{}," 常包含地址栏等区域，键盘场景下易算错高度；可优先考虑 ",[35,1951,1952],{},"100dvh","（动态视口，参见 ",[77,1955,1958],{"href":1956,"rel":1957},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Flength#viewport-percentage_lengths",[81],"MDN：viewport 长度单位","）或 JS 动态计算。",[51,1961,1962,1965,1967],{},[109,1963,1964],{},"上线前测试矩阵",[313,1966],{},"\n至少覆盖：iOS Safari、Android Chrome、微信内置浏览器、目标 App WebView；各测“首个输入框聚焦”“切换输入框”“旋转屏幕”“键盘收起”四条路径。",[295,1969],{},[27,1971,1972],{"id":1972},"小结",[85,1974,1975,1985],{},[88,1976,1977],{},[91,1978,1979,1982],{},[94,1980,1981],{},"优先级",[94,1983,1984],{},"建议",[101,1986,1987,1998,2012,2019],{},[91,1988,1989,1992],{},[106,1990,1991],{},"设计阶段",[106,1993,1994,1995,1997],{},"能不用底部全局 ",[35,1996,166],{}," 则尽量不用",[91,1999,2000,2003],{},[106,2001,2002],{},"纯 H5",[106,2004,2005,2007,2008,372,2010],{},[35,2006,954],{}," + 显隐切换；不支持时回退 ",[35,2009,375],{},[35,2011,188],{},[91,2013,2014,2016],{},[106,2015,287],{},[106,2017,2018],{},"优先 JSBridge + 原生键盘事件",[91,2020,2021,2024],{},[106,2022,2023],{},"所有方案",[106,2025,2026],{},"真机验证 + 路由卸载监听",[295,2028],{},[27,2030,2031],{"id":2031},"参考文献",[85,2033,2034,2044],{},[88,2035,2036],{},[91,2037,2038,2041],{},[94,2039,2040],{},"资料",[94,2042,2043],{},"链接",[101,2045,2046,2055,2068,2084,2095,2108,2122],{},[91,2047,2048,2050],{},[106,2049,82],{},[106,2051,2052],{},[77,2053,79],{"href":79,"rel":2054},[81],[91,2056,2057,2062],{},[106,2058,340,2059],{},[35,2060,2061],{},"Window.innerHeight",[106,2063,2064],{},[77,2065,2066],{"href":2066,"rel":2067},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002FinnerHeight",[81],[91,2069,2070,2078],{},[106,2071,340,2072,868,2075,2077],{},[35,2073,2074],{},"Window",[35,2076,188],{}," 事件",[106,2079,2080],{},[77,2081,2082],{"href":2082,"rel":2083},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002Fresize_event",[81],[91,2085,2086,2089],{},[106,2087,2088],{},"MDN：视口（Viewport）术语",[106,2090,2091],{},[77,2092,2093],{"href":2093,"rel":2094},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FGlossary\u002FViewport",[81],[91,2096,2097,2103],{},[106,2098,2099,2100,2102],{},"MDN：CSS ",[35,2101,343],{}," 与安全区域",[106,2104,2105],{},[77,2106,338],{"href":338,"rel":2107},[81],[91,2109,2110,2117],{},[106,2111,2112,2113,2116],{},"MDN：视口百分比长度单位（含 ",[35,2114,2115],{},"dvh","）",[106,2118,2119],{},[77,2120,1956],{"href":1956,"rel":2121},[81],[91,2123,2124,2127],{},[106,2125,2126],{},"web.dev：Understanding layout and paint",[106,2128,2129],{},[77,2130,2131],{"href":2131,"rel":2132},"https:\u002F\u002Fweb.dev\u002Farticles\u002Funderstand-the-critical-path",[81],[664,2134,2135],{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sN_3T, html code.shiki .sN_3T{--shiki-light:#9C3EDA;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .spbfU, html code.shiki .spbfU{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#6F42C1;--shiki-default-font-style:inherit;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit}html pre.shiki code .svk34, html code.shiki .svk34{--shiki-light:#E2931D;--shiki-light-font-style:italic;--shiki-default:#6F42C1;--shiki-default-font-style:inherit;--shiki-dark:#B392F0;--shiki-dark-font-style:inherit}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sfCm-, html code.shiki .sfCm-{--shiki-light:#90A4AE;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s9AJx, html code.shiki .s9AJx{--shiki-light:#9C3EDA;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":392,"searchDepth":406,"depth":406,"links":2137},[2138,2139,2143,2144,2145,2147,2148,2149,2150,2151,2152],{"id":29,"depth":406,"text":29},{"id":68,"depth":406,"text":68,"children":2140},[2141,2142],{"id":72,"depth":412,"text":72},{"id":138,"depth":412,"text":139},{"id":205,"depth":406,"text":205},{"id":299,"depth":406,"text":300},{"id":368,"depth":406,"text":2146},"方案二：监听 resize + innerHeight（通用兜底）",{"id":887,"depth":406,"text":888},{"id":1250,"depth":406,"text":1251},{"id":1828,"depth":406,"text":1829},{"id":1880,"depth":406,"text":1880},{"id":1972,"depth":406,"text":1972},{"id":2031,"depth":406,"text":2031},{"title":8,"description":9},"knowledge\u002Fteam-documents\u002F03","knowledge\u002Fknowledge\u002Fteam-documents\u002F03.md","md",{"items":2158},[2159,2163,2167,2171,2175,2179],{"path":2160,"title":2161,"description":2162,"category":10,"score":656},"\u002Fknowledge\u002Fteam-documents\u002F17","支付中转页面升级实践","本次需求是支付链路升级：在兼容原有支付能力的基础上，新增不同版本的支付方案（如原生微信支付、小程序拉起支付）。",{"path":2164,"title":2165,"description":2166,"category":10,"score":596},"\u002Fknowledge\u002Fteam-documents\u002F19","GridView 宫格加载渲染优化","系统首页 GridView 宫格模块接口耗时不高，但首次进入总耗时接近 22s。复盘耗时分层定位过程、代码层面的瓶颈（约 2000 行、100 个 tab 重复节点）、优化手段与最终指标对比。",{"path":2168,"title":2169,"description":2170,"category":10,"score":596},"\u002Fknowledge\u002Fteam-documents\u002F04","老系统升级与兼容改造实践","公司原有业务系统采用 Node + jQuery 架构，长期运行后暴露出典型遗留系统问题：",{"path":2172,"title":2173,"description":2174,"category":10,"score":596},"\u002Fknowledge\u002Fteam-documents\u002F02","防篡改水印","在各类管理后台、SaaS 平台或内部系统中，页面水印已经是非常常见的能力：一方面在截图时携带账号、姓名、时间等信息，降低截图外传的风险；另一方面在上传图片或文档预览时，通过水印标记上传者与时间，满足审计和合规需求。",{"path":2176,"title":2177,"description":2178,"category":10,"score":596},"\u002Fknowledge\u002Fteam-documents\u002F20","H5 GPS 定位问题说明","对比普通浏览器 Geolocation、微信 wx.getLocation、第三方地图定位服务三条 H5 定位路径的适用场景、权限与 HTTPS 要求、常见错误码，并给出选型建议。",{"path":2180,"title":2181,"description":2182,"category":10,"score":596},"\u002Fknowledge\u002Fteam-documents\u002F22","企业微信 uni-app H5：OAuth 回退白屏与列表缓存","第三方 BI 报表项目，企业微信内嵌 H5，uni-app 编译，history 模式。主页面 BiLink 同时承担静默授权和列表展示，上线后碰到两个问题：授权完清掉 URL 参数，iOS 侧滑返回还是白屏；列表加了缓存以后，刷新行…",{"series":2184,"title":2185,"items":2186,"index":406,"prev":2260,"next":2261},"team-documents","team documents",[2187,2191,2193,2194,2196,2200,2204,2208,2212,2216,2220,2224,2228,2232,2236,2240,2244,2246,2250,2252,2254,2258],{"path":2188,"title":2189,"date":2190,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F01","执行价格弹窗：表头 \u002F 表体合并与可配置表格","2024-07-27",{"path":2172,"title":2173,"date":2192,"pinned":18},"2024-01-09",{"path":7,"title":8,"date":17,"pinned":18},{"path":2168,"title":2169,"date":2195,"pinned":18},"2024-12-12",{"path":2197,"title":2198,"date":2199,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F05","内部插件 \u002F 工具库开发实践","2021-08-19",{"path":2201,"title":2202,"date":2203,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F06","企业微信与小程序工单问题","2025-10-01",{"path":2205,"title":2206,"date":2207,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F07","企业微信群工具打开缓慢原因分析","2020-04-12",{"path":2209,"title":2210,"date":2211,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F08","属性排序需求","2024-06-16",{"path":2213,"title":2214,"date":2215,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F09","同业主重复单提醒规则","2020-06-07",{"path":2217,"title":2218,"date":2219,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F10","图片上传前的自定义水印实践","2021-06-10",{"path":2221,"title":2222,"date":2223,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F11","系统下单（重复单提示框）异常复盘","2023-11-21",{"path":2225,"title":2226,"date":2227,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F12","系统自动更新说明","2025-05-26",{"path":2229,"title":2230,"date":2231,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F13","新商家系统性能优化实践","2025-04-08",{"path":2233,"title":2234,"date":2235,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F14","选项卡切换与 Loading 状态封装","2019-11-03",{"path":2237,"title":2238,"date":2239,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F15","移动端返回事件触发两次问题复盘","2021-03-09",{"path":2241,"title":2242,"date":2243,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F16","在线协作表格接入实践","2023-10-27",{"path":2160,"title":2161,"date":2245,"pinned":18},"2022-10-15",{"path":2247,"title":2248,"date":2249,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F18","中英文输入法下搜索触发冲突复盘","2024-09-01",{"path":2164,"title":2165,"date":2251,"pinned":18},"2026-03-17",{"path":2176,"title":2177,"date":2253,"pinned":18},"2023-08-31",{"path":2255,"title":2256,"date":2257,"pinned":18},"\u002Fknowledge\u002Fteam-documents\u002F21","vxe-table 行 Hover 联动高亮","2024-08-31",{"path":2180,"title":2181,"date":2259,"pinned":18},"2023-08-17",{"path":2172,"title":2173,"date":2192,"pinned":18},{"path":2168,"title":2169,"date":2195,"pinned":18}]