点击滚动容器内元素,js设置元素滚动到水平居中或者垂直居中位置
话不多说,先来个完整的html例子,可以直接复制到一个html文件中看效果:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>点击居中功能</title> <style> * { margin: 0; padding: 0; } /* 水平居中样式 */ .horizontal-box { border: 10px solid red; display: flex; flex-wrap: nowrap; overflow-x: auto; } .horizontal-box div { background: green; padding: 0 40px; margin-right: 30px; } .horizontal-box div:nth-last-child(1) { margin-right: 0; } /* 垂直居中样式 */ .vertical-box { border: 10px solid red; overflow-y: auto; } .vertical-box div { background: green; height: 100px; margin-bottom: 30px; } .vertical-box div:nth-last-child(1) { margin-bottom: 0; } </style> </head> <body> <div> <p>点击水平居中 </p> <!-- position: relative一定要设置,决定了 offsetxxx 的值 --> <div class="horizontal-box" style="width:500px;height: 100px;position: relative;"> <div>one</div> <div>two</div> <div>three</div> <div>four</div> <div>five</div> <div>six</div> </div> <p style="margin-top: 100px;">点击垂直居中 </p> <!-- position: relative一定要设置,决定了 offsetxxx 的值 --> <div class="vertical-box" style="width:100px;height: 500px;position: relative;"> <div>one</div> <div>two</div> <div>three</div> <div>four</div> <div>five</div> <div>six</div> </div> </div> <script> //点击水平居中 const domListX = document.querySelectorAll('.horizontal-box div') for (const dom of domListX) { dom.addEventListener('click', (e) => { const scrollDom = document.querySelector('.horizontal-box') const targetDom = e.target setScrollToCenter(scrollDom, targetDom, 'x') }) } //点击垂直居中 const domListY = document.querySelectorAll('.vertical-box div') for (const dom of domListY) { dom.addEventListener('click', (e) => { const scrollDom = document.querySelector('.vertical-box') const targetDom = e.target setScrollToCenter(scrollDom, targetDom, 'y') }) } </script> <script> /** *点击元素自动滚动到水平或垂直中间位置 * @param {HTMLElement} scrollDom - 滚动的元素 * @param {HTMLElement} targetDom - 点击的元素 * @param {string} [type='x'] - x表示水平,y表示垂直,默认为水平 */ function setScrollToCenter (scrollDom, targetDom, type = 'x') { if (!scrollDom || !targetDom) return false //如果是浏览器body的滚动条 if ([window, document, document.documentElement].includes(scrollDom)) { scrollDom = document.documentElement } const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = targetDom const { clientWidth, clientHeight } = scrollDom const targetDistance = type == 'x' ? offsetLeft : offsetTop const scrollClient = type == 'x' ? clientWidth : clientHeight const targetOffset = type == 'x' ? offsetWidth : offsetHeight const val = targetDistance - scrollClient / 2 + targetOffset / 2 // x时,相当于: // targetDom.offsetLeft - scrollDom.clientWidth / 2 + targetDom.offsetWidth / 2 // y时,相当于: // targetDom.offsetTop - scrollDom.clientHeight / 2 + targetDom.offsetHeight / 2 const config = { behavior: 'smooth' } type === 'x' ? config.left = val : config.top = val scrollDom.scrollTo(config) } </script> </body> </html>
再看效果图:
主要功能函数:
/** *点击元素自动滚动到水平或垂直中间位置 * @param {HTMLElement} scrollDom - 滚动的元素 * @param {HTMLElement} targetDom - 点击的元素 * @param {string} [type='x'] - x表示水平,y表示垂直,默认为水平 */ function setScrollToCenter (scrollDom, targetDom, type = 'x') { if (!scrollDom || !targetDom) return false //如果是浏览器body的滚动条 if ([window, document, document.documentElement].includes(scrollDom)) { scrollDom = document.documentElement } const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = targetDom const { clientWidth, clientHeight } = scrollDom const targetDistance = type == 'x' ? offsetLeft : offsetTop const scrollClient = type == 'x' ? clientWidth : clientHeight const targetOffset = type == 'x' ? offsetWidth : offsetHeight const val = targetDistance - scrollClient / 2 + targetOffset / 2 // x时,相当于: // targetDom.offsetLeft - scrollDom.clientWidth / 2 + targetDom.offsetWidth / 2 // y时,相当于: // targetDom.offsetTop - scrollDom.clientHeight / 2 + targetDom.offsetHeight / 2 const config = { behavior: 'smooth' } type === 'x' ? config.left = val : config.top = val scrollDom.scrollTo(config) }
如果是body滚动,scrollDom参数传 document 或者 window 或者 document.documentElement 即可
自律使我自由