确定是否用户点击滚动条或内容(的onclick本机的滚动条)确定是否用户点击滚动条或内容(的oncl

2019-05-13 10:58发布

我试图创造,都应该当一个滚动条被点击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:

你或许可以使用这个技巧。

你可以尝试劫持mousedownmouseup事件,避免他们时,点击您的自定义功能供电的滚动条。

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

和逆对mousedownScrollmouseupScroll事件。

$.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.clientXelement.onmousedown 。 元素的scrollWidth不包括滚动条的宽度。 它只包括在内的内容。 如果你想也与水平滚动条检测,同样可以使用高度和Y位置,而不是宽度和X的立场,即规模应用。



文章来源: Determine whether user clicking scrollbar or content (onclick for native scroll bar)