Określ, czy użytkownik kliknie pasek przewijania lub zawartość (kliknij, aby wyświetlić rodzimy pasek przewijania)

Próbuję utworzyć niestandardowe zdarzenia w JQuery, które mają wykryć kliknięcie paska przewijania1.
Wiem, że jest dużo tekstu, ale wszystkie moje pytania są pogrubione i jestPrzykład JSFiddle możesz pracować od razu.

Ponieważ nie znalazłem żadnej wbudowanej funkcjonalności,
Musiałem stworzyćhasScroll funkcja, sprawdzanie, czy element ma pasek przewijania,

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

i aninScrollRange funkcja, sprawdzanie, czy kliknięcie zostało wykonane w zakresie przewijania.

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

Czy wszystkie rozmiary pasków przewijania są jednolite? Np. W Firefoksie i IE to 18px.
Zakładając, że nie ma dostosowanych pasków przewijania, czy są jakieś dodatkowe wypełnienia lub rozmiary w niektórych przeglądarkach?

Wszystkie te funkcje działają zgodnie z przeznaczeniem (z tego, co mogę zauważyć).

Dokonywanie niestandardowych wydarzeń było nieco trudniejsze, ale udało mi się je nieco poprawić. Jedynym problemem jest to, że jeśli kliknięty element ma dołączone do niego wydarzenie, zostanie on również uruchomiony.

Wydaje mi się, że nie mogę powstrzymać innych zdarzeń przed wyzwoleniem, jednocześnie uruchamiając zdarzenia, które wywołuję, 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>

Jak powstrzymać inne zdarzenia „kliknięcia” przed uruchomieniem?

Pytając, zoptymalizuj kod tak bardzo, jak to możliwe.

Oto JSFiddle, z którym można się bawić.

Powodem, dla którego to robię, jest większa wtyczka, którą tworzę. Posiada niestandardowe menu kontekstowe, które pojawia się po kliknięciu prawym przyciskiem myszy jednego z rolek. Nie chcę tego. Pomyślałem, że powinienem zrobić zdarzenie, które sprawdza kliknięcia przewijania (kliknięcie / opuszczenie), a następnie uniemożliwia wyświetlanie menu kontekstowego. Aby to zrobić, potrzebuję kliknięcia przewijania, aby przejść przed normalnym kliknięciem, a także, jeśli to możliwe, powstrzymać normalne kliknięcia przed wystrzeleniem.

Właśnie tu myślę głośno, ale może istnieje sposób na uzyskanie wszystkich funkcji związanych z elementem, a następnie zmianę kolejności, w jakiej zostały dodane? Wiem, że funkcje są wykonywane w kolejności, w jakiej zostały dodane (pierwsza dodana pierwsza wywołana), więc jeśli mógłbym wykorzystać ten proces, być może cała „rejestracja” zdarzenia w JQuery mogłaby zostać wstawiona przed zdarzeniami kliknięcia.

1 może używać tylko mousedown / mouseup, ponieważ kliknięcie nie uruchamia się po kliknięciu paska przewijania. Jeśli jest to fałszywe, podaj roboczy przykład / kod

questionAnswers(10)

yourAnswerToTheQuestion