在过去的几周里,Google为Stack Overflow
结果展示了一个旋转木马,它非常棒,移动平稳但对我来说很奇怪,没有JavaScript
DOM
更改,甚至{{1}这导致水平滚动,我找不到它。
即使我读到了CSS Horizontal Scroll
,但它是如此不同,它只适用于CSS
在其他浏览器中它不存在。
经过一些搜索和实验,我发现这个奇怪的旋转木马实际上是一个带有Google Chrome
滚动条的长水平分割,但是如何用display: none
和移动鼠标指针,分割滚动移动?这是一个原生的铬技巧?或者只是使用grab
来计算水平滚动的动作?
答案 0 :(得分:1)
实际上,我已经找到了问题的答案,但是我决定现在将其发布在这里。 Google网站开发人员使用许多性感技巧来实现UI,而该轮播就是其中之一,当然,这不是DOM
操纵,它是一个简单的滚动分区。因此,分割运动非常平稳,即使拖动正确也是如此。
在某些设备(例如Apple设备或其他触摸设备)中,滚动具有某些本机行为,即使Microsoft新型笔记本电脑也具有一些通过触摸滚动的功能。但是,如果我们使用一些JavaScript
代码来处理拖动,那就很好了,请参见以下代码:
提示:您可以使用本机设备水平滚动功能,例如MacBook触控板上的两指水平滚动或,只需单击并拖动即可移动转盘水平
var slider = document.querySelector('.items');
var isDown = false;
var startX;
var scrollLeft;
slider.addEventListener('mousedown', function (e) {
isDown = true;
slider.classList.add('active');
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', function () {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', function () {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mousemove', function (e) {
if (!isDown) return;
e.preventDefault();
var x = e.pageX - slider.offsetLeft;
var walk = (x - startX) * 3; //scroll-fast
slider.scrollLeft = scrollLeft - walk;
});
@import url(https://fonts.googleapis.com/css?family=Rubik);
body,
html {
color: #fff;
text-align: center;
background: #efefef;
font-family: Helvetica, sans-serif;
margin: 0;
}
.grid-container {
background: #efefef;
font-family: 'Rubik', sans-serif;
}
@supports (display: grid) {
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas: "header header header" "title title footer" "main main main";
}
@media screen and (max-width: 500px) {
.grid-container {
grid-template-columns: 1fr;
grid-template-rows: 0.3fr 1fr auto 1fr;
grid-template-areas: "header" "title" "main" "footer";
}
}
.grid-item {
color: #fff;
background: skyblue;
padding: 3.5em 1em;
font-size: 1em;
font-weight: 700;
}
.header {
background-color: #092a37;
grid-area: header;
padding: 1em;
}
.title {
color: #555;
background-color: #f4fbfd;
grid-area: title;
}
.main {
color: #959595;
background-color: white;
grid-area: main;
padding: 0;
overflow-x: scroll;
overflow-y: hidden;
}
.footer {
background-color: #5bbce4;
grid-area: footer;
padding: 0.6em;
}
.items {
position: relative;
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
transition: all 0.2s;
transform: scale(0.98);
will-change: transform;
user-select: none;
cursor: pointer;
}
.items.active {
background: rgba(255, 255, 255, 0.3);
cursor: grabbing;
cursor: -webkit-grabbing;
transform: scale(1);
}
.item {
display: inline-block;
background: skyblue;
min-height: 100px;
min-width: 400px;
margin: 2em 1em;
}
@media screen and (max-width: 500px) {
.item {
min-height: 100px;
min-width: 200px;
}
}
}
a {
display: block;
color: #c9e9f6;
text-decoration: underline;
margin: 1em auto;
}
a:hover {
cursor: pointer;
}
p {
text-align: left;
text-indent: 20px;
font-weight: 100;
}
i {
color: skyblue;
}
<div class="grid-container">
<main class="grid-item main">
<div class="items">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
<div class="item item7"></div>
<div class="item item8"></div>
<div class="item item9"></div>
<div class="item item10"></div>
</div>
</main>
</div>
答案 1 :(得分:0)
对于 ReactJs 开发人员,我创建了一个很好的钩子来支持桌面水平滚动:
import { useEffect } from 'react';
import type { MutableRefObject } from 'react';
const useHorizontalScroll = (
scrollWrapperRef: MutableRefObject<HTMLElement>,
scrollSpeed = 1
): void => {
useEffect(() => {
const horizWrapper = scrollWrapperRef.current;
let isDown = false;
let startX: number;
let scrollLeft: number;
horizWrapper?.addEventListener('mousedown', (e: any) => {
isDown = true;
startX = e.pageX - horizWrapper?.offsetLeft;
scrollLeft = horizWrapper?.scrollLeft;
});
horizWrapper?.addEventListener('mouseleave', () => {
isDown = false;
});
horizWrapper?.addEventListener('mouseup', () => {
isDown = false;
});
horizWrapper?.addEventListener('mousemove', (e: any) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - horizWrapper?.offsetLeft;
const walk = (x - startX) * scrollSpeed;
horizWrapper.scrollLeft = scrollLeft - walk;
});
}, [scrollSpeed, scrollWrapperRef]);
};
export default useHorizontalScroll;