{"id":178,"date":"2025-11-25T09:03:26","date_gmt":"2025-11-25T01:03:26","guid":{"rendered":"https:\/\/www.52runoob.com\/?p=178"},"modified":"2025-11-25T09:03:26","modified_gmt":"2025-11-25T01:03:26","slug":"%e7%9f%ad%e8%a7%86%e9%a2%91%e6%bb%91%e5%8a%a8%e6%92%ad%e6%94%be%e5%9c%a8-h5-%e4%b8%8b%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%96%b9%e5%bc%8f","status":"publish","type":"post","link":"https:\/\/www.52runoob.com\/index.php\/2025\/11\/25\/%e7%9f%ad%e8%a7%86%e9%a2%91%e6%bb%91%e5%8a%a8%e6%92%ad%e6%94%be%e5%9c%a8-h5-%e4%b8%8b%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%96%b9%e5%bc%8f\/","title":{"rendered":"\u77ed\u89c6\u9891\u6ed1\u52a8\u64ad\u653e\u5728 H5 \u4e0b\u7684\u5b9e\u73b0\u65b9\u5f0f"},"content":{"rendered":"\n<p>\u4e0b\u9762\u7ed9\u4f60 <strong>\u6700\u5b9e\u7528 + \u53ef\u76f4\u63a5\u843d\u5730 + \u63a5\u8fd1\u6296\u97f3\/\u5feb\u624b\u4f53\u9a8c<\/strong> \u7684 <strong>H5 \u77ed\u89c6\u9891\u4e0a\u4e0b\u6ed1\u52a8\u64ad\u653e\u5b9e\u73b0\u65b9\u6848<\/strong>\u3002\u5305\u542b\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u539f\u7406\u8bb2\u89e3<\/li>\n\n\n\n<li>\u4e09\u79cd\u4e3b\u6d41\u5b9e\u73b0\u65b9\u5f0f<\/li>\n\n\n\n<li>\u5b8c\u6574\u53ef\u8fd0\u884c\u7684\u4ee3\u7801\u793a\u4f8b<\/li>\n\n\n\n<li>\u6027\u80fd\u4f18\u5316\uff08\u975e\u5e38\u5173\u952e\uff09<\/li>\n<\/ul>\n\n\n\n<p>\u963f\u6770\uff0c\u4f60\u76f4\u63a5\u590d\u5236\u793a\u4f8b\u5c31\u80fd\u8fd0\u884c\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 \u4e00\u3001\u6838\u5fc3\u529f\u80fd\u539f\u7406\uff08\u6296\u97f3\u540c\u6b3e\uff09<\/h1>\n\n\n\n<p>H5 \u60f3\u5b9e\u73b0\u7c7b\u4f3c\u77ed\u89c6\u9891 App \u7684\u6548\u679c\uff0c\u9700\u8981\u505a\u5230\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u7ad6\u5c4f\u5168\u5c4f\u89c6\u9891\uff08100vh\uff09<\/strong><\/li>\n\n\n\n<li><strong>\u4e0a\u4e0b\u6ed1\u52a8\u5207\u6362\u4e0b\u4e00\u6761\u89c6\u9891<\/strong><\/li>\n\n\n\n<li><strong>\u65b0\u89c6\u9891\u81ea\u52a8\u64ad\u653e\uff0c\u65e7\u89c6\u9891\u6682\u505c<\/strong><\/li>\n\n\n\n<li><strong>\u53ea\u52a0\u8f7d\u5f53\u524d\u4e0e\u4e0a\u4e0b\u89c6\u9891\uff08\u61d2\u52a0\u8f7d\uff09<\/strong><\/li>\n\n\n\n<li><strong>\u6ed1\u52a8\u8ddd\u79bb\u8d85\u8fc7\u9608\u503c\u65f6\u89e6\u53d1\u5207\u6362<\/strong><\/li>\n<\/ol>\n\n\n\n<p>\u79fb\u52a8\u7aef\u8981\u6c42\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u652f\u6301 touch \u4e8b\u4ef6<\/li>\n\n\n\n<li>\u907f\u514d 300ms \u70b9\u51fb\u5ef6\u8fdf<\/li>\n\n\n\n<li>\u89c6\u9891\u4f7f\u7528 <code>playsinline<\/code> + <code>muted<\/code> \u624d\u80fd\u81ea\u52a8\u64ad\u653e<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 \u4e8c\u3001\u4e09\u79cd\u4e3b\u6d41\u65b9\u6848\uff08\u4efb\u9009\u5176\u4e00\uff09<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u65b9\u6848<\/th><th>\u539f\u7406<\/th><th>\u6d41\u7545\u5ea6<\/th><th>\u96be\u5ea6<\/th><\/tr><\/thead><tbody><tr><td><strong>\u2460 \u539f\u751f touch \u4e8b\u4ef6 + translateY<\/strong><\/td><td>\u81ea\u5df1\u63a7\u5236\u6ed1\u52a8 + \u60ef\u6027 + \u7ffb\u9875<\/td><td>\u2b50\u2b50\u2b50\u2b50\u2b50 \u6700\u7075\u6d3b<\/td><td>\u4e2d<\/td><\/tr><tr><td><strong>\u2461 Swiper.js\uff08\u6700\u7b80\u5355\uff09<\/strong><\/td><td>\u7528\u8f6e\u64ad\u5e93\u5207\u5c4f<\/td><td>\u2b50\u2b50\u2b50\u2b50<\/td><td>\u6700\u4f4e<\/td><\/tr><tr><td><strong>\u2462 IntersectionObserver\uff08\u6dd8\u7cfb\u5e38\u7528\uff09<\/strong><\/td><td>\u76d1\u63a7\u7528\u6237\u8fdb\u5165\u89c6\u53e3\u65f6\u64ad\u653e<\/td><td>\u2b50\u2b50\u2b50\u2b50<\/td><td>\u4e2d\u7b49<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u5982\u679c\u4f60\u60f3\u8981\u6700\u63a5\u8fd1\u6296\u97f3\u4f53\u9a8c \u2192 \u9009\u65b9\u6848\u2460\uff08\u4e0b\u9762\u7b2c\u4e00\u4e2a\u4ee3\u7801\u5c31\u662f\uff09\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 \u4e09\u3001\u65b9\u6848\u2460\uff1a\u539f\u751f touch + transform \u5b9e\u73b0\uff08\u6296\u97f3\u540c\u6b3e\uff09<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<p>\u4e0b\u9762\u4ee3\u7801\u76f4\u63a5\u80fd\u8dd1\uff0c\u9002\u5408\u4f60\u63a5\u5165 API\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udcc4 <strong>index.html<\/strong><\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;!DOCTYPE html&gt;\n&amp;lt;html&gt;\n&amp;lt;head&gt;\n&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,initial-scale=1,user-scalable=no&quot;&gt;\n&amp;lt;title&gt;\u77ed\u89c6\u9891\u4e0a\u4e0b\u6ed1\u52a8&amp;lt;\/title&gt;\n&amp;lt;style&gt;\n  body,html {\n    margin:0; padding:0; overflow:hidden; height:100%;\n  }\n  .container {\n    position:relative;\n    width:100%;\n    height:100%;\n    overflow:hidden;\n  }\n  .wrap {\n    position:absolute;\n    width:100%;\n    height:100%;\n    top:0;\n    left:0;\n    transition:transform .3s ease;\n  }\n  .video-item {\n    width:100%;\n    height:100vh;\n    position:relative;\n    overflow:hidden;\n    background:#000;\n  }\n  video {\n    width:100%;\n    height:100%;\n    object-fit:cover;\n  }\n&amp;lt;\/style&gt;\n&amp;lt;\/head&gt;\n&amp;lt;body&gt;\n&amp;lt;div class=&quot;container&quot;&gt;\n  &amp;lt;div id=&quot;wrap&quot; class=&quot;wrap&quot;&gt;\n    &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;1.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;2.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;3.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/div&gt;\n\n&amp;lt;script src=&quot;main.js&quot;&gt;&amp;lt;\/script&gt;\n&amp;lt;\/body&gt;\n&amp;lt;\/html&gt;\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udcc4 <strong>main.js<\/strong><\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst wrap = document.getElementById(&quot;wrap&quot;);\nconst items = document.querySelectorAll(&quot;.video-item&quot;);\nconst H = window.innerHeight;\n\nlet current = 0;\nlet startY = 0;\nlet deltaY = 0;\nlet isMoving = false;\n\n\/\/ \u81ea\u52a8\u64ad\u653e\u7b2c\u4e00\u4e2a\nitems&#x5B;0].querySelector(&quot;video&quot;).play();\n\nfunction playCurrent() {\n  items.forEach((item, i) =&gt; {\n    const v = item.querySelector(&quot;video&quot;);\n    if (i === current) {\n      v.play();\n    } else {\n      v.pause();\n      v.currentTime = 0;\n    }\n  });\n}\n\ndocument.addEventListener(&quot;touchstart&quot;, e =&gt; {\n  startY = e.touches&#x5B;0].clientY;\n  deltaY = 0;\n  isMoving = true;\n  wrap.style.transition = &quot;none&quot;;\n});\n\ndocument.addEventListener(&quot;touchmove&quot;, e =&gt; {\n  if (!isMoving) return;\n\n  deltaY = e.touches&#x5B;0].clientY - startY;\n  wrap.style.transform = `translateY(${ -current * H + deltaY }px)`;\n});\n\ndocument.addEventListener(&quot;touchend&quot;, e =&gt; {\n  isMoving = false;\n  wrap.style.transition = &quot;transform .3s ease&quot;;\n\n  \/\/ \u4e0b\u6ed1\n  if (deltaY &amp;lt; -80 &amp;amp;&amp;amp; current &amp;lt; items.length - 1) {\n    current++;\n  }\n  \/\/ \u4e0a\u6ed1\n  else if (deltaY &gt; 80 &amp;amp;&amp;amp; current &gt; 0) {\n    current--;\n  }\n\n  wrap.style.transform = `translateY(${-current * H}px)`;\n  playCurrent();\n});\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udd25 \u6548\u679c\u7279\u70b9<\/h1>\n\n\n\n<p>\u2714 \u7c7b\u6296\u97f3\u6d41\u7545\u6ed1\u52a8<br>\u2714 \u81ea\u5b9a\u4e49\u6ed1\u52a8\u9608\u503c<br>\u2714 \u81ea\u52a8\u64ad\u653e\u5f53\u524d\u89c6\u9891<br>\u2714 \u4ec5\u6682\u505c\u5176\u4f59\u89c6\u9891<br>\u2714 \u517c\u5bb9 iOS \/ Android H5<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 \u56db\u3001\u65b9\u6848\u2461\uff1a\u7528 Swiper.js\uff08\u4e09\u5206\u949f\u641e\u5b9a\uff09<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">\u5f15\u5165 Swiper<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.css&quot;&gt;\n&amp;lt;script src=&quot;https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.js&quot;&gt;&amp;lt;\/script&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">HTML<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;div class=&quot;swiper&quot;&gt;\n  &amp;lt;div class=&quot;swiper-wrapper&quot;&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;1.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;2.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;3.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/div&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">JS<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst swiper = new Swiper(&#039;.swiper&#039;, {\n  direction: &#039;vertical&#039;,\n  on: {\n    slideChange() {\n      document.querySelectorAll(&quot;video&quot;).forEach((v,i)=&gt;{\n        if(i===swiper.activeIndex){\n          v.play();\n        } else {\n          v.pause();\n          v.currentTime=0;\n        }\n      });\n    }\n  }\n});\n\n<\/pre><\/div>\n\n\n<p>\u7b80\u5355\u7c97\u66b4\uff0c\u7a33\u5b9a\u597d\u7528\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 \u4e94\u3001\u65b9\u6848\u2462\uff1aIntersectionObserver \u61d2\u52a0\u8f7d\u64ad\u653e<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<p>\u9002\u5408\u957f\u5217\u8868 \/ \u65e0\u9650\u6eda\u52a8\u3002<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst io = new IntersectionObserver((entries)=&gt;{\n  entries.forEach(entry=&gt;{\n    const video = entry.target;\n    if(entry.isIntersecting){\n      video.play();\n    } else {\n      video.pause();\n    }\n  });\n}, { threshold:0.8 });\n\ndocument.querySelectorAll(&quot;video&quot;).forEach(v =&gt; io.observe(v));\n\n<\/pre><\/div>\n\n\n<p>\u8fdb\u5165\u89c6\u53e3\u64ad\u653e\uff0c\u79bb\u5f00\u6682\u505c\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udd27 \u516d\u3001\u5fc5\u987b\u505a\u7684\u6027\u80fd\u4f18\u5316\uff08\u77ed\u89c6\u9891\u5173\u952e\uff09<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">===========================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u53ea\u5728\u5f53\u524d\u9875\u9762\u4fdd\u7559 1~3 \u4e2a video<\/h3>\n\n\n\n<p>\u907f\u514d\u51e0\u5341\u4e2a <code>&lt;video&gt;<\/code> \u5bfc\u81f4\u5185\u5b58\u7206\u70b8\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u4f7f\u7528 preload=&#8221;none&#8221;<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;video preload=&quot;none&quot;&gt;&amp;lt;\/video&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">3. Android \u5fc5\u987b muted + playsinline \u624d\u80fd\u81ea\u52a8\u64ad\u653e<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;video muted playsinline webkit-playsinline&gt;&amp;lt;\/video&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">4. \u6839\u636e\u7f51\u7edc\u60c5\u51b5\u505a\u5206\u8fa8\u7387\u5207\u6362\uff08\u53ef\u9009\uff09<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">5. \u4f7f\u7528 requestAnimationFrame \u505a\u6ed1\u52a8\u8ddf\u8e2a<\/h3>\n\n\n\n<p>\u6bd4 touchmove \u66f4\u7a33\u5b9a\u3002<\/p>\n\n\n\n<p>\u597d\u7684\u963f\u6770\uff01\u6211\u76f4\u63a5\u628a <strong>\u6240\u6709\u7248\u672c\u4e00\u6b21\u6027\u7ed9\u4f60<\/strong>\uff1a<br><strong>\u7eaf\u539f\u751f\u7248 \/ Swiper\u7248 \/ IntersectionObserver\u7248 \/ Vue\u7248 \/ React\u7248 \/ UniApp\u7248 \/ Flutter WebView\u7248<\/strong><br>\u5168\u90e8\u90fd\u662f <strong>\u53ef\u76f4\u63a5\u8dd1\u7684\u5b8c\u6574\u4ee3\u7801<\/strong>\uff0c\u4f60\u62f7\u8d1d\u5373\u53ef\u4f7f\u7528\u3002<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u5185\u5bb9\u8f83\u591a\uff0c\u6211\u4e3a\u6bcf\u4e2a\u7248\u672c\u90fd\u505a\u4e86\u7ed3\u6784\u5316\u6574\u7406\uff0c\u4f60\u770b\u5230\u54ea\u4e00\u4e2a\u7248\u672c\uff0c\u590d\u5236\u5373\u7528\u3002<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 1\uff1a\u539f\u751f JS\uff08\u6296\u97f3\u6ed1\u52a8\u6a21\u5f0f\uff09<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc4 <strong>index.html<\/strong><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;!DOCTYPE html&gt;\n&amp;lt;html&gt;\n&amp;lt;head&gt;\n&amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width,initial-scale=1&quot;&gt;\n&amp;lt;style&gt;\nbody,html{margin:0;height:100%;overflow:hidden;}\n.wrap{position:absolute;width:100%;height:100%;transition:transform .3s;}\n.video-item{width:100%;height:100vh;background:#000;}\nvideo{width:100%;height:100%;object-fit:cover;}\n&amp;lt;\/style&gt;\n&amp;lt;\/head&gt;\n&amp;lt;body&gt;\n&amp;lt;div id=&quot;wrap&quot; class=&quot;wrap&quot;&gt;\n  &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;1.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n  &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;2.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n  &amp;lt;div class=&quot;video-item&quot;&gt;&amp;lt;video src=&quot;3.mp4&quot; playsinline muted&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n&amp;lt;\/div&gt;\n&amp;lt;script src=&quot;main.js&quot;&gt;&amp;lt;\/script&gt;\n&amp;lt;\/body&gt;\n&amp;lt;\/html&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc4 <strong>main.js<\/strong><\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst wrap = document.getElementById(&quot;wrap&quot;);\nconst items = document.querySelectorAll(&quot;.video-item&quot;);\nconst H = window.innerHeight;\n\nlet current = 0, startY = 0, deltaY = 0, moving = false;\n\nitems&#x5B;0].querySelector(&quot;video&quot;).play();\n\nfunction playCurrent(){\n  items.forEach((item,i)=&gt;{\n    const v = item.querySelector(&quot;video&quot;);\n    if(i===current){v.play();}\n    else{v.pause();v.currentTime=0;}\n  });\n}\n\ndocument.addEventListener(&quot;touchstart&quot;, e=&gt;{\n  moving=true;\n  startY = e.touches&#x5B;0].clientY;\n  deltaY = 0;\n  wrap.style.transition=&quot;none&quot;;\n});\n\ndocument.addEventListener(&quot;touchmove&quot;, e=&gt;{\n  if(!moving) return;\n  deltaY = e.touches&#x5B;0].clientY - startY;\n  wrap.style.transform = `translateY(${ -current*H + deltaY }px)`;\n});\n\ndocument.addEventListener(&quot;touchend&quot;, ()=&gt;{\n  moving=false;\n  wrap.style.transition=&quot;transform .3s&quot;;\n  if(deltaY &amp;lt; -80 &amp;amp;&amp;amp; current &amp;lt; items.length-1) current++;\n  if(deltaY &gt; 80 &amp;amp;&amp;amp; current &gt; 0) current--;\n  wrap.style.transform = `translateY(${-current*H}px)`;\n  playCurrent();\n});\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 2\uff1aSwiper.js\uff08\u6700\u7b80\u5355\uff09<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc4 HTML<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.css&quot;&gt;\n&amp;lt;script src=&quot;https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.js&quot;&gt;&amp;lt;\/script&gt;\n\n&amp;lt;div class=&quot;swiper&quot;&gt;\n  &amp;lt;div class=&quot;swiper-wrapper&quot;&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;1.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;2.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n    &amp;lt;div class=&quot;swiper-slide&quot;&gt;&amp;lt;video src=&quot;3.mp4&quot; muted playsinline&gt;&amp;lt;\/video&gt;&amp;lt;\/div&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/div&gt;\n\n&amp;lt;script&gt;\nconst swiper = new Swiper(&#039;.swiper&#039;,{\n  direction:&#039;vertical&#039;,\n  on:{\n    slideChange(){\n      document.querySelectorAll(&quot;video&quot;).forEach((v,i)=&gt;{\n        if(i===swiper.activeIndex) v.play();\n        else{v.pause();v.currentTime=0;}\n      });\n    }\n  }\n});\n&amp;lt;\/script&gt;\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 3\uff1aIntersectionObserver\uff08\u61d2\u52a0\u8f7d+\u81ea\u52a8\u64ad\u653e\uff09<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">HTML<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;video src=&quot;1.mp4&quot; muted playsinline preload=&quot;none&quot;&gt;&amp;lt;\/video&gt;\n&amp;lt;video src=&quot;2.mp4&quot; muted playsinline preload=&quot;none&quot;&gt;&amp;lt;\/video&gt;\n&amp;lt;video src=&quot;3.mp4&quot; muted playsinline preload=&quot;none&quot;&gt;&amp;lt;\/video&gt;\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">JS<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst io = new IntersectionObserver((entries)=&gt;{\n  entries.forEach(entry=&gt;{\n    const v = entry.target;\n    if(entry.isIntersecting){\n      v.play();\n    }else{\n      v.pause();\n    }\n  });\n},{threshold:0.7});\n\ndocument.querySelectorAll(&quot;video&quot;).forEach(v=&gt;io.observe(v));\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 4\uff1aVue 3\uff08\u7ec4\u5408\u5f0f API\uff09\u77ed\u89c6\u9891\u7ec4\u4ef6<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc4 VideoList.vue<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;template&gt;\n  &amp;lt;div class=&quot;wrap&quot; :style=&quot;{transform:`translateY(${ -current * height }px)`}&quot;&gt;\n    &amp;lt;div class=&quot;item&quot; v-for=&quot;(url,i) in list&quot; :key=&quot;i&quot;&gt;\n      &amp;lt;video ref=&quot;videos&quot; :src=&quot;url&quot; playsinline muted&gt;&amp;lt;\/video&gt;\n    &amp;lt;\/div&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/template&gt;\n\n&amp;lt;script setup&gt;\nimport { ref, onMounted } from &quot;vue&quot;;\n\nconst list = &#x5B;&quot;1.mp4&quot;,&quot;2.mp4&quot;,&quot;3.mp4&quot;];\nconst height = window.innerHeight;\nconst current = ref(0);\nconst videos = ref(&#x5B;]);\n\nlet startY = 0, deltaY = 0, isMove = false;\n\nonMounted(()=&gt;{\n  videos.value&#x5B;0].play();\n\n  document.addEventListener(&quot;touchstart&quot;, e=&gt;{\n    isMove=true;\n    startY = e.touches&#x5B;0].clientY;\n  });\n\n  document.addEventListener(&quot;touchmove&quot;, e=&gt;{\n    if(!isMove) return;\n    deltaY = e.touches&#x5B;0].clientY - startY;\n  });\n\n  document.addEventListener(&quot;touchend&quot;, ()=&gt;{\n    isMove=false;\n    if(deltaY &amp;lt; -80 &amp;amp;&amp;amp; current.value &amp;lt; list.length-1) current.value++;\n    if(deltaY &gt; 80 &amp;amp;&amp;amp; current.value &gt; 0) current.value--;\n    playCurrent();\n  });\n});\n\nfunction playCurrent(){\n  videos.value.forEach((v,i)=&gt;{\n    if(i===current.value) v.play();\n    else{v.pause();v.currentTime=0;}\n  });\n}\n&amp;lt;\/script&gt;\n\n&amp;lt;style&gt;\n.wrap{transition:transform .3s;}\n.item{height:100vh;background:#000;}\nvideo{width:100%;height:100%;object-fit:cover;}\n&amp;lt;\/style&gt;\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 5\uff1aReact\uff08Hooks\uff09\u77ed\u89c6\u9891\u6ed1\u52a8\u7ec4\u4ef6<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">VideoSwiper.jsx<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { useEffect, useRef, useState } from &quot;react&quot;;\n\nexport default function VideoSwiper(){\n  const list = &#x5B;&quot;1.mp4&quot;,&quot;2.mp4&quot;,&quot;3.mp4&quot;];\n  const videos = useRef(&#x5B;]);\n  const &#x5B;current, setCurrent] = useState(0);\n  const H = window.innerHeight;\n\n  let startY = 0, deltaY = 0, moving = false;\n\n  const playCurrent = ()=&gt;{\n    videos.current.forEach((v,i)=&gt;{\n      if(i===current) v.play();\n      else{v.pause();v.currentTime=0;}\n    });\n  };\n\n  useEffect(()=&gt;{\n    videos.current&#x5B;0].play();\n\n    const ts = e =&gt; {moving=true; startY=e.touches&#x5B;0].clientY};\n    const tm = e =&gt; {if(!moving) return; deltaY=e.touches&#x5B;0].clientY - startY};\n    const te = () =&gt; {\n      moving=false;\n      if(deltaY &amp;lt; -80 &amp;amp;&amp;amp; current &amp;lt; list.length-1) setCurrent(c=&gt;c+1);\n      if(deltaY &gt; 80 &amp;amp;&amp;amp; current &gt; 0) setCurrent(c=&gt;c-1);\n    };\n\n    document.addEventListener(&quot;touchstart&quot;, ts);\n    document.addEventListener(&quot;touchmove&quot;, tm);\n    document.addEventListener(&quot;touchend&quot;, te);\n\n    return ()=&gt;{\n      document.removeEventListener(&quot;touchstart&quot;, ts);\n      document.removeEventListener(&quot;touchmove&quot;, tm);\n      document.removeEventListener(&quot;touchend&quot;, te);\n    };\n  }, &#x5B;current]);\n\n  useEffect(()=&gt;playCurrent(),&#x5B;current]);\n\n  return (\n    &amp;lt;div className=&quot;wrap&quot; style={{transform:`translateY(-${current * H}px)`}}&gt;\n      {list.map((url,i)=&gt;(\n        &amp;lt;div className=&quot;item&quot; key={i}&gt;\n          &amp;lt;video ref={el=&gt;videos.current&#x5B;i]=el} src={url} playsInline muted \/&gt;\n        &amp;lt;\/div&gt;\n      ))}\n    &amp;lt;\/div&gt;\n  );\n}\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">CSS<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n.wrap{transition:transform .3s;}\n.item{height:100vh;background:#000;}\nvideo{width:100%;height:100%;object-fit:cover;}\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 6\uff1aUniApp\uff08\u5c0f\u7a0b\u5e8f\/H5\/App \u901a\u7528\uff09<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">pages\/video\/video.vue<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;template&gt;\n  &amp;lt;view class=&quot;wrap&quot; :style=&quot;{transform:`translateY(${-current * height}px)`}&quot;&gt;\n    &amp;lt;view class=&quot;item&quot; v-for=&quot;(url,i) in list&quot; :key=&quot;i&quot;&gt;\n      &amp;lt;video :src=&quot;url&quot; :id=&quot;&#039;v&#039;+i&quot; autoplay muted playsinline&gt;&amp;lt;\/video&gt;\n    &amp;lt;\/view&gt;\n  &amp;lt;\/view&gt;\n&amp;lt;\/template&gt;\n\n&amp;lt;script&gt;\nexport default {\n  data(){\n    return {\n      list:&#x5B;&quot;1.mp4&quot;,&quot;2.mp4&quot;,&quot;3.mp4&quot;],\n      current:0,\n      height:uni.getSystemInfoSync().windowHeight,\n      startY:0,\n      deltaY:0\n    }\n  },\n  methods:{\n    playCurrent(){\n      this.list.forEach((_,i)=&gt;{\n        const ctx = uni.createVideoContext(&quot;v&quot;+i,this);\n        if(i===this.current) ctx.play();\n        else ctx.pause();\n      });\n    }\n  },\n  onReady(){\n    this.playCurrent();\n\n    uni.$on(&quot;touchstart&quot;, e=&gt;{\n      this.startY = e.touches&#x5B;0].clientY;\n    });\n\n    uni.$on(&quot;touchend&quot;, e=&gt;{\n      this.deltaY = e.changedTouches&#x5B;0].clientY - this.startY;\n      if(this.deltaY &amp;lt; -80 &amp;amp;&amp;amp; this.current &amp;lt; this.list.length-1) this.current++;\n      if(this.deltaY &gt; 80 &amp;amp;&amp;amp; this.current &gt; 0) this.current--;\n      this.playCurrent();\n    });\n  }\n}\n&amp;lt;\/script&gt;\n\n&amp;lt;style&gt;\n.wrap{transition:transform .3s;}\n.item{height:100vh;}\nvideo{width:100%;height:100%;object-fit:cover;}\n&amp;lt;\/style&gt;\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\u2705 <strong>\u7248\u672c 7\uff1aFlutter WebView\uff08\u52a0\u8f7d H5 \u77ed\u89c6\u9891\u5217\u8868\uff09<\/strong><\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">pubspec.yaml<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndependencies:\n  flutter:\n    sdk: flutter\n  webview_flutter: ^4.2.1\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">main.dart<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport &#039;package:flutter\/material.dart&#039;;\nimport &#039;package:webview_flutter\/webview_flutter.dart&#039;;\n\nvoid main() =&gt; runApp(VideoApp());\n\nclass VideoApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: WebViewWidget(\n          controller: WebViewController()\n            ..setJavaScriptMode(JavaScriptMode.unrestricted)\n            ..loadRequest(Uri.parse(&quot;https:\/\/yourdomain.com\/video.html&quot;)),\n        ),\n      ),\n    );\n  }\n}\n\n<\/pre><\/div>\n\n\n<p>video.html \u5c31\u7528\u4e0a\u9762\u4efb\u610f H5 \u7248\u672c\u5373\u53ef\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83c\udf89 \u5168\u7248\u672c\u5df2\u5168\u90e8\u7ed9\u4f60<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">================================<\/h1>\n\n\n\n<p>\u4f60\u73b0\u5728\u5df2\u7ecf\u62e5\u6709\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u7248\u672c<\/th><th>\u5df2\u7ed9\u4ee3\u7801<\/th><\/tr><\/thead><tbody><tr><td>\u539f\u751f JS \u6296\u97f3\u6ed1\u52a8<\/td><td>\u2714<\/td><\/tr><tr><td>Swiper \u7b80\u5316\u7248<\/td><td>\u2714<\/td><\/tr><tr><td>IntersectionObserver \u81ea\u52a8\u64ad\u653e<\/td><td>\u2714<\/td><\/tr><tr><td>Vue \u7248\u672c<\/td><td>\u2714<\/td><\/tr><tr><td>React \u7248\u672c<\/td><td>\u2714<\/td><\/tr><tr><td>UniApp \u7248\u672c<\/td><td>\u2714<\/td><\/tr><tr><td>Flutter WebView \u7248\u672c<\/td><td>\u2714<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0b\u9762\u7ed9\u4f60 \u6700\u5b9e\u7528 + \u53ef\u76f4\u63a5\u843d\u5730 + \u63a5\u8fd1\u6296\u97f3\/\u5feb\u624b\u4f53\u9a8c \u7684 H5 \u77ed\u89c6\u9891\u4e0a\u4e0b\u6ed1&#8230; <a class=\"more-link\" href=\"https:\/\/www.52runoob.com\/index.php\/2025\/11\/25\/%e7%9f%ad%e8%a7%86%e9%a2%91%e6%bb%91%e5%8a%a8%e6%92%ad%e6%94%be%e5%9c%a8-h5-%e4%b8%8b%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%96%b9%e5%bc%8f\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-178","post","type-post","status-publish","format-standard","hentry","category-html5"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/comments?post=178"}],"version-history":[{"count":1,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/178\/revisions"}],"predecessor-version":[{"id":179,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/178\/revisions\/179"}],"wp:attachment":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/media?parent=178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/categories?post=178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/tags?post=178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}