本文介绍了具有动画效果的CSS滚动捕捉的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
[前提条件]
我正在尝试制作一个用户可以在其上滚动的号码列表选择器。
应该将所选的数字捕捉到容器的中心
。
选定数字后,应将其放大并更改颜色。
I am trying to make a number list picker that user can scroll on it.The selected number was supposed to snap to the center
of the container.Once a number was selected, it should be enlarged and changed the color.
[问题]
- 如何将第一个或最后一个项目捕捉到
容器的中心? - 是否有CSS或JavaScript检测数字的方法是将
捕捉到中心,然后在其上分配selected
类? - 不要依赖任何插件。
- How can I snap the first or latest items to the center of thecontainer?
- Is there a CSS or JavaScript way to detect a number issnapping to the center then assign
selected
class on it? - Do not rely on any plugins.
* {
box-sizing: border-box;
font-family: Roboto, sans-serif;
}
.container {
display: flex;
flex-direction: row;
width: 10rem;
height: 22rem;
border-radius: 3rem;
border: solid 0.2rem #b2b2c2;
background-color: #000000;
display: flex;
align-items: center;
justify-content: center;
}
.scrollport {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: 9.4rem;
height: 22rem;
overflow: auto;
scroll-snap-type: y mandatory;
}
.cell {
display: block;
scroll-snap-align: center;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 33.3%;
display: flex;
justify-content: center;
align-items: center;
color: #e9e9f2;
font-size: 2.4rem;
}
.selected {
font-size: 3rem;
font-weight: bold;
color: #0073e6;
}
<div class="container">
<div class="scrollport">
<div class="cell">09</div>
<div class="cell selected">10</div>
<div class="cell">11</div>
<div class="cell">12</div>
<div class="cell">13</div>
<div class="cell">14</div>
<div class="cell">15</div>
<div class="cell">16</div>
</div>
</div>
[期望结果]
推荐答案
将伪元素添加到 .scrollport
并将其样式设置为 .cell
Add pseudo elements to .scrollport
and style them like .cell
.scrollport:before,
.scrollport:after {
content: '';
}
.scrollport:before,
.scrollport:after,
.cell {
/* ... */
}
我还创建了一个使用的函数可模拟滚动结束事件。然后,我检查每个单元格
的中心是否在 scrollport
中心附近,并相应地设置类。
Also I created a JS function that utilizes David Walsh's debounce function to simulate a scrollend event. I then check for every cell
if it's center is around the scrollport
's center and set the classes accordingly
"use strict";
console.clear()
{
const selector = 'scrollport'
const selected = 'selected'
const scrollports = document.getElementsByClassName(selector)
for (const scrollport of scrollports) {
scrollport.addEventListener('scroll', debounce(check, 250) /* simulate scrollend event */ )
}
function check(e) {
// uses native elementFromPoint for better performance
const rect = e.target.getBoundingClientRect();
const centerCell = document.elementFromPoint(rect.left + e.target.offsetWidth / 2, rect.top + e.target.offsetHeight / 2)
for (const cell of e.target.getElementsByClassName(selected)) {
cell.classList.remove(selected)
}
centerCell.classList.add(selected)
// Old version for backward compatibility
// const rect = e.target.getBoundingClientRect();
// for (const cell of e.target.children) {
// const cellRect = cell.getBoundingClientRect();
// const bounds = [rect.height/2 - cellRect.height/2, rect.height/2 + cellRect.height/2];
// const centerScrollOffset = cellRect.top - rect.top + cell.offsetHeight / 2
// if (bounds[0] < centerScrollOffset && centerScrollOffset < bounds[1]) {
// cell.classList.add(selected)
// } else {
// cell.classList.remove(selected)
// }
// }
}
}
// From: https://davidwalsh.name/javascript-debounce-function
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
* {
box-sizing: border-box;
font-family: Roboto, sans-serif;
}
.container {
display: flex;
flex-direction: row;
width: 10rem;
height: 22rem;
border-radius: 3rem;
border: solid 0.2rem #b2b2c2;
background-color: #000000;
display: flex;
align-items: center;
justify-content: center;
}
.scrollport:before,
.scrollport:after {
content: '';
}
.scrollport {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: 9.4rem;
height: 22rem;
overflow: auto;
scroll-snap-type: y mandatory;
}
.scrollport:before,
.scrollport:after,
.cell {
display: block;
scroll-snap-align: center;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 33.3%;
display: flex;
justify-content: center;
align-items: center;
color: #e9e9f2;
font-size: 2.4rem;
}
.selected {
font-size: 3rem;
font-weight: bold;
color: #0073e6;
}
<div class="container">
<div class="scrollport">
<div class="cell">09</div>
<div class="cell selected">10</div>
<div class="cell">11</div>
<div class="cell">12</div>
<div class="cell">13</div>
<div class="cell">14</div>
<div class="cell">15</div>
<div class="cell">16</div>
</div>
</div>
这篇关于具有动画效果的CSS滚动捕捉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!