如何使 div 对角滚动?常规滚动会向上/向下或向左/向右,但我想让 div 向上和向右或向下和向左滚动。
3 回答
编辑:根据 OP 的要求,我更新了示例代码以引入一个校正因子,需要更改对角线移动方向和度数。
如果你想使用 jQuery,你必须下载MouseWheel插件。
然后,您可以编写一个简单的函数绑定到mousewheel
事件,例如:
HTML
<div id="block"></div>
CSS
#block {
position: absolute;
width: 200px;
height: 150px;
top: 200px;
left: 50px;
background-color: red;
}
备选方案1:JS使用CSS top and left
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// retrieves the top and left coordinates
top = parseInt($block.css('top')),
left = parseInt($block.css('left')),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
offset = -1 * delta,
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 5,
factorY = 2,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = top + Math.floor(offset * factorY),
newLeft = left - Math.floor(offset * factorX);
// moves the block
$block.css({
top: newTop + 'px',
left: newLeft + 'px'
});
});
});
备选方案 2:JS 使用 offset()
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// retrieves the top and left coordinates
position = $block.offset(),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
offset = -1 * delta,
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 5,
factorY = 2,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = position.top + Math.floor(offset * factorY),
newLeft = position.left - Math.floor(offset * factorX);
// moves the block
$block.offset({ top: newTop, left: newLeft });
});
});
现在您可以通过向上滚动来上下移动框,反之亦然通过向下滚动。在此示例中,对于每个mousewheel
事件,回调函数:
- 检索当前元素位置(
top
和left
CSS 属性) - 反转事件返回的增量值
mousewheel
,因此向上滚动我们有一个负增量,向下滚动我们有一个正增量 - 设置定义对角线移动方向和度数所需的因子值
- 计算新位置
- 移动对象。
要更改度数和方向,只需更改factorX
和/或factorY
值,以便:
- 负值反转方向,并且
- 不同的值会改变度数(例如,相对于 X = 5 和 Y = 2,X = 2 和 Y = 5 使元素以更闭合的角度移动)。
这是一个您可以测试的演示。
备选方案 3:JS 使用 cos() 和 sin()
$(function(){
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
// read current block position
position = $block.offset(),
// inverts the delta; scroll up == -1 - scroll down == +1
direction = -1 * delta,
// sets the angle and converts it in radians
angle = 45 * Math.PI / 180,
// set displacememt factor
factorX = Math.cos(angle) * direction,
factorY = Math.sin(angle) * direction,
// calculate the new position
newTop = position.top + factorY,
newLeft = position.left - factorX;
// moves the block
$block.offset({ top: newTop, left: newLeft });
});
});
在本例中,要更改的是angle
(本例中为 45)中的值。其他一切都像其他示例一样工作。
最后一件事,如果需要改变运动的速度,只需乘以factorX
和/或乘以factorY
所需的系数(例如,1.5 表示速度的一倍半,或 2 表示两倍的速度,等等)。
可以在演示中尝试。
编辑
只是为了知识,您可以使用CSS Transform达到相同的目标。这使您可以利用 GPU 加速硬件。(更多信息可以在Smashing Magazine和Paul Irish的文章中找到)。
HTML
<div id="block"></div>
CSS
#block {
width: 200px;
height: 150px;
background-color: red;
transform: translate3d(0, 0, 0);
}
JS
$(function(){
var blockOffsetX = 50,
blockOffsetY = 200;
$('#block').css({
transform: 'translate3d(' + blockOffsetX + 'px' + ', ' + blockOffsetY + 'px, 0)'
});
$(window).on('mousewheel', function(evt,delta){
var $block = $('#block'),
offset = -1 * delta;
factorX = 5,
factorY = 2;
blockOffsetX -= offset * factorX;
blockOffsetY += offset * factorY;
$block.css({
transform: 'translate3d(' + blockOffsetX + 'px, ' + blockOffsetY + 'px, 0)'
});
});
});
但是,正如您在本示例中所见,您需要跟踪元素 X、Y 的位置,因为直接从 CSS 中检索这些值有点复杂。此外,这个例子更简单,但在生产中,您必须支持每个供应商特定的 CSS 属性(-webkit-
、-moz-
、-o-
、-ms-
等)。
这是一个工作演示(如果它不起作用,您可能必须根据浏览器的特定前缀 CSS 属性编辑代码)。
编辑:由于 OP 已经看到监听scroll
事件对他来说是更好的选择,所以我添加了相关代码(这里只报告了 JS 代码,因为 HTML 和 CSS 与第一个示例几乎相同):
$(function(){
var lastScrollYPos = 0;
$(window).on('scroll', function(){
var $this = $(this),
$block = $('#block'),
// retrieves the top and left coordinates
position = $block.offset(),
// X and Y factors allows to change the diagonal movement direction and
// degree. Negative values inverts the direction.
factorX = 1,
factorY = 1,
// retrieves current vertical scrolling position and calculate the
// relative offset
scrollYPos = $this.scrollTop(),
offset = Math.abs(scrollYPos - lastScrollYPos),
// mouse wheel delta is inverted respect to the direction, so we need to
// normalize it against the direction
direction = scrollYPos > lastScrollYPos ? -1 : 1,
// calculates the new position. NOTE: if integers only are used for factors,
// then `Math.floor()` isn't required.
newTop = position.top + Math.floor(direction * offset * factorY),
newLeft = position.left - Math.floor(direction * offset * factorX);
// moves the block
$block.offset({ top: newTop, left: newLeft });
lastScrollYPos = scrollYPos;
});
});
这是一个工作演示。
奖金:想法
代替对每个元素使用公共局部变量,HTML5data-*
属性可以用来存储元素的数据(例如:校正因子、最后位置等),然后.data()
可以使用 jQuery 方法检索这些数据并处理它们。
亲:
- 将回调函数与元素解耦
- 自定义页面上的每个元素以彼此不同
缺点:
- 它可能会以某种方式影响渲染性能,尤其是是否必须通过回调函数同时管理许多元素。
您可以使用 onScroll 事件,检测用户是垂直滚动还是水平滚动,然后适当地滚动另一个方向。
例子:
JS
var lastScrollTop = 0;
$("#diagonalscroller").scroll(function(e) {
var scrollTop = $(this).scrollTop();
if (scrollTop === lastScrollTop) {
// Vertical scroll position is unchanged, so we're scrolling horizontal.
$(this).scrollTop($(this).scrollLeft());
} else {
// Vertical scroll position has changed, so we're scrolling vertical.
$(this).scrollLeft($(this).scrollTop());
}
lastScrollTop = scrollTop;
});
HTML
<h1>Try scrolling using the scrollbars</h1>
<div id="diagonalscroller">
<img src="http://dummyimage.com/800/" />
</div>
CSS
#diagonalscroller {
width: 200px;
height: 200px;
overflow: scroll;
}
观看演示。
老问题..但是遇到过这个问题的人可能会喜欢
这是对角线网页布局的概念。
在这里发布的代码太大了,它可能比 OP 要求的要多。
必须如此发布代码。这是发挥魔力的部分。(使用 Modernizr 进行跨浏览器支持)
var $window = $(window);
var con = $('#content');
$window.on('touchmove scroll', function() {
var winScroll = $window.scrollTop() * -1;
if (!Modernizr.csstransforms3d && Modernizr.csstransforms) {
con.css({
transform: 'translate(' + winScroll + 'px,' + winScroll + 'px)'
});
} else if (Modernizr.csstransforms3d) {
con.css({
transform: 'translate3d(' + winScroll + 'px,' + winScroll + 'px,0)'
});
} else {
con.css({
left: winScroll,
top: winScroll
});
}
});