jQuery Conitextmenu

  • Hi,
    ich habe auch mal (ja, da gibts schon zig' davon) ein Contextmenu mit jQuery geschrieben. Es kann beliebig verschachtelt sein und Einträge können auch mit icons versehen werden. Jeder Eintrag hat das hover und click event. Hier ein beispiel:

    Hier ist anzumerken, dass das "click" event bei den erweiterten Einträgen nicht funktioniert.
    Und so siehts am Ende aus:

    Zusätzlich zu den sowieso benötigten Bildern sind noch "add.png", "delete.png" und "edit.png" als icons dabei.

    Benötigt weren jQuery.jContextMenu.js und contextmenu.css (oder den Teil in eine Andere CSS).
    Die Klassen, nachdenen das Menü gestaltet wird, lassen sich ebenfalls anpassen:

    Code
    $(selector).jContextMenu({...elemente...}, {    
    });

    für das 2te argument gilt:

    Code
    {     hoverClass: Die CSS-Klasse, die einem Menüeintrag gegeben wird, wennn sich der Mauszeiger über ihm befindet,     expendClass: Die CSS-Klasse, die einem Menüeintrag gegeben wird, wenn er sich erweitern kann,     iconClass: Die CSS-Klasse, die einem Menüeintrag gegeben wird, wenn er ein icon hat,     iconSelfClass: Die CSS-Klasse, die dem <span>-Element, wessen Hintergrund das icon ist, gegeben wird,     menuClass: Die CSS-Klasse, die den <div>´s gegeben werden, die ein Kontextmenü darstellen,     openOn: Event, auf welches das Menü geöffnet werden soll,     show: Wie das Menü geöffnet werden soll,     hide: Wie das Menü geschlossen werden soll }

    Die ganzen *class dürften Klar sein.
    openOn:
    Hier kann "rclick", "lclick", "hover" stehen. "rlcick" ist der Rechtsclick, "lclick" demnach der Linksklick.
    show:
    Kann entweder "pop" sein (hier wird das Menü per display: none/block; gezeigt), eine Zahl (in dieser Zeit in Millisekunden wird das Menü "gefadet") oder ein Objekt mit 2 Funktionen, die wie folgt aussehen:

    Code
    {     show: function(ui) {         $(ui).slideDown(1000);     },     hide: function(ui) {         $(ui).slideUp(1000);     }

    Hier noch die Standardwerte für diese Optionen:

    Code
    {     hoverClass: "ui-context-hover",     expendClass: "ui-context-expendable",     iconClass: "ui-context-icon",     iconSelfClass: "ui-icon",     menuClass: "ui-contextmenu",     openOn: "rclick",     show: "pop",     hide: "pop" }

    Zu guter letzt noch zu den Events. Bei hover und Click entspricht das event-Argument
    demhier:

    Code
    {     event: Das Event-Objekt, dass von jQuery übergeben wurde,     element: Das DOM-Objekt, auf dass der Benutzer geklickt hat,     mouseX: X-Koordiante vom Punkt im DOM-Objekt (element), auf den der Benutzer geklickt hat,     mouseY: Y-Koordiante vom Punkt im DOM-Objekt (element), auf den der Benutzer geklickt hat }

    Hier noch die CSS und JS zusammen mit den Bildern und einer Demo-Datei (aus dem Screenshot):
    jContextMenu.zip

    Viel Spaß damit!
    Feedback, bitte, immer. Aber konstruktiv bitte. Auf negatives kann ich verzichten und
    werde auch nicht drauf reagieren.

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

    3 Mal editiert, zuletzt von Tobse (13. Juni 2011 um 17:55)

  • In Chrome 11.0.696 wird auch das "normale" Kontextmenü geöffnet, dass dann darüber liegt. Aber ich schätze bei manchen Browsern kann man dagegen wohl nix machen.

    PHP
    if(isset($this) || !isset($this)){ // that's the question...
  • Erstmal danke für das Positive Feedback!
    @macrosdesign:
    Rein mit CSS wäre schon nice, allerdings macht am ende nur JS davon gebrauch, da man mit CSS ja nix richtiges Programmieren kann. Und wenn, hätte man dann mit CSS nicht auch die Probleme, die man jetzt mit JS hat?
    EDIT:
    upps, hab gelesen 'warum js' ;)
    Hier warum mit jQuery:
    JQuery ist mehr Crossbrowser als CSS3 (bzgl. Einiger Bugs im IE 7+8).
    Und mit jQuery ist ebenfalls crossbrowser der CSS Selektor verfügbar, DOM.querySelector(); ist ja HTML5 und leider längst noch kein Standart.

    @teron Leider nein, zuminest fällt mir da keine möglichkeit ein. Ich kenne da nur event.stopPropagation(), ist aber schon drin :|

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

    Einmal editiert, zuletzt von Tobse (13. Juni 2011 um 00:51)

  • Beim GMX Mediencenter funktionierts im Browser (auch in Chrome), dass sie das Kontextmenü unterdrücken.

    EDIT:
    Vielleicht wäre es sinnvoller statt auf stopPropagation() zurückzugreifen dem Dokument ein click-Event zuzuweisen und dann den Eventparameter auf die geklickte Maustaste überprüfen, also if(e.button == 3) return false; ??

    PHP
    if(isset($this) || !isset($this)){ // that's the question...

    Einmal editiert, zuletzt von Teron Gerofied (13. Juni 2011 um 10:16)

  • Das muss ich mal ausprobieren. Muss mal schaun, inwiefern die Rückgabewerte durch jQuery durchkommen, sollten aber schon.

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Ich hab doch geschrieben, dass es da viele von gibt. Ich hab das auch nicht geschrieben, damit ich eins habe, weils sonst keins gäbe, sondern weil ich in JS nicht so stark bin und es als herausforderung gesehen habe.

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

  • Wäre es nicht sinnvoller einfach eine "Programmoberfläche" zu bauen die dir so ein Menü zusammenschraubt aber die Funktion des Menüs einfach nur mit CSS funktioniert.. das geht nämlich auch schon mit CSS 2 ..

  • Aber sollte meine Idee nicht funktionieren kannst du dir von dem Plugin, was der Gast da geschickt hat, anschauen, wie die das "richtige" Kontextmenü verbergen, weil das wird im Chrome auch verborgen.

    Ansonsten übrigens sehr schönes Plugin ;)

    PHP
    if(isset($this) || !isset($this)){ // that's the question...
  • Danke :)
    @unknownsolider:
    Ja, da gibts ja so menüs für navigation (siehe cssplay.co.uk), allerdings reagiert css auch nicht auf den rechtsclick, oder doch?

    Code
    $(this).bind("contextmenu", function(){ return false; });

    ist schon drin. Wenn das fehlt, ist im FF das gleiche Problem wie im Chrome. Ich hab auchmal in die anderen "Bindings" ein return false rein, das kommt aber nicht an...

    EDIT:
    Ja, in dem anderen Plugin war tatsächlich was zu finden:
    Dein Codeschnispel von oben musste ich dazu erweitern:

    Code
    $(menuable_object).add($("."+options.menuClass)).bind("contextmenu", function(){ return false; });

    Nun klappts auch im Chrome, IE und Safari. (Hab die ZIP im Hauptpost erneuert).

    Der, der weiß dass er nichts weiß, weiß mehr als der, der nicht weiß, dass er nichts weiß.

    Wer nach etwas fragt, geht grundsätzlich das Risiko ein, es auch zu bekommen!

    2 Mal editiert, zuletzt von Tobse (13. Juni 2011 um 17:52)

  • Ach ich bin doch ein Idioooot !!

    Ich hab ganz vergessen, dass es den Eventhandler "contextmenu" auch noch gibt... Ach, da sieht man wieder, dass ich mit modifizierten Kontextmenüs nicht viel zu tun habe xD

    PHP
    if(isset($this) || !isset($this)){ // that's the question...