前言
在 用 JavaScript 实现 position sticky 文章中,我提到了用 wheel 来模拟 scroll 效果。
这篇来说说具体怎么实现,挺简单的哦。
Preparation
table.html
<div class="container"><table><thead><tr><th>First Name</th><th>Last Name</th><th>Age</th><th>Address</th><th>Email</th><th>Phone</th><th>City</th><th>Country</th><th>Occupation</th><th>Salary</th></tr></thead><tbody><tr><td>John</td><td>Doe</td><td>30</td><td>123 Main St</td><td>john.doe@example.com</td><td>123-456-7890</td><td>New York</td><td>USA</td><td>Software Engineer</td><td>$80,000</td></tr><tr><td>Jane</td><td>Smith</td><td>25</td><td>456 Elm St</td><td>jane.smith@example.com</td><td>987-654-3210</td><td>Los Angeles</td><td>USA</td><td>Graphic Designer</td><td>$60,000</td></tr><tr><td>Michael</td><td>Johnson</td><td>35</td><td>789 Oak St</td><td>michael.johnson@example.com</td><td>456-789-0123</td><td>Chicago</td><td>USA</td><td>Teacher</td><td>$50,000</td></tr><tr><td>Sarah</td><td>Williams</td><td>28</td><td>321 Pine St</td><td>sarah.williams@example.com</td><td>789-012-3456</td><td>Miami</td><td>USA</td><td>Accountant</td><td>$70,000</td></tr><tr><td>David</td><td>Brown</td><td>40</td><td>654 Cedar St</td><td>david.brown@example.com</td><td>210-987-6543</td><td>Houston</td><td>USA</td><td>Engineer</td><td>$90,000</td></tr><tr><td>Emily</td><td>Miller</td><td>33</td><td>987 Maple St</td><td>emily.miller@example.com</td><td>567-890-1234</td><td>Seattle</td><td>USA</td><td>Manager</td><td>$100,000</td></tr><tr><td>James</td><td>Wilson</td><td>27</td><td>753 Walnut St</td><td>james.wilson@example.com</td><td>890-123-4567</td><td>San Francisco</td><td>USA</td><td>Marketing Specialist</td><td>$75,000</td></tr><tr><td>Emma</td><td>Anderson</td><td>29</td><td>159 Birch St</td><td>emma.anderson@example.com</td><td>234-567-8901</td><td>Boston</td><td>USA</td><td>Consultant</td><td>$85,000</td></tr><tr><td>Christopher</td><td>Lee</td><td>32</td><td>852 Oakwood St</td><td>christopher.lee@example.com</td><td>678-901-2345</td><td>Atlanta</td><td>USA</td><td>Lawyer</td><td>$120,000</td></tr><tr><td>Olivia</td><td>Clark</td><td>26</td><td>357 Elmwood St</td><td>olivia.clark@example.com</td><td>123-456-7890</td><td>Denver</td><td>USA</td><td>Artist</td><td>$55,000</td></tr><tr><td>William</td><td>White</td><td>31</td><td>951 Cedarwood St</td><td>william.white@example.com</td><td>456-789-0123</td><td>Phoenix</td><td>USA</td><td>Architect</td><td>$95,000</td></tr><tr><td>Ava</td><td>Hall</td><td>34</td><td>246 Pinecrest St</td><td>ava.hall@example.com</td><td>789-012-3456</td><td>Dallas</td><td>USA</td><td>Financial Analyst</td><td>$80,000</td></tr><tr><td>Alexander</td><td>Young</td><td>29</td><td>753 Maplewood St</td><td>alexander.young@example.com</td><td>210-987-6543</td><td>Philadelphia</td><td>USA</td><td>Real Estate Agent</td><td>$70,000</td></tr><tr><td>Mia</td><td>Scott</td><td>38</td><td>852 Oak St</td><td>mia.scott@example.com</td><td>567-890-1234</td><td>Minneapolis</td><td>USA</td><td>Doctor</td><td>$150,000</td></tr><tr><td>Ethan</td><td>Adams</td><td>27</td><td>369 Walnut St</td><td>ethan.adams@example.com</td><td>890-123-4567</td><td>Portland</td><td>USA</td><td>Journalist</td><td>$65,000</td></tr><tr><td>Isabella</td><td>Carter</td><td>30</td><td>147 Pine St</td><td>isabella.carter@example.com</td><td>234-567-8901</td><td>Detroit</td><td>USA</td><td>Entrepreneur</td><td>$200,000</td></tr><tr><td>Logan</td><td>Green</td><td>31</td><td>258 Elm St</td><td>logan.green@example.com</td><td>678-901-2345</td><td>San Diego</td><td>USA</td><td>Engineer</td><td>$90,000</td></tr><tr><td>Amelia</td><td>Roberts</td><td>29</td><td>369 Cedar St</td><td>amelia.roberts@example.com</td><td>123-456-7890</td><td>Charlotte</td><td>USA</td><td>Designer</td><td>$70,000</td></tr><tr><td>Benjamin</td><td>Hill</td><td>35</td><td>741 Oakwood St</td><td>benjamin.hill@example.com</td><td>456-789-0123</td><td>San Antonio</td><td>USA</td><td>Manager</td><td>$100,000</td></tr><tr><td>Charlotte</td><td>Adams</td><td>33</td><td>852 Maple St</td><td>charlotte.adams@example.com</td><td>789-012-3456</td><td>Orlando</td><td>USA</td><td>Software Developer</td><td>$85,000</td></tr><tr><td>Gabriel</td><td>Cook</td><td>28</td><td>159 Pinecrest St</td><td>gabriel.cook@example.com</td><td>210-987-6543</td><td>Tampa</td><td>USA</td><td>Writer</td><td>$60,000</td></tr></tbody></table> </div>
table.scss
.container {max-height: 256px;overflow-y: auto;max-width: 768px;margin-inline: auto; }table {border-spacing: 0;margin-inline: auto;th,td {border: 1px solid black;}:is(th, td):nth-child(n + 2) {border-left: unset;}td {border-top: unset;}thead {tr {background-color: white;}th {padding: 16px;}}td,th {padding: 16px;min-width: 250px;max-width: 250px;} }
实现原理
监听 wheel 事件,会得到一个 WheelEvent 对象。
它里面有一个 deltaY 属性,我们 wheel 一下,这个 deltaY 会是 100 或 -100。
positive 表示 scroll down,negative 表示 scroll up。
100 是游览器设定的一下 wheel 要移动多少 scrollTop。
轻轻 wheel 一下就是 scrollTop += 100
如果快速 wheel 几下,这个 deltaY 不一定是 100,有可能是 200 甚至 300。
也就是说 wheel 的越快越多,移动的 scrollTop 越大。这是游览器的交互体验。
我们监听 wheel 然后 update scrollTop 就可以了。如果要体验好,就加入 animation,让它 smooth 一点。