Events 确定用户是单击滚动条还是单击内容(单击本机滚动条)
我正在尝试在JQuery中创建自定义事件,以检测何时单击滚动条1。Events 确定用户是单击滚动条还是单击内容(单击本机滚动条),events,scrollbar,jquery,Events,Scrollbar,Jquery,我正在尝试在JQuery中创建自定义事件,以检测何时单击滚动条1。 我知道有很多文本,但我所有的问题都是黑体字,而且有一个你可以马上处理的问题 因为我还没有找到这方面的任何内置功能, 我必须创建一个hasScroll函数,检查元素是否有滚动条 $.fn.hasScroll = function(axis){ var overflow = this.css("overflow"), overflowAxis; if(typeof axis == "undefine
我知道有很多文本,但我所有的问题都是黑体字,而且有一个你可以马上处理的问题 因为我还没有找到这方面的任何内置功能,
我必须创建一个
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中是18px。假设没有定制的滚动条,在某些浏览器中是否有额外的填充或大小 这些功能都按预期执行(据我所知) 制作定制活动有点棘手,但我让它在某种程度上发挥了作用。唯一的问题是,如果单击的元素附加了mousedown/up事件,那么也会触发该事件 我似乎无法阻止其他事件触发,同时触发我所称的mousedownsroll/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.");
});
如何阻止其他“点击”事件触发?
在我提问时,请尽可能地优化代码
我之所以这么做是因为我正在开发一个更大的插件。它有一个自定义上下文菜单,当我右键单击其中一个滚动条时,它会显示出来。我不想那样。所以我想我应该做一个事件来检查滚动点击(鼠标点击/按下),然后阻止上下文菜单被显示。为了做到这一点,我需要在正常点击之前进行滚动点击,如果可能的话,还需要停止正常点击
我只是想大声说出来,但是也许有办法获取绑定到元素的所有函数,然后切换它们的添加顺序?我知道函数是按照它们被添加的顺序执行的(第一次添加第一次调用),因此,如果我能进入这个过程,也许整个事件到JQuery的“注册”可以在单击事件之前插入
1只能使用mousedown/mouseup,因为单击滚动条时不会触发单击。如果这是错误的,请提供一个工作示例/代码您可能会使用此黑客 您可以尝试劫持
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" );
};
顺便说一下,我认为滚动条的宽度是一个操作系统设置。应该指出的是,在Mac OSX 10.7+上,没有持久的滚动条。滚动条在您滚动时出现,在您完成操作时消失。它们也比18px小得多(它们是7px) 截图:
我在以前的项目中遇到了相同的问题,我建议使用此解决方案。它不是很干净,但很有效,我怀疑我们能用html做得更好。以下是我的解决方案的两个步骤: 1。在桌面环境中测量滚动条的宽度。 为了实现这一点,在应用程序启动时,您需要执行以下操作: 将以下元素添加到主体中:
使用jQUery的.width()测量先前添加元素的内部div的with,并将滚动条的宽度存储在某个位置(scollbar的宽度为50-内部div的with)
删除用于测量滚动条的额外元素(现在已经有了结果,请删除添加到正文中的元素)
所有这些步骤都不应该被用户看到,并且您的操作系统上有滚动条的宽度
例如,您可以使用以下代码段:
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;
};
var-measureScrollBarWidth=function(){
var scrollBarMeasure=$('');
$('body').append(scrollBarMeasure);
滚动条测量。宽度(50)。高度(50)
.css({
溢出:“滚动”,
可见性:“隐藏”,
位置:'绝对'
});
var scrollBarMeasureContent=$('').height(1);
追加(scrollBarMeasureContent);
var insideWidth=scrollBarMeasureContent.width();
var outsideWitdh=scrollBarMeasure.width();
scrollBarMeasure.remove();
从外部返回到DH-从内部返回;
};
2。检查滚动条上是否有单击。
现在您已经有了滚动条的宽度,您可以使用事件的坐标计算相对于滚动条位置矩形的事件坐标,并执行非常棒的操作
如果要过滤单击,可以在处理程序中返回false以防止其传播。我将提交我自己的答案并接受,因为它使其工作完美,并向上投票,因为它正确计算了滚动条的宽度,这也是我需要的
话虽如此,我决定创建两个独立的事件,而不是试图覆盖/覆盖JQuery的
mousedown
事件
这给了我所需的灵活性,而不会干扰JQuery自己的事件,而且非常容易做到
鼠标向下滚动
mousedownContent
- 这实现了亚历山大的答案+塞缪尔的答案
$.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; };
$.fn.hasScroll=函数(轴){ var overflow=this.css(“溢出”), 过流轴; 如果(typeof axis==“undefined”| | axis==“y”)overflowAxis=this.css(“overflow-y”); else overflowAxis=this.css(“overflow-x”); var bshouldcroll=this.get(0).scrollHeight>this.innerHeight
$.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; };
<div class='test container'><div class='test content'></div></div> <div id="results">please click</div>
#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; }
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" ); });
var clickedOnScrollbar = function(mouseX){ if( $(window).outerWidth() <= mouseX ){ return true; } } $(document).mousedown(function(e){ if( clickedOnScrollbar(e.clientX) ){ alert("clicked on scrollbar"); } });
$(document).mousedown(function(e){ bScrollbarClicked = e.clientX > document.documentElement.clientWidth || e.clientY > document.documentElement.clientHeight;
.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; }
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 } });
window.addEventListener("mousedown", onMouseDown); function onMouseDown(e) { if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) { // mouse down over scroll element } }
clickOnScrollbar = event.clientX > event.target.clientWidth || event.clientY > event.target.clientHeight;