确定用户是否点击滚动条或内容(onclick为本机滚动条) [英] Determine whether user clicking scrollbar or content (onclick for native scroll bar)

查看:144
本文介绍了确定用户是否点击滚动条或内容(onclick为本机滚动条)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在JQuery中创建自定义事件,这些事件应该是在滚动条被点击时检测。

我知道有很多文本,但是我所有的问题是大胆的,有一个 JSFiddle示例,您可以立即工作。



因为我没有找到任何内置的功能,

我不得不创建一个 hasScroll 函数,检查元素是否有一个滚动条, / p>

  $。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;
};

和一个 inScrollRange 函数,点击执行在滚动范围内。

  var scrollSize = 18; 

函数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()。
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;
}

所有滚动条大小是否均匀?例如在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。); //点击滚动条时被点击
} );

$(selector)。mousedownScroll(function(e){
console.log(Clicked croller。);
});

如何阻止其他点击事件触发? / p>

在我问的时候,请尽可能优化代码。



这是一个JSFiddle来解决。



原因我这样做是因为我正在开发一个更大的插件。当我右键单击其中一个滚动条时,它会显示一个自定义上下文菜单。我不想要所以我想我应该做一个检查滚动点击(mouseup / downs)的事件,然后阻止上下文菜单的显示。为了做到这一点,我需要滚动点击进入正常点击之前,并且如果可能的话,停止正常的点击点击。



我只是在这里大声思考,但可能有一种方法来获取绑定到元素的所有函数,然后切换添加它们的顺序?我知道这些函数按照它们被添加的顺序执行(第一次被添加到第一个调用),所以如果我可以利用这个过程,或许整个注册事件到JQuery可以在点击事件之前被插入。 / p>




1 只能使用mousedown / mouseup,因为点击时点击不会触发在滚动条上。如果这是错误的,请提供一个工作示例/代码

解决方案

您可能会使用此黑客。 p>

您可以尝试劫持 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);
};

而对于 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);
};

顺便说一句,我认为滚动条宽度是一个操作系统设置。


I'm trying to create custom events in JQuery that are supposed to detect when a scrollbar is clicked1.
I know there's lots of text, but all my questions are boldfaced and there's a JSFiddle example you can work on straight away.

Because I haven't found any built in functionality for this,
I had to create a hasScroll function, checking if the element has a scrollbar,

$.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;
};

and an inScrollRange function, checking if the click performed was within the scroll range.

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;
}

Are all scrollbar sizes uniform? E.g in Firefox and IE it's 18px.
Assuming there are no customized scrollbars, is there any extra padding or sizes in some browsers?

These functions all perform as intended (from what I can discern).

Making custom events was a bit trickier, but I got it to work somewhat. The only problem is that if the element clicked has a mousedown/up event attached to it, that will be triggered as well.

I can't seem to stop the other events from triggering while simultaneously triggering, what I call, the mousedownScroll/mouseupScroll events.

$.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.");
});

How do I stop the other "click" events from triggering?

While I'm asking, please feel free to optimize the code as much as possible.

Here's a JSFiddle to mess around with.

The reason I'm making this is because of a bigger plugin I'm developing. It's got a custom context menu that is showing up when I right click one of the scrollers. I don't want that. So I thought I should make an event that checks for scroll clicks (mouseup/downs) and then prevent the context menu from being displayed. In order to do that though, I need the scroll click to come before the normal click, and also, if possible, stop the normal clicks from firing.

I'm just thinking out loud here but maybe there's a way to get all the functions that are bound to the element and then switch the order in which they were added? I know that functions are executed in the order they were added (1st added 1st called), so, if I could tap into that process, perhaps the whole "registering" of the event to JQuery could just be inserted before the click events.


1 can only use mousedown/mouseup because click doesn't trigger when clicking on a scrollbar. If this is false, please provide a working example/code

解决方案

You may probably use this hack.

You could try hijacking the mousedown and mouseup events and avoiding them when click on a scrollbar with your custom powered function.

$.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" );
};

And the inverse for mousedownScroll and mouseupScroll events.

$.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" );
};

By the way, I think the scrollbar width is an OS setting.

这篇关于确定用户是否点击滚动条或内容(onclick为本机滚动条)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆