我试图创造,都应该当一个滚动条被点击1检测JQuery的自定义事件。
我知道有很多的文字,但我所有的问题都是粗体,有一个的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;
};
和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;
}
是否所有的滚动条大小一致的? 例如,在Firefox和IE是18像素。
假设没有出现任何定制的滚动条,有没有在某些浏览器的任何微胖或大小?
这些功能都按预期执行(从我可以看出)。
制作自定义事件是有点麻烦,但我得到了它在一定程度上工作。 唯一的问题是,如果点击的元素附加了一个鼠标按下/释放事件,这也会被触发。
我似乎无法从触发,同时触发,我所说的的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.");
});
如何阻止对方从触发“点击”事件?
当我问,请随时对代码进行优化,尽可能。
这里有一个的jsfiddle更动。
我在做这个的原因是因为一个更大的插件,我开发的。 它有被显示出来,当我右键单击滚动条的一个自定义的快捷菜单。 我不希望出现这种情况。 所以我想我应该做,对于滚动点击(鼠标松开/起伏)检查,然后阻止显示上下文菜单中的事件。 为了做到这一点,虽然,我需要滚动点击来正常点击之前,而且,如果可能的话,从射击停止正常点击。
我只是在想大声这里,但也许有一种方式来获得绑定到的元素,然后切换它们被添加的顺序将所有的功能呢? 我知道,功能都在他们加入(被称为第一次加1)的顺序执行,所以,如果我可以利用这个过程,也许整个简直单击事件之前插入该事件的jQuery“注册”。
1只能使用鼠标按下/鼠标松开,因为在滚动条时,点击点击不会触发。 如果这是假的,请提供一个工作示例/代码
Answer 1:
你或许可以使用这个技巧。
你可以尝试劫持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" );
};
顺便说一句,我觉得滚动条宽度为操作系统的设置。
Answer 2:
解决了:
的最短滚动条点击检测我能想出,在IE,火狐,Chrome测试。
var clickedOnScrollbar = function(mouseX){
if( $(window).outerWidth() <= mouseX ){
return true;
}
}
$(document).mousedown(function(e){
if( clickedOnScrollbar(e.clientX) ){
alert("clicked on scrollbar");
}
});
工作示例: https://jsfiddle.net/s6mho19z/
Answer 3:
我有同样的问题在以前的项目,我建议这个解决方案。 这不是很干净,但它的工作原理,我怀疑我们可以用HTML好得多。 这里是我的解决方案的两个步骤:
1.测量您的桌面环境中的滚动条的宽度。
为了实现这一点,在应用程序启动,请执行以下操作:
下面的元素添加到身体:
<div style='width: 50px; height: 50px; overflow: scroll'><div style='height: 1px;'/></div>
与jQuery的.WIDTH()先前添加的元件的内格的测量,并存储滚动条的宽度某处(该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;
};
2.检查的点击滚动条上。
现在,你有滚动条的宽度,可以与该事件的坐标计算事件相对于滚动条的位置矩形的坐标和perfom真棒的东西...
如果你要过滤的点击,你可以在处理程序返回false,以防止其传播。
Answer 4:
确保您的scollarea的内容完全[上]填充父DIV。
然后,您可以在容器上的内容点击和点击之间进行区分。
HTML:
<div class='test container'><div class='test content'></div></div>
<div id="results">please click</div>
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;
}
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" );
});
http://codepen.io/jedierikb/pen/JqaCb
Answer 5:
使用以下解决方案来检测,如果用户点击鼠标移到元素的滚动条。 没有测试它如何与窗口的滚动条的作品。 我想皮特的解决方案更好地工作与窗口滚动。
window.addEventListener("mousedown", onMouseDown);
function onMouseDown(e) {
if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight)
{
// mouse down over scroll element
}
}
Answer 6:
我会提出我自己的答案,并接受亚历山大的回答 ,因为它使人们很好地工作,并给予好评萨穆埃尔的答案 ,因为它正确地计算滚动条的宽度,这是我需要什么为好。
话虽这么说,我决定做的,而不是试图覆盖/覆盖JQuery的两个独立事件mousedown
事件。
这给了我,我没有必要用jQuery自己搞乱事件的灵活性,并且是很容易做到。
-
mousedownScroll
-
mousedownContent
下面是使用亚历山大的两种实现方式,和我自己。 这两个工作,我本来想他们,但前者可能是最好的。
这里有一个的jsfiddle实现亚历山大的答案+萨穆埃尔的答案。
$.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; }; $.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" ); }; $.fn.mouseup = 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( "mouseup", data, fn ); } return this.trigger( "mouseup" ); }; $.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" ); }; $.fn.mouseupScroll = function(data, fn) { if ( fn == null ) { fn = data; data = null; } var o = fn; fn = function(e){ if(inScrollRange(e)) { e.type = "mouseupscroll"; return o.apply(this, arguments); } return; }; if ( arguments.length > 0 ) { return this.bind( "mouseup", data, fn ); } return this.trigger( "mouseup" ); }; var RECT = function(){ this.top = 0; this.left = 0; this.bottom = 0; this.right = 0; } function inRect(rect, x, y){ return (y >= rect.top && y <= rect.bottom) && (x >= rect.left && x <= rect.right) } var scrollSize = measureScrollWidth(); 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; } $(document).on("mousedown", function(e){ //Determine if has scrollbar(s) if(inScrollRange(e)){ $(e.target).trigger("mousedownScroll"); } }); $(document).on("mouseup", function(e){ if(inScrollRange(e)){ $(e.target).trigger("mouseupScroll"); } }); }); function measureScrollWidth() { 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; };
这里有一个的jsfiddle什么,我决定做代替。
$.fn.hasScroll = function(axis){ var overflow = this.css("overflow"), overflowAxis, bShouldScroll, bAllowedScroll, bOverrideScroll; if(typeof axis == "undefined" || axis == "y") overflowAxis = this.css("overflow-y"); else overflowAxis = this.css("overflow-x"); bShouldScroll = this.get(0).scrollHeight > this.innerHeight(); bAllowedScroll = (overflow == "auto" || overflow == "visible") || (overflowAxis == "auto" || overflowAxis == "visible"); bOverrideScroll = overflow == "scroll" || overflowAxis == "scroll"; return (bShouldScroll && bAllowedScroll) || bOverrideScroll; }; $.fn.mousedownScroll = function(fn, data){ var ev_mds = function(e){ if(inScrollRange(e)) fn.call(data, e); } $(this).on("mousedown", ev_mds); return ev_mds; }; $.fn.mouseupScroll = function(fn, data){ var ev_mus = function(e){ if(inScrollRange(e)) fn.call(data, e); } $(this).on("mouseup", ev_mus); return ev_mus; }; $.fn.mousedownContent = function(fn, data){ var ev_mdc = function(e){ if(!inScrollRange(e)) fn.call(data, e); } $(this).on("mousedown", ev_mdc); return ev_mdc; }; $.fn.mouseupContent = function(fn, data){ var ev_muc = function(e){ if(!inScrollRange(e)) fn.call(data, e); } $(this).on("mouseup", ev_muc); return ev_muc; }; var RECT = function(){ this.top = 0; this.left = 0; this.bottom = 0; this.right = 0; } function inRect(rect, x, y){ return (y >= rect.top && y <= rect.bottom) && (x >= rect.left && x <= rect.right) } var scrollSize = measureScrollWidth(); 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; } function measureScrollWidth() { 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; };
Answer 7:
对我来说(只是针对IE11测试)工作的唯一解决方案:
$(document).mousedown(function(e){
bScrollbarClicked = e.clientX > document.documentElement.clientWidth || e.clientY > document.documentElement.clientHeight;
});
Answer 8:
我需要来检测鼠标按下但不能在窗口,但在DIV滚动条,和我有元素填写的内容,我用没有滚动条来检测尺寸:
.element {
position: relative;
}
.element .fill-node {
position: absolute;
left: 0;
top: -100%;
width: 100%;
height: 100%;
margin: 1px 0 0;
border: none;
opacity: 0;
pointer-events: none;
box-sizing: border-box;
}
用于检测所述代码类似于@DariuszSikorski答案但包括偏移量和使用,这是内部滚动的节点:
function scrollbar_event(e, node) {
var left = node.offset().left;
return node.outerWidth() <= e.clientX - left;
}
var node = self.find('.fill-node');
self.on('mousedown', function(e) {
if (!scrollbar_event(e, node)) {
// click on content
}
});
Answer 9:
应该指出的是,在Mac OSX 10.7以上版本,没有持续性滚动条。 显示滚动条滚动时,当你完成消失。 他们也小得多然后18像素(他们是7px的)。
截图: http://i.stack.imgur.com/zdrUS.png
Answer 10:
只是检测是否element.offsetLeft + element.scrollWidth < event.clientX
下element.onmousedown
。 元素的scrollWidth
不包括滚动条的宽度。 它只包括在内的内容。 如果你想也与水平滚动条检测,同样可以使用高度和Y位置,而不是宽度和X的立场,即规模应用。
文章来源: Determine whether user clicking scrollbar or content (onclick for native scroll bar)