在JavaScript中的数字选择器小部件内将所选项目居中 [英] Center Selected Item Inside a Number Picker Widget in JavaScript

查看:94
本文介绍了在JavaScript中的数字选择器小部件内将所选项目居中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[前提条件]



我很难弄清楚如何使 Number Picker Widget 的行为类似到

解决方案

您可以尝试通过以下方式减去选定值的 offsetTop 来设置父级的滚动位置code> scrollHeight 以获得精确的垂直居中位置:



 使用严格; console.clear(); {const选择器= scrollport; const selected =已选择; const scrollports = document.getElementsByClassName(selector); const initialValue = document.getElementsByClassName(selected); const debouncedFunc = debounce(check,250); for(scrollports的const scrollport){scrollport.addEventListener( scroll,debouncedFunc); scrollport.scrollTo({top:initialValue [0] .offsetTop-initialValue [0] .scrollHeight,行为:平滑}); }函数check(e){const rect = e.target.getBoundingClientRect(); const centerCell = document.elementFromPoint(rect.left + e.target.offsetWidth / 2,rect.top + e.target.offsetHeight / 2); for(e.target.getElementsByClassName(selected)的const cell){cell.classList.remove(selected); } centerCell.classList.add(selected); }}函数debounce(func,wait){让超时; return function(... args){const context = this; clearTimeout(timeout);超时= setTimeout(()=> func.apply(context,args),等待); };}  

  * {box-sizing:border-box ; font-family:Roboto,无衬线;}。container {display:flex; flex-direction:行;宽度:10rem;高度:22rem; border-radius:3rem;边框:实心0.2rem#b2b2c2;背景颜色:#000000;显示:flex; align-items:居中; justify-content:center;}。scrollport:before,.scrollport:after {content:’’;}。scrollport {display:flex; flex-direction:列; flex-wrap:nowrap;宽度:9.4rem;高度:22rem;溢出:自动; scroll-snap-type:y必选;}。scrollport:之前,.scrollport:之后,.cell {display:block;滚动对齐对齐方式:居中; flex-grow:1; flex-shrink:0;弹性基础:33.3%;显示:flex;证明内容:中心; align-items:居中;颜色:#e9e9f2; font-size:2.4rem;}。selected {font-size:3rem; font-weight:粗体;颜色:#0073e6;}  

 < div class =容器 < div class = scrollport> < div class = cell> 09< / div> < div class =选定的单元格> 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>  


[Precondition]

I am having difficulty figuring out how to make a Number Picker Widget behave similarly to the mobile picker component. If the user assigns a number by default, then the selected number should be automatically snap to the center when page load.


[Problems]

  • How can I snap this element <div class="cell selected">10</div> to the center of the scrollport by default?
  • Do not rely on any plugins.

"use strict";
console.clear();

{
  const selector = "scrollport";
  const selected = "selected";
  const scrollports = document.getElementsByClassName(selector);
  const debouncedFunc = debounce(check, 250);
  for (const scrollport of scrollports) {
    scrollport.addEventListener("scroll", debouncedFunc);
  }

  function check(e) {
    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);
  }
}

function debounce(func, wait) {
  let timeout;
  return function(...args) {
    const context = this;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), wait);
  };
}

* {
  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>


[Expect Result]

解决方案

You can try setting the parent's scroll position by subtracting the selected value's offsetTop with scrollHeight to get the precise vertically centered position:

"use strict";
console.clear();

{
  const selector = "scrollport";
  const selected = "selected";
  const scrollports = document.getElementsByClassName(selector);
  const initialValue = document.getElementsByClassName(selected);
  const debouncedFunc = debounce(check, 250);
  for (const scrollport of scrollports) {
    scrollport.addEventListener("scroll", debouncedFunc);
    scrollport.scrollTo({
      top: initialValue[0].offsetTop - initialValue[0].scrollHeight,
      behavior: 'smooth'
    });
  }

  function check(e) {
    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);
  }
}

function debounce(func, wait) {
  let timeout;
  return function(...args) {
    const context = this;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), wait);
  };
}

* {
  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>

这篇关于在JavaScript中的数字选择器小部件内将所选项目居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆