<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>picker</title> <style type="text/css"> * {margin: 0;padding: 0;} .picker {position: fixed;bottom: 0;left: 0;box-shadow: 0 0 10px 2px #eee;right: 0;height: 250px; overflow: hidden;border: 20px solid #fff;border-left: 0;border-right: 0;} .picker-box {transform: translate3d(0, 0, 0);position: absolute;top: 100px;left: 0;right: 0;height: auto;} .picker-box > div {height: 50px;line-height: 50px;text-align: center;} .picker-indicator {width: 100%;height: 50px;position: absolute;top: 50%;left: 0; transform: translateY(-50%);} .picker-indicator::before {content: '';position: absolute;top: 0;left: 50%;width: 90%;height: 1px; background-color: #ccc;transform: scaleY(0.5) translateX(-50%);} .picker-indicator::after {content: '';position: absolute;bottom: 0;left: 50%;width: 90%;height: 1px; background-color: #ccc;transform: scaleY(0.5) translateX(-50%);} .picker-mask {position: absolute;top: 50%;left: 0;right: 0;height: 250px; transform: translateY(-50%);background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6)), linear-gradient(0deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, .6)); background-repeat: no-repeat;background-position: top, bottom;background-size: 100% 100px;z-index: 3;} </style> </head> <body> <div id="app"> <div class="picker"> <div class="picker-mask"></div> <div class="picker-indicator"></div> <div class="picker-box"></div> </div> </div> </body> <script type="text/javascript"> window.onload = function() { const words = ['长城', '故宫', '西湖', '西施', '南瓜', '冬瓜', '西瓜', '西瓜', '西瓜', '西瓜']; const picker_mask = document.querySelector(".picker-mask"); const picker_box = document.querySelector(".picker-box"); for (let i = 0; i < words.length; i++) { let divDom = document.createElement('div'); divDom.innerHTML = words[i]; picker_box.appendChild(divDom); } const box_div = document.querySelector('.picker-box > div'); const lineHeight = box_div.offsetHeight; //每行的高度 let targetY = 0; let startY = 0; let moveY = 0; picker_mask.addEventListener("touchstart", function(e) { e = e || window.event; startY = e.changedTouches[0].clientY; }); picker_mask.addEventListener("touchmove", function(e) { e = e || window.event; moveY = e.changedTouches[0].clientY - startY; targetY += moveY; startY = e.changedTouches[0].clientY; picker_box.style.transform = "translate3d(0, " + targetY + "px, 0)"; }); picker_mask.addEventListener("touchend", function(e) { e = e || window.event; picker_box.style.transition = 'transform .3s ease'; if (targetY >= 0) { targetY = 0; } else if (targetY <= -(words.length - 1) * lineHeight) { targetY = -(words.length - 1) * lineHeight; } else { targetY = myRound(targetY, lineHeight) * lineHeight; } picker_box.style.transform = "translate3d(0, " + targetY + "px, 0)"; picker_box.addEventListener('transitionend', removeTrans); }); function removeTrans() { picker_box.style.transition = ''; picker_box.removeEventListener('transitionend', removeTrans); } function myRound(x, y) { x = -x; const ret = x / y - parseInt(x / y); if (ret > 0.3) { return -(parseInt(x / y) + 1); } else { return -parseInt(x / y); } } } </script> </html>