Edge与Chrome浏览器中图片轮播平滑滚动失效问题求助
问题解决:Chrome/Edge中scroll-snap拖拽轮播失效的修复
问题根源
你的轮播在Firefox正常但Chrome/Edge失效,核心是webkit内核的兼容性差异:
scroll()方法在webkit中行为与Firefox不一致,原生滚动逻辑干扰自定义拖拽- 未阻止鼠标事件默认行为,浏览器原生滚动/选择与自定义拖拽冲突
transform: translateX(50%)会打乱webkit的scroll-snap计算逻辑- 恢复scroll-snap样式的时机未适配webkit的渲染机制
修复步骤
1. 替换scroll方法为直接修改scrollLeft
将拖拽时的container.scroll((currentscroll - moved), 0)改为container.scrollLeft = currentscroll - moved,规避webkit内核的方法行为差异。
2. 阻止鼠标事件默认行为
在down和move函数中添加e.preventDefault(),阻止浏览器原生滚动、文本选择等行为,避免干扰自定义拖拽逻辑。
3. 移除transform,改用padding实现居中
将.carousel-item的transform: translateX(50%)替换为父容器的padding-left: 50%和padding-right: 50%,同时调整最后一个item的margin,确保scroll-snap在webkit中正常计算。
4. 优化样式恢复时机
在up函数中使用requestAnimationFrame延迟恢复scroll-snap样式,确保webkit内核正确应用样式,避免滚动跳变。
修改后的完整代码
JavaScript
// ----------------------- // // ------ FONCTIONS ------ // // ----------------------- // // DISABLE SELECTION FOR ELEMENTS function clicAndDrag() { const childs = Array.from(document.querySelector('.carousel').children) childs.forEach(undrag) function undrag(e) { e.setAttribute("draggable", "false") e.style.cssText="-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;-o-user-select:none;" e.unselectable="on" e.style.onselectstart = "return false;" e.style.onmousedown = "return false;" const subchilds = Array.from(e.children) subchilds.forEach(undrag) } // GRABBING EFFECT const container = document.querySelector('.carousel') let mousedown = false; document.body.addEventListener('mousedown', () => {mousedown = true}); document.body.addEventListener('mouseup', () => {mousedown = false}); let firstpos; let currentscroll; // Remove smooth scrolling and scrol-snap for free scrolling and get the scroll/cursor positions container.addEventListener('mousedown', down) function down(e) { e.preventDefault(); // 阻止默认行为 currentscroll = container.scrollLeft firstpos = e.clientX container.style.cssText="scroll-behavior: initial; scroll-snap-type: none;" childs.forEach(e => { e.style.cssText="scroll-snap-align: none;" }) } container.addEventListener('mousemove', move) function move(e) { // Grab Effect if (mousedown === true) { e.preventDefault(); // 阻止默认行为 const moved = e.clientX - firstpos container.scrollLeft = currentscroll - moved // 改用scrollLeft直接赋值 } } // Add smooth scrolling with scroll-snap on releasing mouse container.addEventListener('mouseup', up) function up() { // 延迟恢复样式,适配webkit渲染 requestAnimationFrame(() => { container.style.cssText="scroll-snap-type: x mandatory; scroll-behavior: smooth;" childs.forEach(e => { e.style.cssText="scroll-snap-align: center;" }) }) } } // ----------------------- // // ------ LANCEMENT ------ // // ----------------------- // // Gestion du javascript si activé document.addEventListener("DOMContentLoaded", function() { var htmlClass = document.getElementsByTagName('html')[0]; htmlClass.classList.replace("no-js", "has-js"); }) // Lancement des fonctions lorsque la page est chargée window.addEventListener('load', function () { clicAndDrag(); });
CSS
/* -------------------------------- */ /* ------------ GLOBAL ------------ */ /* -------------------------------- */ * { box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body, html { margin: 0; padding: 0; height: 100%; width: 100%; } #global { display: flex; flex-direction: column; } /* -------------------------------- */ /* ------ NAVIGATION EN HAUT ------ */ /* -------------------------------- */ nav { display: flex; justify-content: space-between;; width: 100%; height: 60px; padding: 10px 40px; font-family: 'Karla', sans-serif; font-weight: 400; color: #111; } nav a { text-decoration: none; color: #111; } .logo { display: flex; align-items: center; } .logo a { text-transform: uppercase; font-size: 1.3125em; /* Equivalent a 21px standard*/ letter-spacing: 0.2em; } .menu { display: flex; list-style: none; align-items: center; justify-content: center; font-size: 0.75em; /* Equivalent a 12px standard*/ margin: 0; padding: 0; } .is-active { text-decoration: underline !important; } .menu li { padding-right: 30px; } .menu li:last-child { padding-right: 0; } .social { display: block; } .serie { font-weight: 700; } /* -------------------------------- */ /* ----------- CAROUSEL ----------- */ /* -------------------------------- */ .carousel { display: flex; height: calc(100svh - 80px); width: 100%; overflow-x: scroll; scroll-snap-type: x mandatory; scroll-behavior: smooth; padding-left: 50%; /* 替换transform实现居中 */ padding-right: 50%; } /* Masquage de la scrollbar si javascript activé */ .has-js .carousel { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } /* Idem mais pour navigateurs webkit */ .has-js .carousel::-webkit-scrollbar { display: none; } .carousel-item { display: flex; height: calc(100% - 40px); flex-direction: column; flex: 0 0 auto; margin-right: 30px; /* Espacement entre chaque image */ scroll-snap-align: center; /* 移除transform: translateX(50%) */ } .carousel-item img { height: 100%; /* Redimensionnement par rapport à la hauteur du carrousel */ max-height: 1400px; width: auto; /* Pour conserver les proportions de l'image */ } .carousel-item:last-child { margin-right: 0; /* 调整最后一个item的margin */ } .caption { display: block; font-family: 'Karla', sans-serif; font-weight: 400; color: #111; font-size: 0.75em; /* Equivalent a 12px standard*/ padding: 4px 0 0 0; } footer { display: flex; height: 20px; align-items: center; justify-content: right; font-family: 'Karla', sans-serif; font-weight: 400; text-transform: uppercase; color: #aaaaaa; font-size: 10px; margin-right: 10px; }
HTML
<!DOCTYPE html> <html lang="fr" class="no-js"> <head> <title>Alan Renault - Photographie</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/all.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Karla:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap" rel="stylesheet"> </head> <body> <div id="global"> <!-- NAVIGATION EN HAUT DE LA PAGE --> <nav> <!-- Logo --> <div class="logo"> <a href="#">Alan Renault</a> </div> <!-- Navigation --> <ul class="menu"> <li><span class="serie">Séries :</span></li> <li><a class="is-active" href="index.html">2023</a></li> <li><a href="2022.html">2022</a></li> <li><a href="about.html">À propos</a></li> <li><a href="contact.html">Contact</a></li> <a class="social" href="https://www.instagram.com/alanrenault/" target="_blank"><i class="fa-brands fa-instagram"></i></a> </ul> </nav> <!-- CARROUSEL DE PHOTOS --> <div class="carousel" id="myCarousel"> <div class="carousel-item"><img src="https://alanrenault.com/gallery/photographies/ALR_7064.jpg" alt="Image 1"><span class="caption">Légende</span></div> <div class="carousel-item"><img src="https://alanrenault.com/gallery/photographies/ALR_7048.jpg" alt="Image 2"><span class="caption">Légende</span></div> <div class="carousel-item"><img src="https://alanrenault.com/gallery/photographies/ALR_7977.jpg" alt="Image 3"><span class="caption">Légende</span></div> <div class="carousel-item"><img src="https://alanrenault.com/gallery/photographies/ALR_7940.jpg" alt="Image 3"><span class="caption">Légende</span></div> <div class="carousel-item"><img src="https://alanrenault.com/gallery/photographies/ALR_6932.jpg" alt="Image 3"><span class="caption">Légende</span></div> </div> <footer> Copyright © 2023 - Alan Renault </footer> </div> <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <script src="js/script.js"></script> </body> </html>
内容的提问来源于stack exchange,提问作者Alan Renault
相关产品推荐
相关产品推荐

