Determine se o usuário está clicando na barra de rolagem ou no conteúdo (onclick for native scroll bar)

Eu estou tentando criar eventos personalizados no JQuery que devem detectar quando uma barra de rolagem é clicada1.
Eu sei que há muito texto, mas todas as minhas perguntas são corajosas e há umExemplo JSFiddle você pode trabalhar imediatamente.

Porque eu não encontrei nenhuma funcionalidade embutida para isso,
Eu tive que criar umhasScroll função, verificando se o elemento tem uma barra de rolagem,

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

e uminScrollRange função, verificando se o clique realizado estava dentro do intervalo de rolagem.

<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 os tamanhos das barras de rolagem são uniformes? Por exemplo, no Firefox e no IE, são 18 px.
Supondo que não existam barras de rolagem personalizadas, há algum preenchimento ou tamanhos extras em alguns navegadores?

Todas essas funções funcionam como planejadas (pelo que eu posso discernir).

Fazer eventos personalizados foi um pouco mais complicado, mas consegui que funcionasse um pouco. O único problema é que, se o elemento clicado tiver um evento mousedown / up anexado a ele, ele também será acionado.

Não consigo impedir que os outros eventos sejam acionados enquanto, simultaneamente, estou acionando, como eu chamo, os 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>

Como faço para impedir que os outros eventos de "clique" sejam acionados?

Enquanto estou perguntando, sinta-se à vontade para otimizar o código o máximo possível.

Aqui está um JSFiddle para mexer com.

A razão pela qual estou fazendo isso é por causa de um plugin maior que estou desenvolvendo. Ele tem um menu de contexto personalizado que aparece quando clico com o botão direito do mouse em um dos roladores. Eu não quero isso. Então eu pensei que deveria fazer um evento que verifica os cliques de rolagem (mouseup / downs) e então impedir que o menu de contexto seja exibido. No entanto, para fazer isso, preciso que o clique de rolagem ocorra antes do clique normal e, se possível, que os cliques normais sejam disparados.

Eu só estou pensando em voz alta aqui, mas talvez haja uma maneira de obter todas as funções que estão vinculadas ao elemento e, em seguida, alternar a ordem na qual elas foram adicionadas? Eu sei que as funções são executadas na ordem em que foram adicionadas (1ª adicionada à 1ª chamada), portanto, se eu pudesse explorar esse processo, talvez todo o "registro" do evento no JQuery pudesse ser inserido antes dos eventos de clique.

1 só pode usar mousedown / mouseup porque o clique não é acionado ao clicar em uma barra de rolagem. Se isso for falso, por favor, forneça um exemplo / código de trabalho

questionAnswers(10)

yourAnswerToTheQuestion