Bestimmen Sie, ob der Benutzer auf die Bildlaufleiste oder auf den Inhalt klickt (klicken Sie auf die native Bildlaufleiste).

Ich versuche, benutzerdefinierte Ereignisse in JQuery zu erstellen, die erkennen sollen, wenn auf eine Bildlaufleiste geklickt wird1.
Ich weiß, dass es viel Text gibt, aber alle meine Fragen sind fett geschrieben und es gibt eineJSFiddle Beispiel Sie können sofort weiterarbeiten.

Da ich dafür keine eingebaute Funktionalität gefunden habe,
Ich musste eine erstellenhasScroll Funktion, Überprüfung, ob das Element eine Bildlaufleiste hat,

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

und eininScrollRange Funktion, um zu überprüfen, ob der durchgeführte Klick innerhalb des Bildlaufbereichs liegt.

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

Sind alle Bildlaufleistengrößen einheitlich? Zum Beispiel in Firefox und IE ist es 18px.
Angenommen, es gibt keine benutzerdefinierten Bildlaufleisten. Gibt es in einigen Browsern zusätzliche Auffüllungen oder Größen?

Diese Funktionen werden alle wie vorgesehen ausgeführt (soweit ich das beurteilen kann).

Es war etwas schwieriger, benutzerdefinierte Ereignisse zu erstellen, aber ich brachte es dazu, etwas zu funktionieren. Das einzige Problem ist, dass das angeklickte Element auch ausgelöst wird, wenn ein Ereignis zum Herunterfahren / Hochfahren mit dem Mausklick verknüpft ist.

Ich kann anscheinend nicht verhindern, dass die anderen Ereignisse ausgelöst werden, während gleichzeitig die mousedownScroll / mouseupScroll-Ereignisse ausgelöst werden, wie ich es nenne.

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

Wie verhindere ich, dass die anderen "Klick" -Ereignisse ausgelöst werden?

Während ich frage, können Sie den Code so weit wie möglich optimieren.

Hier ist eine JSFiddle, mit der man herumspielen kann.

Der Grund, warum ich das mache, ist ein größeres Plugin, das ich entwickle. Es gibt ein benutzerdefiniertes Kontextmenü, das angezeigt wird, wenn ich mit der rechten Maustaste auf einen der Bildlaufleisten klicke. Ich will das nicht. Daher dachte ich, ich sollte ein Ereignis erstellen, das nach Bildlauf-Klicks sucht (Maus-Auf / Ab) und dann verhindert, dass das Kontextmenü angezeigt wird. Um dies zu tun, muss der Bildlauf vor dem normalen Klick erfolgen und wenn möglich auch das Auslösen der normalen Klicks verhindern.

Ich denke hier nur laut nach, aber Vielleicht gibt es eine Möglichkeit, alle an das Element gebundenen Funktionen abzurufen und dann die Reihenfolge zu ändern, in der sie hinzugefügt wurden. Ich weiß, dass Funktionen in der Reihenfolge ausgeführt werden, in der sie hinzugefügt wurden (1st added 1st called). Wenn ich diesen Prozess ansprechen könnte, könnte möglicherweise die gesamte "Registrierung" des Ereignisses in JQuery nur vor den Click-Ereignissen eingefügt werden.

1 kann nur mousedown / mouseup verwenden, da beim Klicken auf eine Bildlaufleiste kein Klick ausgelöst wird. Wenn dies falsch ist, geben Sie bitte ein funktionierendes Beispiel / Code an

Antworten auf die Frage(10)

Ihre Antwort auf die Frage