Determine si el usuario hace clic en la barra de desplazamiento o en el contenido (haga clic para la barra de desplazamiento nativa)

Estoy tratando de crear eventos personalizados en JQuery que se supone que detectan cuando se hace clic en una barra de desplazamiento1.
Sé que hay muchos textos, pero todas mis preguntas están en negrita y hay unaEjemplo de JSFiddle Usted puede trabajar de inmediato.

Porque no he encontrado ninguna funcionalidad integrada para esto,
Tuve que crear unhasScroll función, comprobando si el elemento tiene una barra de desplazamiento,

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

y uninScrollRange función, verificando si el clic realizado estaba dentro del rango de desplazamiento.

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

¿Todos los tamaños de barra de desplazamiento son uniformes? Por ejemplo, en Firefox e IE es 18px.
Suponiendo que no haya barras de desplazamiento personalizadas, ¿hay algún relleno o tamaño adicional en algunos navegadores?

Todas estas funciones se desempeñan según lo previsto (por lo que puedo discernir).

Hacer eventos personalizados fue un poco más complicado, pero conseguí que funcionara un poco. El único problema es que si el elemento en el que se hace clic tiene un evento de supresión / subida adjunto, también se activará.

Parece que no puedo evitar que los otros eventos se activen mientras se activan simultáneamente, lo que yo llamo, los eventos mousedownScroll / mouseupScroll.

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

¿Cómo evito que los otros eventos de "clic" se activen?

Mientras pregunto, no dude en optimizar el código tanto como sea posible.

Aquí hay un JSFiddle para jugar.

La razón por la que estoy haciendo esto es debido a un complemento más grande que estoy desarrollando. Tiene un menú contextual personalizado que aparece cuando hago clic derecho en uno de los scrollers. No quiero eso Así que pensé que debería hacer un evento que compruebe los clics de desplazamiento (mouseup / downs) y luego evitar que se muestre el menú contextual. Sin embargo, para hacer eso, necesito que el clic de desplazamiento aparezca antes que el clic normal y también, si es posible, detenga el disparo de los clics normales.

Estoy pensando en voz alta aquí, pero tal vez hay una manera de obtener todas las funciones que están vinculadas al elemento y luego cambiar el orden en que se agregaron? Sé que las funciones se ejecutan en el orden en que se agregaron (primero se agregó primero), así que, si pudiera aprovechar ese proceso, tal vez todo el "registro" del evento en JQuery podría insertarse antes de los eventos de clic.

1 solo se puede usar mousedown / mouseup porque el clic no se dispara al hacer clic en una barra de desplazamiento. Si esto es falso, por favor proporcione un ejemplo / código de trabajo

Respuestas a la pregunta(10)

Su respuesta a la pregunta