diagnosis.html 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1">
  6. <title>BetterScroll 的“疑难杂症” | BetterScroll 2.0</title>
  7. <meta name="generator" content="VuePress 1.9.10">
  8. <link rel="shortcut icon" href="/docs/assets/bs.ico" type="images/x-icon">
  9. <script src="https://www.googletagmanager.com/gtag/js?id=G-7E85TW7P27"></script>
  10. <script type="text/javascript">
  11. window.dataLayer = window.dataLayer || [];
  12. function gtag(){dataLayer.push(arguments);}
  13. gtag('js', new Date());
  14. gtag('config', 'G-7E85TW7P27');
  15. </script>
  16. <meta name="description" content="Make Scroll Perfect">
  17. <link rel="preload" href="/docs/assets/css/0.styles.0cd93813.css" as="style"><link rel="preload" href="/docs/assets/js/app.c71b64d3.js" as="script"><link rel="preload" href="/docs/assets/js/5.d6412664.js" as="script"><link rel="preload" href="/docs/assets/js/4.4855b9ef.js" as="script"><link rel="preload" href="/docs/assets/js/3.481632b4.js" as="script"><link rel="preload" href="/docs/assets/js/99.c75096e0.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.8644db92.js"><link rel="prefetch" href="/docs/assets/js/10.6f8c38eb.js"><link rel="prefetch" href="/docs/assets/js/100.ee08226e.js"><link rel="prefetch" href="/docs/assets/js/101.fd2f3d9f.js"><link rel="prefetch" href="/docs/assets/js/102.79d86e3d.js"><link rel="prefetch" href="/docs/assets/js/103.7a3ae3b5.js"><link rel="prefetch" href="/docs/assets/js/104.7be4589d.js"><link rel="prefetch" href="/docs/assets/js/105.75386d15.js"><link rel="prefetch" href="/docs/assets/js/106.a4a18e8d.js"><link rel="prefetch" href="/docs/assets/js/107.561ec2e2.js"><link rel="prefetch" href="/docs/assets/js/108.1c61689f.js"><link rel="prefetch" href="/docs/assets/js/109.da71a73e.js"><link rel="prefetch" href="/docs/assets/js/110.5e0fa2d1.js"><link rel="prefetch" href="/docs/assets/js/111.1e326dd1.js"><link rel="prefetch" href="/docs/assets/js/112.590ba317.js"><link rel="prefetch" href="/docs/assets/js/113.cf201ace.js"><link rel="prefetch" href="/docs/assets/js/114.6d895ce2.js"><link rel="prefetch" href="/docs/assets/js/115.572aee19.js"><link rel="prefetch" href="/docs/assets/js/116.754722a0.js"><link rel="prefetch" href="/docs/assets/js/117.15e4dab3.js"><link rel="prefetch" href="/docs/assets/js/118.721d68f8.js"><link rel="prefetch" href="/docs/assets/js/119.c5c28d96.js"><link rel="prefetch" href="/docs/assets/js/120.12cd2e0e.js"><link rel="prefetch" href="/docs/assets/js/121.e41f8100.js"><link rel="prefetch" href="/docs/assets/js/122.9ebe2f53.js"><link rel="prefetch" href="/docs/assets/js/123.f90c91f9.js"><link rel="prefetch" href="/docs/assets/js/13.b0c40cd7.js"><link rel="prefetch" href="/docs/assets/js/14.28bec126.js"><link rel="prefetch" href="/docs/assets/js/15.87b22af4.js"><link rel="prefetch" href="/docs/assets/js/16.c10e14e7.js"><link rel="prefetch" href="/docs/assets/js/17.5c921c77.js"><link rel="prefetch" href="/docs/assets/js/18.dc23b7e3.js"><link rel="prefetch" href="/docs/assets/js/19.a4034f95.js"><link rel="prefetch" href="/docs/assets/js/2.03f0f2c8.js"><link rel="prefetch" href="/docs/assets/js/20.8633fd45.js"><link rel="prefetch" href="/docs/assets/js/21.1fbf8d7e.js"><link rel="prefetch" href="/docs/assets/js/22.2888cfc5.js"><link rel="prefetch" href="/docs/assets/js/23.f951d302.js"><link rel="prefetch" href="/docs/assets/js/24.12842718.js"><link rel="prefetch" href="/docs/assets/js/25.5a5a3137.js"><link rel="prefetch" href="/docs/assets/js/26.88e81f0b.js"><link rel="prefetch" href="/docs/assets/js/27.152b8fda.js"><link rel="prefetch" href="/docs/assets/js/28.22550ea8.js"><link rel="prefetch" href="/docs/assets/js/29.f43fa807.js"><link rel="prefetch" href="/docs/assets/js/30.4ed38f67.js"><link rel="prefetch" href="/docs/assets/js/31.af4018f6.js"><link rel="prefetch" href="/docs/assets/js/32.930ee0b7.js"><link rel="prefetch" href="/docs/assets/js/33.c6a68c75.js"><link rel="prefetch" href="/docs/assets/js/34.6d10da1e.js"><link rel="prefetch" href="/docs/assets/js/35.11ba7b51.js"><link rel="prefetch" href="/docs/assets/js/36.8a54712b.js"><link rel="prefetch" href="/docs/assets/js/37.b26eb85d.js"><link rel="prefetch" href="/docs/assets/js/38.d6569a11.js"><link rel="prefetch" href="/docs/assets/js/39.1d22cfba.js"><link rel="prefetch" href="/docs/assets/js/40.577a94d7.js"><link rel="prefetch" href="/docs/assets/js/41.155e01e0.js"><link rel="prefetch" href="/docs/assets/js/42.3c26eaba.js"><link rel="prefetch" href="/docs/assets/js/43.d90991e2.js"><link rel="prefetch" href="/docs/assets/js/44.5437344c.js"><link rel="prefetch" href="/docs/assets/js/45.0d2eca0a.js"><link rel="prefetch" href="/docs/assets/js/46.11455b40.js"><link rel="prefetch" href="/docs/assets/js/47.1ee1a8f0.js"><link rel="prefetch" href="/docs/assets/js/48.c82450ab.js"><link rel="prefetch" href="/docs/assets/js/49.8016ee5f.js"><link rel="prefetch" href="/docs/assets/js/50.ab73e091.js"><link rel="prefetch" href="/docs/assets/js/51.bce6eb99.js"><link rel="prefetch" href="/docs/assets/js/52.c9b1992f.js"><link rel="prefetch" href="/docs/assets/js/53.7057f0f5.js"><link rel="prefetch" href="/docs/assets/js/54.cbb0a6b5.js"><link rel="prefetch" href="/docs/assets/js/55.89176a68.js"><link rel="prefetch" href="/docs/assets/js/56.cd04bae9.js"><link rel="prefetch" href="/docs/assets/js/57.c7a42e07.js"><link rel="prefetch" href="/docs/assets/js/58.09d6cb1b.js"><link rel="prefetch" href="/docs/assets/js/59.8445a09f.js"><link rel="prefetch" href="/docs/assets/js/6.5737c458.js"><link rel="prefetch" href="/docs/assets/js/60.86b1f417.js"><link rel="prefetch" href="/docs/assets/js/61.fa371ad1.js"><link rel="prefetch" href="/docs/assets/js/62.dbc75ddc.js"><link rel="prefetch" href="/docs/assets/js/63.a4465c93.js"><link rel="prefetch" href="/docs/assets/js/64.a39c3193.js"><link rel="prefetch" href="/docs/assets/js/65.a7275f82.js"><link rel="prefetch" href="/docs/assets/js/66.afd0af7d.js"><link rel="prefetch" href="/docs/assets/js/67.8009e00e.js"><link rel="prefetch" href="/docs/assets/js/68.de3c51dd.js"><link rel="prefetch" href="/docs/assets/js/69.41a50235.js"><link rel="prefetch" href="/docs/assets/js/7.518ccda7.js"><link rel="prefetch" href="/docs/assets/js/70.938e9532.js"><link rel="prefetch" href="/docs/assets/js/71.af7fca59.js"><link rel="prefetch" href="/docs/assets/js/72.25df569a.js"><link rel="prefetch" href="/docs/assets/js/73.f16b7dc3.js"><link rel="prefetch" href="/docs/assets/js/74.d2184ed7.js"><link rel="prefetch" href="/docs/assets/js/75.9497b6fa.js"><link rel="prefetch" href="/docs/assets/js/76.2081d35e.js"><link rel="prefetch" href="/docs/assets/js/77.e5a8b470.js"><link rel="prefetch" href="/docs/assets/js/78.6d3ef23b.js"><link rel="prefetch" href="/docs/assets/js/79.025583e1.js"><link rel="prefetch" href="/docs/assets/js/8.8547d4ad.js"><link rel="prefetch" href="/docs/assets/js/80.e7e3ef35.js"><link rel="prefetch" href="/docs/assets/js/81.569d569f.js"><link rel="prefetch" href="/docs/assets/js/82.ac3ed0f7.js"><link rel="prefetch" href="/docs/assets/js/83.3393dfc3.js"><link rel="prefetch" href="/docs/assets/js/84.e5352ac1.js"><link rel="prefetch" href="/docs/assets/js/85.c7cdb129.js"><link rel="prefetch" href="/docs/assets/js/86.0aa0af94.js"><link rel="prefetch" href="/docs/assets/js/87.0db12b1e.js"><link rel="prefetch" href="/docs/assets/js/88.e8651cfa.js"><link rel="prefetch" href="/docs/assets/js/89.1b58abde.js"><link rel="prefetch" href="/docs/assets/js/9.0a882dfc.js"><link rel="prefetch" href="/docs/assets/js/90.d65d2d13.js"><link rel="prefetch" href="/docs/assets/js/91.32b2ad41.js"><link rel="prefetch" href="/docs/assets/js/92.795675a1.js"><link rel="prefetch" href="/docs/assets/js/93.818e5569.js"><link rel="prefetch" href="/docs/assets/js/94.79c2b16e.js"><link rel="prefetch" href="/docs/assets/js/95.4810ee5e.js"><link rel="prefetch" href="/docs/assets/js/96.6e382fd5.js"><link rel="prefetch" href="/docs/assets/js/97.e270d7b5.js"><link rel="prefetch" href="/docs/assets/js/98.728ef6c2.js"><link rel="prefetch" href="/docs/assets/js/vendors~docsearch.2091e099.js">
  18. <link rel="stylesheet" href="/docs/assets/css/0.styles.0cd93813.css">
  19. </head>
  20. <body>
  21. <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/docs/zh-CN/" class="home-link router-link-active"><img src="https://dpubstatic.udache.com/static/dpubimg/t_L6vAgQ-E/logo.svg" alt="BetterScroll 2.0" class="logo"> <span class="site-name can-hide">BetterScroll 2.0</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"><div class="nav-item"><a href="/docs/zh-CN/guide/" class="nav-link">
  22. 指南
  23. </a></div><div class="nav-item"><a href="/docs/zh-CN/plugins/" class="nav-link">
  24. 插件
  25. </a></div><div class="nav-item"><a href="/docs/zh-CN/FAQ/" class="nav-link router-link-active">
  26. 常见问题
  27. </a></div><div class="nav-item"><a href="https://github.com/ustbhuangyi/better-scroll/issues" target="_blank" rel="noopener noreferrer" class="nav-link external">
  28. 讨论
  29. <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">选择语言</span> <span class="arrow down"></span></button> <button type="button" aria-label="Select language" class="mobile-dropdown-title"><span class="title">选择语言</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/docs/en-US/FAQ/diagnosis.html" class="nav-link">
  30. English
  31. </a></li><li class="dropdown-item"><!----> <a href="/docs/zh-CN/FAQ/diagnosis.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  32. 简体中文
  33. </a></li></ul></div></div> <a href="https://github.com/ustbhuangyi/better-scroll" target="_blank" rel="noopener noreferrer" class="repo-link">
  34. GitHub
  35. <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/docs/zh-CN/guide/" class="nav-link">
  36. 指南
  37. </a></div><div class="nav-item"><a href="/docs/zh-CN/plugins/" class="nav-link">
  38. 插件
  39. </a></div><div class="nav-item"><a href="/docs/zh-CN/FAQ/" class="nav-link router-link-active">
  40. 常见问题
  41. </a></div><div class="nav-item"><a href="https://github.com/ustbhuangyi/better-scroll/issues" target="_blank" rel="noopener noreferrer" class="nav-link external">
  42. 讨论
  43. <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">选择语言</span> <span class="arrow down"></span></button> <button type="button" aria-label="Select language" class="mobile-dropdown-title"><span class="title">选择语言</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/docs/en-US/FAQ/diagnosis.html" class="nav-link">
  44. English
  45. </a></li><li class="dropdown-item"><!----> <a href="/docs/zh-CN/FAQ/diagnosis.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  46. 简体中文
  47. </a></li></ul></div></div> <a href="https://github.com/ustbhuangyi/better-scroll" target="_blank" rel="noopener noreferrer" class="repo-link">
  48. GitHub
  49. <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>常见问题</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/docs/zh-CN/FAQ/" aria-current="page" class="sidebar-link">FAQ</a></li><li><a href="/docs/zh-CN/FAQ/diagnosis.html" aria-current="page" class="active sidebar-link">BetterScroll 的“疑难杂症”</a><ul class="sidebar-sub-headers"></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="betterscroll-的-疑难杂症"><a href="#betterscroll-的-疑难杂症" class="header-anchor">#</a> BetterScroll 的“疑难杂症”</h1> <h3 id="【问题一】为什么我的-betterscroll-滑动不了"><a href="#【问题一】为什么我的-betterscroll-滑动不了" class="header-anchor">#</a> 【问题一】为什么我的 BetterScroll 滑动不了?</h3> <p>问题基本上出在于<strong>高度的计算错误</strong>。首先,你必须对 <code>BetterScroll</code> 的滚动原理有一个清晰的认识,对于竖向滚动,简单的来说就是 <code>wrapper</code> 容器的高度大于 <code>content</code> 内容的高度,修改 <code>translateY</code> 来达到滚动的目的,横向滚动的原理类似。那么计算<strong>可滚动的高度</strong>就是 BetterScroll 必备的逻辑。一般这个逻辑出错的场景在于:</p> <ol><li><p><strong>存在不确定尺寸的图片</strong></p> <ul><li><p><strong>原因</strong></p> <p>bs 执行计算<strong>可滚动高度</strong>的时候,图片还未渲染完成,也无法监听到图片的加载。有时候甚至配置 <code>observeDOM</code> 为 <code>true</code> 也没效果。</p></li> <li><p><strong>解决</strong></p> <p>在图片的 onload 的回调函数里面调用 <code>bs.refresh()</code> 来确保得到正确的图片高度之后再计算<strong>可滚动的高度</strong>。</p> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p><code>observeDOM</code> 为 <code>true</code> 的时候,BetterScroll 首先通过 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver" target="_blank" rel="noopener noreferrer">MutationObserver<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 来监视对 DOM Tree 的改变,但是<strong>无法监听图片是否加载完成</strong>,所以需要手动调用 <code>refresh()</code> 来计算高度。</p> <p>如果当前浏览器不支持 MutationObserver,会降级用 <code>setTimeout</code> 每隔 1s 来重复计算可滚动的高度,这样又能保证在图片加载完成之后,可滚动的高度计算正确。</p></div></li></ul></li> <li><p><strong>Vue 的 keep-alive 组件</strong></p> <ul><li><p><strong>场景</strong></p> <p>假设存在 A、B 两个被 <code>keep-alive</code> 包裹的组件,A 组件使用了 BetterScroll,在 A 组件做了某种操作,弹出输入键盘,之后进入到 B 组件,再返回 A 组件的时候,bs 无法滚动。</p></li> <li><p><strong>原因</strong></p> <p>由于 Vue 的 keep-alive 的缓存加上输入键盘弹起时候,会压缩可视区域的高度,导致之前计算过的可滚动的高度有误。</p></li> <li><p><strong>解决</strong></p> <p>可以在 Vue 的 <code>activated</code> 的钩子里面调用 <code>bs.refresh()</code> 重新计算高度或者重新实例化 bs。</p></li></ul></li></ol> <h3 id="【问题二】为什么我用-betterscroll-做了横向滚动之后-纵向滚动失效"><a href="#【问题二】为什么我用-betterscroll-做了横向滚动之后-纵向滚动失效" class="header-anchor">#</a> 【问题二】为什么我用 BetterScroll 做了横向滚动之后,纵向滚动失效?</h3> <p>BetterScroll 提供了 <code>slide</code> 的 feature。如果实现了一个横向滚动的 <code>slide</code>,在 <code>slide</code> 区域做竖向滚动的操作,无法冒泡到浏览器,这样就无法操纵原生浏览器的滚动条了。</p> <ul><li><p><strong>原因</strong></p> <p>BetterScroll 内部的滚动计算存在于用户的交互,比如移动端就是 <code>touchstart/touchmove/touchend</code> 事件,这些事件的侦听器一般都有 <code>e.preventDefault()</code> 这一行代码,会阻止浏览器的默认行为,这样浏览器的滚动条无法被滚动。</p></li> <li><p><strong>解决</strong></p> <p>配置 <code>eventPassthrough</code> 属性。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> bs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  50. <span class="token literal-property property">eventPassthrough</span><span class="token operator">:</span> <span class="token string">'vertical'</span> <span class="token comment">// 保持纵向的原生浏览器滚动</span>
  51. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  52. </code></pre></div></li></ul> <h3 id="【问题三】为什么我用-betterscroll-之后-无法在浏览器弹出长按图片保存等弹窗。"><a href="#【问题三】为什么我用-betterscroll-之后-无法在浏览器弹出长按图片保存等弹窗。" class="header-anchor">#</a> 【问题三】为什么我用 BetterScroll 之后,无法在浏览器弹出长按图片保存等弹窗。</h3> <ul><li><p><strong>原因</strong></p> <p>在<strong>问题二</strong>已经提到了,<code>touchstart</code> 事件里面的<code>e.preventDefault()</code> 造成的。</p></li> <li><p><strong>解决</strong></p> <p>方案一:配置 <code>preventDefaultException</code> 属性。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> bs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  53. <span class="token literal-property property">preventDefaultException</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  54. <span class="token literal-property property">className</span><span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">(^|\s)test(\s|$)</span><span class="token regex-delimiter">/</span></span>
  55. <span class="token punctuation">}</span>
  56. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  57. </code></pre></div><p>通过 <code>preventDefaultException</code> 可以控制 <code>touchstart</code> 和 <code>touchmove</code> 事件的 <code>e.preventDefault()</code>。上述的正则是用来校验当前触摸的目标元素 class 名称是否含有 <code>test</code>,如果通过了,则不会调用 <code>e.preventDefault()</code>。</p> <p>方案二:配置 <code>preventDefault</code> 属性。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> bs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  58. <span class="token literal-property property">preventDefault</span><span class="token operator">:</span> <span class="token boolean">false</span>
  59. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  60. </code></pre></div><p>preventDefault 设置为 false,会有一些副作用,一般推荐使用<strong>方案一</strong>。</p> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>副作用在于:touch 事件可能会冒泡到 document,导致文档也被拖拽。这个时候你需要监听 <code>wrapper</code> 元素的父元素或者祖先元素,给他们绑定 touchmove 事件,并且调用 <code>e.preventDefault()</code>。最常见的应该是<a href="https://www.cnblogs.com/jasonwang2y60/p/6848464.html" target="_blank" rel="noopener noreferrer">禁止微信下拉浏览器查看域名<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></div></li></ul> <h3 id="【问题四】为什么-betterscroll-content-内部的所有的-click-事件的侦听器都不触发"><a href="#【问题四】为什么-betterscroll-content-内部的所有的-click-事件的侦听器都不触发" class="header-anchor">#</a> 【问题四】为什么 BetterScroll content 内部的所有的 click 事件的侦听器都不触发?</h3> <ul><li><p><strong>原因</strong></p> <p>依然是 <code>touch</code> 事件的 <code>e.preventDefault()</code> 的原因。在移动端,如果你在 <code>touchstart/touchmove/touchend</code> 的逻辑里面调用 <code>e.preventDefault()</code>,会阻止它以及它子元素的 click 事件的执行。因此,BetterScroll 内部会管理 <code>click</code> 事件的派发,你只需要 <code>click</code> 配置项即可。</p></li> <li><p><strong>解决</strong></p> <p>配置 <code>click</code> 属性。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> bs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  61. <span class="token literal-property property">click</span><span class="token operator">:</span> <span class="token boolean">true</span>
  62. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  63. </code></pre></div></li></ul> <h3 id="【问题五】为什么在嵌套-betterscroll-的时候-click-事件派发两次"><a href="#【问题五】为什么在嵌套-betterscroll-的时候-click-事件派发两次" class="header-anchor">#</a> 【问题五】为什么在嵌套 BetterScroll 的时候,click 事件派发两次?</h3> <ul><li><p><strong>原因</strong></p> <p>正如<strong>问题四</strong>所说,BetterScroll 内部会派发 <code>click</code> 事件,并且嵌套场景肯定是存在两个或两个以上的 bs。</p></li> <li><p><strong>解决</strong></p> <p>你可以通过实例化内层 BetterScroll 的 <code>stopPropagation</code> 配置项来管理事件的冒泡,或者通过配置内层 BetterScroll 的 <code>click</code> 配置项来防止 click 的多次触发。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> innerBS <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  64. <span class="token literal-property property">stopPropagation</span><span class="token operator">:</span> <span class="token boolean">true</span>
  65. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  66. <span class="token comment">// 或者</span>
  67. <span class="token keyword">let</span> innerBS <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  68. <span class="token literal-property property">click</span><span class="token operator">:</span> <span class="token boolean">false</span>
  69. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  70. </code></pre></div></li></ul> <h3 id="【问题六】为什么我监听了-bs-的-scroll-事件-为啥回调不执行"><a href="#【问题六】为什么我监听了-bs-的-scroll-事件-为啥回调不执行" class="header-anchor">#</a> 【问题六】为什么我监听了 bs 的 scroll 事件,为啥回调不执行?</h3> <ul><li><p><strong>原因</strong></p> <p>BetterScroll 并不是在任何时刻都会派发 <code>scroll</code> 事件,因为获取 bs 的滚动位置是有一定的性能损耗。至于是否派发,是取决于 <code>probeType</code> 配置项。</p></li> <li><p><strong>解决</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> bs <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.div'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  71. <span class="token literal-property property">probeType</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token comment">// 实时派发</span>
  72. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  73. </code></pre></div></li></ul> <h3 id="【问题七】在两个纵向嵌套的-bs-场景-为什么移动内层的-bs-会导致外层也被滚动。"><a href="#【问题七】在两个纵向嵌套的-bs-场景-为什么移动内层的-bs-会导致外层也被滚动。" class="header-anchor">#</a> 【问题七】在两个纵向嵌套的 bs 场景,为什么移动内层的 bs,会导致外层也被滚动。</h3> <ul><li><p><strong>原因</strong></p> <p>BetterScroll 的内部逻辑都在 touch 事件的侦听器函数体内,既然内部的 bs 的 touch 事件被触发,自然会冒泡到外层的 bs。</p></li> <li><p><strong>解决</strong></p> <p>既然知道原因,那么也有相对应的解决办法。比如在你滚动内层的 bs 时候,监听 scroll 事件,调用外层的 <code>bs.disable()</code> 来禁用外层的 bs。当内层的 bs 滚动到底部的时候,说明这个时候需要滚动外层的 bs,这个时候调用外层的 <code>bs.enable()</code> 来激活外层,并且调用内层的 <code>bs.disable()</code> 禁止内层滚动。其实仔细想一想,这个交互就跟原生 Web 的嵌套滚动行为表现一致,只不过浏览器帮你处理了各种滚动嵌套的逻辑,而在 BetterScroll 需要你自己通过派发的事件以及暴露的 API 来实现。</p> <blockquote><p>cube-ui 的 <a href="https://didi.github.io/cube-ui/example/#/scroll/v-scrolls" target="_blank" rel="noopener noreferrer">scroll<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 组件对此场景给出了相应的解决思路。<a href="https://github.com/didi/cube-ui/blob/dev/src/components/scroll/scroll.vue" target="_blank" rel="noopener noreferrer">代码在这<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></blockquote></li></ul> <h3 id="【问题八】在纵向-bs-嵌套横向-bs-的场景-为什么在横向-bs-的区域竖向移动不会使得外层纵向-bs-的垂直滚动"><a href="#【问题八】在纵向-bs-嵌套横向-bs-的场景-为什么在横向-bs-的区域竖向移动不会使得外层纵向-bs-的垂直滚动" class="header-anchor">#</a> 【问题八】在纵向 bs 嵌套横向 bs 的场景,为什么在横向 bs 的区域竖向移动不会使得外层纵向 bs 的垂直滚动?</h3> <ul><li><p><strong>原因</strong></p> <p>原因与<strong>问题二</strong>类似,还是因为 <code>e.preventDefault()</code> 影响了默认的滚动行为,导致外层的 bs 不会触发 touch 事件。</p></li> <li><p><strong>解决</strong></p> <p>解决办法就是配置内层的 bs 的 <code>eventPassthrough</code> 属性,让其保持默认的原生竖向滚动,</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> innerBS <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BScroll</span><span class="token punctuation">(</span><span class="token string">'.wrapper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  74. <span class="token literal-property property">eventPassthrough</span><span class="token operator">:</span> <span class="token string">'vertical'</span> <span class="token comment">// 保持纵向的原生浏览器滚动</span>
  75. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  76. </code></pre></div></li></ul> <h3 id="【问题九】国产浏览器中-横向-slide-切换卡顿或无效问题。"><a href="#【问题九】国产浏览器中-横向-slide-切换卡顿或无效问题。" class="header-anchor">#</a> 【问题九】国产浏览器中,横向 slide 切换卡顿或无效问题。</h3> <ul><li><p><strong>原因</strong></p> <p>国产浏览器大多数都会监听默认的横滑事件,以实现浏览器的快速“回退”和”前进“。</p></li> <li><p><strong>解决</strong></p> <p>主要是使用一个 CSS 特性<code>touch-action</code>,如果是横向的滑动,将 <code>touch-action: pan-y</code> CSS 设置在 <code>wrapper</code> 上面,这样就可以避免横向的切换触发浏览器的默认行为。</p></li></ul></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/ustbhuangyi/better-scroll/edit/dev/packages/vuepress-docs/docs/zh-CN/FAQ/diagnosis.md" target="_blank" rel="noopener noreferrer">在 GitHub 上编辑此页</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2021/1/7 10:43:35</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
  77. <a href="/docs/zh-CN/FAQ/" class="prev router-link-active">
  78. FAQ
  79. </a></span> <!----></p></div> </main></div><div class="global-ui"><!----></div></div>
  80. <script src="/docs/assets/js/app.c71b64d3.js" defer></script><script src="/docs/assets/js/5.d6412664.js" defer></script><script src="/docs/assets/js/4.4855b9ef.js" defer></script><script src="/docs/assets/js/3.481632b4.js" defer></script><script src="/docs/assets/js/99.c75096e0.js" defer></script>
  81. </body>
  82. </html>