![](/img/trans.png)
[英]Scroll the page vertically and scroll big image inside div horizontally on mouse drag with jQuery
[英]Scroll the page on drag with jQuery
我曾嘗試使用 kinetic.js 和下面的代碼,但是當我在 IE11 中嘗試此操作時,每次滾動時它都會跳到頂部:
$("html").kinetic();
我想讓頁面在平板電腦和 IE10 和 11 上可滾動,這樣用戶就可以像在移動設備上一樣向上推動頁面向下滾動。
我怎樣才能在純 JS 或 jQuery 中做到這一點而不跳到頂部?
您可以通過記錄單擊時鼠標的位置以及拖動時的當前位置來非常簡單地做到這一點。 嘗試這個:
var clicked = false, clickY;
$(document).on({
'mousemove': function(e) {
clicked && updateScrollPos(e);
},
'mousedown': function(e) {
clicked = true;
clickY = e.pageY;
},
'mouseup': function() {
clicked = false;
$('html').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$('html').css('cursor', 'row-resize');
$(window).scrollTop($(window).scrollTop() + (clickY - e.pageY));
}
要防止在拖動時選擇文本,請添加以下 CSS:
body {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
更新
這是上面作為 jQuery 插件的版本,擴展為允許通過設置進行垂直和水平滾動。 它還允許您更改也使用的cursor
。
(function($) { $.dragScroll = function(options) { var settings = $.extend({ scrollVertical: true, scrollHorizontal: true, cursor: null }, options); var clicked = false, clickY, clickX; var getCursor = function() { if (settings.cursor) return settings.cursor; if (settings.scrollVertical && settings.scrollHorizontal) return 'move'; if (settings.scrollVertical) return 'row-resize'; if (settings.scrollHorizontal) return 'col-resize'; } var updateScrollPos = function(e, el) { $('html').css('cursor', getCursor()); var $el = $(el); settings.scrollVertical && $el.scrollTop($el.scrollTop() + (clickY - e.pageY)); settings.scrollHorizontal && $el.scrollLeft($el.scrollLeft() + (clickX - e.pageX)); } $(document).on({ 'mousemove': function(e) { clicked && updateScrollPos(e, this); }, 'mousedown': function(e) { clicked = true; clickY = e.pageY; clickX = e.pageX; }, 'mouseup': function() { clicked = false; $('html').css('cursor', 'auto'); } }); } }(jQuery)) $.dragScroll();
/* Note: CSS is not relevant to the solution. This is only needed for this demonstration */ body, html { padding: 0; margin: 0; } div { height: 1000px; width: 2000px; border-bottom: 3px dashed #EEE; /* gradient is only to make the scroll movement more obvious */ background: rgba(201, 2, 2, 1); background: -moz-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%); background: -webkit-gradient(left top, right bottom, color-stop(0%, rgba(201, 2, 2, 1)), color-stop(16%, rgba(204, 0, 204, 1)), color-stop(31%, rgba(94, 0, 201, 1)), color-stop(43%, rgba(0, 153, 199, 1)), color-stop(56%, rgba(0, 199, 119, 1)), color-stop(69%, rgba(136, 199, 0, 1)), color-stop(83%, rgba(199, 133, 0, 1)), color-stop(100%, rgba(107, 0, 0, 1))); background: -webkit-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%); background: -o-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%); background: -ms-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%); background: linear-gradient(-110deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%); filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#c90202', endColorstr='#6b0000', GradientType=1); color: #EEE; padding: 20px; font-size: 2em; } body { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div>First...</div> <div>Second...</div>
我只是想補充。 使用 Rory 的代碼,我進行了水平滾動。
var clicked = false, base = 0;
$('#someDiv').on({
mousemove: function(e) {
clicked && function(xAxis) {
var _this = $(this);
if(base > xAxis) {
base = xAxis;
_this.css('margin-left', '-=1px');
}
if(base < xAxis) {
base = xAxis;
_this.css('margin-left', '+=1px');
}
}.call($(this), e.pageX);
},
mousedown: function(e) {
clicked = true;
base = e.pageX;
},
mouseup: function(e) {
clicked = false;
base = 0;
}
});
此代碼適用於水平和垂直鼠標拖動滾動。 這很簡單。
var curYPos = 0,
curXPos = 0,
curDown = false;
window.addEventListener('mousemove', function(e){
if(curDown === true){
window.scrollTo(document.body.scrollLeft + (curXPos - e.pageX), document.body.scrollTop + (curYPos - e.pageY));
}
});
window.addEventListener('mousedown', function(e){ curDown = true; curYPos = e.pageY; curXPos = e.pageX; });
window.addEventListener('mouseup', function(e){ curDown = false; });
基於 Rory McCrossan 的想法,使用 AngularJS2 實現。
import {Directive, ElementRef, OnDestroy, Input} from "@angular/core";
declare var jQuery: any;
@Directive({
selector: '[appDragScroll]'
})
export class DragScrollDirective implements OnDestroy {
@Input() scrollVertical: boolean = true;
@Input() scrollHorizontal: boolean = true;
private dragging = false;
private originalMousePositionX: number;
private originalMousePositionY: number;
private originalScrollLeft: number;
private originalScrollTop: number;
constructor(private nodeRef: ElementRef) {
let self = this;
jQuery(document).on({
"mousemove": function (e) {
self.dragging && self.updateScrollPos(e);
},
"mousedown": function (e) {
self.originalMousePositionX = e.pageX;
self.originalMousePositionY = e.pageY;
self.originalScrollLeft = jQuery(self.nodeRef.nativeElement).scrollLeft();
self.originalScrollTop = jQuery(self.nodeRef.nativeElement).scrollTop();
self.dragging = true;
},
"mouseup": function (e) {
jQuery('html').css('cursor', 'auto');
self.dragging = false;
}
});
}
ngOnDestroy(): void {
jQuery(document).off("mousemove");
jQuery(document).off("mousedown");
jQuery(document).off("mouseup");
}
private updateScrollPos(e) {
jQuery('html').css('cursor', this.getCursor());
let $el = jQuery(this.nodeRef.nativeElement);
if (this.scrollHorizontal) {
$el.scrollLeft(this.originalScrollLeft + (this.originalMousePositionX - e.pageX));
}
if (this.scrollVertical) {
$el.scrollTop(this.originalScrollTop + (this.originalMousePositionY - e.pageY));
}
}
private getCursor() {
if (this.scrollVertical && this.scrollHorizontal) return 'move';
if (this.scrollVertical) return 'row-resize';
if (this.scrollHorizontal) return 'col-resize';
}
}
基於第一個答案,這是鼠標拖動水平滾動的代碼:
var clicked = false, clickX;
$(document).on({
'mousemove': function(e) {
clicked && updateScrollPos(e);
},
'mousedown': function(e) {
e.preventDefault();
clicked = true;
clickX = e.pageX;
},
'mouseup': function() {
clicked = false;
$('html').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$('html').css('cursor', 'grabbing');
$(window).scrollLeft($(window).scrollLeft() + (clickX - e.pageX));
}
我對 Rory 的代碼進行了相當多的修改,並讓每個元素的側滾動功能正常工作。 對於在 web 應用程序的單個視圖中有多個可滾動磁貼的項目,我需要它。 將.drag
類添加到任何元素,可能做一些樣式,應該很好。
// jQuery sidescroll code. Can easily be modified for vertical scrolling as well.
// This code was hacked together so clean it up if you use it in prod.
// Written by Josh Moore
// Thanks to Rory McCrossan for a good starting point
// How far away the mouse should move on a drag before interrupting click
// events (your own code must also interrupt regular click events with a
// method that calls getAllowClick())
const THRESHOLD = 32;
var clicked = false;
var allowClick = true;
// mouseX: most recent mouse position. updates when mouse moves.
// el: jQuery element that will be scrolled.
// thX: "threshold X", where the mouse was at the beginning of the drag
var mouseX, startY, el, thX;
// Add the .drag class to any element that should be scrollable.
// You may need to also add these CSS rules:
// overflow: hidden; /* can be replaced with overflow-x or overflow-y */
// whitespace: none;
function drag() {
$('.drag').on({
'mousemove': e => {
if (el != null && clicked) {
el.scrollLeft(el.scrollLeft() + (mouseX - e.pageX));
mouseX = e.pageX;
allowClick = Math.abs(thX - mouseX) > THRESHOLD ? false : true;
}
},
'mousedown': e => {
clicked = true;
// This lets the user click child elements of the scrollable.
// Without it, you must click the .drag element directly to be able to scroll.
el = $(e.target).closest('.drag');
mouseX = e.pageX;
thX = e.pageX;
},
'mouseup': e => {
clicked = false;
el = null;
allowClick = true;
}
});
}
function getAllowClick() {
return allowClick;
}
同樣,我沒有使用垂直滾動,但添加起來非常簡單(用 Y 替換 X、 scrollTop()
而不是scrollLeft()
等)。 希望這對將來的人有所幫助!
下面是一個基於單個元素類的簡單滾動解決方案
var cursordown = false;
var cursorypos = 0;
var cursorxpos = 0;
$('.cursorgrab').mousedown(function(e){
cursordown = true;
cursorxpos = $(this).scrollLeft() + e.clientX;
cursorypos = $(this).scrollTop() +e.clientY;
}).mousemove(function(e){
if(!cursordown) return;
try { $(this).scrollLeft(cursorxpos - e.clientX); } catch(e) { }
try { $(this).scrollTop(cursorypos - e.clientY); } catch(e) { }
}).mouseup(end = function(e){
cursordown = false;
}).mouseleave(end)
.css('user-select', 'none')
.css('cursor', 'grab');
完全驗證水平和垂直滾動
您只需將.cursorgrab類設置到您的元素中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.