Sha*_*ter 51 jquery events scrollbar
我正在尝试在JQuery中创建自定义事件,以便在单击滚动条时检测到1.
我知道有很多文字,但我的所有问题都是粗体,并且有一个JSFiddle示例,您可以立即处理.
因为我还没有找到任何内置功能,所以
我必须创建一个hasScroll函数,检查元素是否有滚动条,
$.fn.hasScroll = function(axis){
var overflow = this.css("overflow"),
overflowAxis;
if(typeof axis == "undefined" || axis == "y") overflowAxis = this.css("overflow-y");
else overflowAxis = this.css("overflow-x");
var bShouldScroll = this.get(0).scrollHeight > this.innerHeight();
var bAllowedScroll = (overflow == "auto" || overflow == "visible") ||
(overflowAxis == "auto" || overflowAxis == "visible");
var bOverrideScroll = overflow == "scroll" || overflowAxis == "scroll";
return (bShouldScroll && bAllowedScroll) || bOverrideScroll;
};
Run Code Online (Sandbox Code Playgroud)
和一个inScrollRange函数,检查执行的点击是否在滚动范围内.
var scrollSize = 18;
function inScrollRange(event){
var x = event.pageX,
y = event.pageY,
e = $(event.target),
hasY = e.hasScroll(),
hasX = e.hasScroll("x"),
rX = null,
rY = null,
bInX = false,
bInY = false
if(hasY){
rY = new RECT();
rY.top = e.offset().top;
rY.right = e.offset().left + e.width();
rY.bottom = rY.top +e.height();
rY.left = rY.right - scrollSize;
//if(hasX) rY.bottom -= scrollSize;
bInY = inRect(rY, x, y);
}
if(hasX){
rX = new RECT();
rX.bottom = e.offset().top + e.height();
rX.left = e.offset().left;
rX.top = rX.bottom - scrollSize;
rX.right = rX.left + e.width();
//if(hasY) rX.right -= scrollSize;
bInX = inRect(rX, x, y);
}
return bInX || bInY;
}
Run Code Online (Sandbox Code Playgroud)
所有滚动条尺寸均匀吗?例如在Firefox和IE中它是18px.
假设没有自定义滚动条,在某些浏览器中是否有任何额外的填充或大小?
这些功能都按预期执行(从我能辨别的内容).
制作自定义事件有点棘手,但我有点工作.唯一的问题是,如果点击的元素附加了mousedown/up事件,那么它也会被触发.
我似乎无法阻止其他事件触发,同时触发,我称之为mousedownScroll/mouseupScroll事件.
$.fn.mousedownScroll = function(fn, data){
if(typeof fn == "undefined" && typeof data == "undefined"){
$(this).trigger("mousedownScroll");
return;
}
$(this).on("mousedownScroll", data, fn);
};
$.fn.mouseupScroll = function(fn, data){
if(typeof fn == "undefined" && typeof data == "undefined"){
$(this).trigger("mouseupScroll");
return;
}
$(this).on("mouseupScroll", data, fn);
};
$(document).on("mousedown", function(e){
if(inScrollRange(e)){
$(e.target).trigger("mousedownScroll");
}
});
$(document).on("mouseup", function(e){
if(inScrollRange(e)){
$(e.target).trigger("mouseupScroll");
}
});
$("selector").mousedown(function(e){
console.log("Clicked content."); //Fired when clicking scroller as well
});
$("selector").mousedownScroll(function(e){
console.log("Clicked scroller.");
});
Run Code Online (Sandbox Code Playgroud)
如何阻止其他"点击"事件触发?
在我问的时候,请尽可能地优化代码.
我之所以这样做是因为我正在开发一个更大的插件.当我右键单击其中一个滚动条时,它会显示一个自定义上下文菜单.我不希望这样.所以我认为我应该创建一个检查滚动点击(mouseup/downs)的事件,然后阻止显示上下文菜单.为了做到这一点,我需要在正常点击之前滚动点击,并且如果可能的话,还要停止点击正常点击.
我只是在这里大声思考,但也许有办法获得绑定到元素的所有函数,然后切换它们被添加的顺序?我知道函数按照它们被添加的顺序执行(第一次添加第一个调用),因此,如果我可以进入该过程,也许可以在点击事件之前插入事件到JQuery的整个"注册".
1只能使用mousedown/mouseup,因为单击滚动条时不会触发click.如果这是错误的,请提供一个工作示例/代码
Dar*_*ski 24
我可以提出最短的滚动条点击检测,在IE,Firefox,Chrome上进行测试.
var clickedOnScrollbar = function(mouseX){
if( $(window).outerWidth() <= mouseX ){
return true;
}
}
$(document).mousedown(function(e){
if( clickedOnScrollbar(e.clientX) ){
alert("clicked on scrollbar");
}
});
Run Code Online (Sandbox Code Playgroud)
工作示例:https: //jsfiddle.net/s6mho19z/
Ale*_*der 16
你可能会使用这个hack.
您可以尝试劫持mousedown和mouseup事件,并在使用自定义供电功能单击滚动条时避免它们.
$.fn.mousedown = function(data, fn) {
if ( fn == null ) {
fn = data;
data = null;
}
var o = fn;
fn = function(e){
if(!inScrollRange(e)) {
return o.apply(this, arguments);
}
return;
};
if ( arguments.length > 0 ) {
return this.bind( "mousedown", data, fn );
}
return this.trigger( "mousedown" );
};
Run Code Online (Sandbox Code Playgroud)
和反向mousedownScroll和mouseupScroll事件.
$.fn.mousedownScroll = function(data, fn) {
if ( fn == null ) {
fn = data;
data = null;
}
var o = fn;
fn = function(e){
if(inScrollRange(e)) {
e.type = "mousedownscroll";
return o.apply(this, arguments);
}
return;
};
if ( arguments.length > 0 ) {
return this.bind( "mousedown", data, fn );
}
return this.trigger( "mousedown" );
};
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我认为滚动条宽度是一个OS设置.
我在之前的项目中遇到了同样的问题,我推荐这个解决方案.它不是很干净,但它有效,我怀疑我们可以用html做得更好.以下是我的解决方案的两个步骤:
1.测量桌面环境中滚动条的宽度.
为了实现这一点,在应用程序启动时,您执行以下操作:
将以下元素添加到正文:
<div style='width: 50px; height: 50px; overflow: scroll'><div style='height: 1px;'/></div>
使用jQUery的.width()测量先前添加的元素的内部div的with,并将滚动条的宽度存储在某处(scollbar的宽度为50 - 内部div的宽度)
删除用于测量滚动条的额外元素(现在您已获得结果,删除添加到主体的元素).
用户不应看到所有这些步骤,并且您的操作系统上有滚动条的宽度
例如,您可以使用此代码段:
var measureScrollBarWidth = function() {
var scrollBarMeasure = $('<div />');
$('body').append(scrollBarMeasure);
scrollBarMeasure.width(50).height(50)
.css({
overflow: 'scroll',
visibility: 'hidden',
position: 'absolute'
});
var scrollBarMeasureContent = $('<div />').height(1);
scrollBarMeasure.append(scrollBarMeasureContent);
var insideWidth = scrollBarMeasureContent.width();
var outsideWitdh = scrollBarMeasure.width();
scrollBarMeasure.remove();
return outsideWitdh - insideWidth;
};
Run Code Online (Sandbox Code Playgroud)
2.检查滚动条上是否有单击.
现在您已经拥有了滚动条的宽度,您可以使用事件的坐标来计算相对于滚动条的位置矩形的事件坐标,并执行令人敬畏的事情......
如果要过滤点击次数,可以在处理程序中返回false以防止其传播.
这里有很多答案涉及event.clientX,element.clientHeight等等,它们都是错误的。不要使用它们。
overflow: scroll滚动条显示为覆盖层,或者您可能使用 强制它overflow: overlay。你需要看看event.target。如有必要,请使用占据滚动元素所有客户区域的内部元素,并查看是否 event.target是该元素或其后代。
确保你的scollarea的内容完全[over]填充父div.
然后,您可以区分内容点击次数和容器点击次数.
HTML:
<div class='test container'><div class='test content'></div></div>
<div id="results">please click</div>
Run Code Online (Sandbox Code Playgroud)
CSS:
#results {
position: absolute;
top: 110px;
left: 10px;
}
.test {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: green;
}
.container {
overflow: scroll;
}
.content {
background-color: red;
}
Run Code Online (Sandbox Code Playgroud)
JS:
function log( _l ) {
$("#results").html( _l );
}
$('.content').on( 'mousedown', function( e ) {
log( "content-click" );
e.stopPropagation();
});
$('.container').on( 'mousedown', function( e ) {
var pageX = e.pageX;
var pageY = e.pageY;
log( "scrollbar-click" );
});
Run Code Online (Sandbox Code Playgroud)
http://codepen.io/jedierikb/pen/JqaCb
使用以下解决方案来检测用户是否在元素的滚动条上单击了鼠标。没有测试它如何与窗口的滚动条一起工作。我猜想Pete的解决方案与窗口滚动效果更好。
window.addEventListener("mousedown", onMouseDown);
function onMouseDown(e) {
if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight)
{
// mouse down over scroll element
}
}
Run Code Online (Sandbox Code Playgroud)