鼠标和触摸水平 div 滑动
Mouse & Touch horizontal div sliding
我正在尝试为我的网站制作一项功能,允许用户使用 mousemove 和 touchmove 事件水平滚动 div 内容(类似于 Apple AppStore any app Screenshots section)。我通过为第一个 child 设置负 margin-left 属性 来做到这一点。一切正常,除了当移动设备上的用户触摸屏幕或桌面上的用户将光标移动到 parent div 时,它的内容不会从当前位置滚动,而是 "jumping"。我试图通过将当前 margin-left 值添加到新的 pageX 值来实现这一点,但它不起作用。我做错了什么?或者可能无法通过这种方式实现此功能?
JS/Babel代码:
class Collage {
constructor(selector) {
this.selector = $(selector);
this.children = this.selector.children(':first-child');
this.selector.on('mousemove touchmove', this.onMove.bind(this));
}
onMove(event) {
const marginLeft = parseFloat(this.children.css('margin-left'));
let mouseX = event.pageX || -event.touches[0].pageX || -event.changedTouches[0].pageX;
const margin = calculateMargin(mouseX, 1);
this.children.css('margin-left', margin);
function calculateMargin(value, speed) {
let val = -value*speed;
return val <= 0 ? val : 0;
}
}
}
SCSS代码:
.collage {
overflow: hidden;
max-height: 300px;
white-space: nowrap;
font-size: 0;
img {
display: inline-block;
&:first-of-type {
margin-left: -20%;
}
}
}
我的fiddle
提前感谢您的回答。
您可以通过在图像周围创建第二个包装器元素来在没有 Javascript 的情况下获得您想要的内容吗?
<div class="collage">
<div class="wrapper">
<img /> ....
</div>
</div>
然后CSS
.collage {
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
width: 100%;
display: block;
position: relative;
}
.wrapper {
width: 10000px;
/* set width to something large
or set with Javascript to the calculated width of your images */
}
我处理这个问题。通过 Matthew Levy's 的回答,我发现它可以更容易地完成。所以我将全部内容放入嵌套容器中,我的 CSS (SCSS) 代码如下所示:
.collage {
overflow: hidden;
-webkit-overflow-scrolling: touch;
width: 100%;
max-height: 300px;
font-size: 0;
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
padding: 0;
white-space: nowrap;
}
img {
display: inline-block;
&:first-of-type {
// transition prevent jumping when user move cursor into container
transition: margin .8s;
}
}
}
使用此代码,我不需要 JS 中的 touchmove 事件。所以现在我的 JS 代码如下所示(顺便说一句,我针对最后一个代码优化了这段代码):
class Collage {
constructor(selector) {
this.selector = $(selector);
this.child = this.selector.children();
const offsetHeight = this.child[0].offsetHeight;
const clientHeight = this.child[0].clientHeight;
// hide scrollbar - it can be done with CSS but in various browsers scrollbar may has various size so using JS to deal with this is safier
this.selector.css('margin-top', -(offsetHeight - clientHeight));
this.child.css('margin-top', offsetHeight - clientHeight);
this.child.on('mousemove', this.onMove.bind(this));
this.mouseX = 0;
this.marginLeft = 0;
this.selectorWidth = this.selector.width();
this.selectorLeft = this.selector.position().left;
}
onMove(event) {
// calculate new margin value in percentages
const calculateMargin = () => parseInt((100 * (this.mouseX - this.selectorLeft)) / this.selectorWidth);
this.mouseX = event.pageX;
// limit a new value between 0/100%
this.marginLeft += (Math.min(Math.max(calculateMargin(), 0), 100) - this.marginLeft);
this.child.children(':first-child').css('margin-left', `-${this.marginLeft}%`);
}
}
工作fiddle
我正在尝试为我的网站制作一项功能,允许用户使用 mousemove 和 touchmove 事件水平滚动 div 内容(类似于 Apple AppStore any app Screenshots section)。我通过为第一个 child 设置负 margin-left 属性 来做到这一点。一切正常,除了当移动设备上的用户触摸屏幕或桌面上的用户将光标移动到 parent div 时,它的内容不会从当前位置滚动,而是 "jumping"。我试图通过将当前 margin-left 值添加到新的 pageX 值来实现这一点,但它不起作用。我做错了什么?或者可能无法通过这种方式实现此功能?
JS/Babel代码:
class Collage {
constructor(selector) {
this.selector = $(selector);
this.children = this.selector.children(':first-child');
this.selector.on('mousemove touchmove', this.onMove.bind(this));
}
onMove(event) {
const marginLeft = parseFloat(this.children.css('margin-left'));
let mouseX = event.pageX || -event.touches[0].pageX || -event.changedTouches[0].pageX;
const margin = calculateMargin(mouseX, 1);
this.children.css('margin-left', margin);
function calculateMargin(value, speed) {
let val = -value*speed;
return val <= 0 ? val : 0;
}
}
}
SCSS代码:
.collage {
overflow: hidden;
max-height: 300px;
white-space: nowrap;
font-size: 0;
img {
display: inline-block;
&:first-of-type {
margin-left: -20%;
}
}
}
我的fiddle
提前感谢您的回答。
您可以通过在图像周围创建第二个包装器元素来在没有 Javascript 的情况下获得您想要的内容吗?
<div class="collage">
<div class="wrapper">
<img /> ....
</div>
</div>
然后CSS
.collage {
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
width: 100%;
display: block;
position: relative;
}
.wrapper {
width: 10000px;
/* set width to something large
or set with Javascript to the calculated width of your images */
}
我处理这个问题。通过 Matthew Levy's 的回答,我发现它可以更容易地完成。所以我将全部内容放入嵌套容器中,我的 CSS (SCSS) 代码如下所示:
.collage {
overflow: hidden;
-webkit-overflow-scrolling: touch;
width: 100%;
max-height: 300px;
font-size: 0;
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
padding: 0;
white-space: nowrap;
}
img {
display: inline-block;
&:first-of-type {
// transition prevent jumping when user move cursor into container
transition: margin .8s;
}
}
}
使用此代码,我不需要 JS 中的 touchmove 事件。所以现在我的 JS 代码如下所示(顺便说一句,我针对最后一个代码优化了这段代码):
class Collage {
constructor(selector) {
this.selector = $(selector);
this.child = this.selector.children();
const offsetHeight = this.child[0].offsetHeight;
const clientHeight = this.child[0].clientHeight;
// hide scrollbar - it can be done with CSS but in various browsers scrollbar may has various size so using JS to deal with this is safier
this.selector.css('margin-top', -(offsetHeight - clientHeight));
this.child.css('margin-top', offsetHeight - clientHeight);
this.child.on('mousemove', this.onMove.bind(this));
this.mouseX = 0;
this.marginLeft = 0;
this.selectorWidth = this.selector.width();
this.selectorLeft = this.selector.position().left;
}
onMove(event) {
// calculate new margin value in percentages
const calculateMargin = () => parseInt((100 * (this.mouseX - this.selectorLeft)) / this.selectorWidth);
this.mouseX = event.pageX;
// limit a new value between 0/100%
this.marginLeft += (Math.min(Math.max(calculateMargin(), 0), 100) - this.marginLeft);
this.child.children(':first-child').css('margin-left', `-${this.marginLeft}%`);
}
}
工作fiddle