2013-04-03 6 views
7

Ich versuche, ein benutzerdefiniertes Kontextmenü mit jQuery zu positionieren.
Das erste Mal erscheint es an der richtigen Position (Mauskoordinaten), aber dann wird die aktuelle Position mit der neuen Position summiert, so dass das Menü vom Bildschirm verschwindet.
Hier ist die JavaScript:Positionierung Kontextmenü

<script> 
$(function(){ 
    $('#box').hide(); 

    $(document).bind("contextmenu", function(e) { 
     $("#box").offset({left:e.pageX, top:e.pageY}); 
     $('#box').show(); 
     e.preventDefault(); 
    }); 

    $(document).bind("click", function(e) { 
     $('#box').hide(); 
    }); 
    $('#box').bind("click", function(e) { 
     $('#box').hide(); 
    }); 
}); 
</script> 
+0

By the way, [ '.on()'] (http://api.jquery.com/on) hat verdrängte ' .bind() 'in neueren Versionen von jQuery. – Blazemonger

Antwort

8

nicht offset Methode verwenden, versuchen css stattdessen Menü Positionierung Kontext absolut:

$("#box").css({left:e.pageX, top:e.pageY}); 

CSS:

#box { 
    ... 
    position: absolute; 
} 

http://jsfiddle.net/smxLk/

+0

Ich mag das auf jeden Fall besser. Das CSS richtig zu verstehen und es entsprechend zu setzen wird meiner Meinung nach immer besser sein als die Verwendung von jQuery, aber ich würde eine Verbesserung vornehmen. Ich würde 'fixed' anstelle von' absolute' verwenden. Auf diese Weise kann es nicht von einem nicht statischen Elternteil beeinflusst werden und es verursacht keine Bildlaufleisten. –

+1

@JosephMarikle Die Verwendung von 'position: fixed' bewirkt, dass sich das Kontextmenü merkwürdig verhält: http: //jsfiddle.net/smxLk/1/ auf der Seite mit dem langen Seiteninhalt. 'position: absolute' funktioniert gut: http://jsfiddle.net/smxLk/2/. Ich denke auch, dass wir vor dem Anzeigen überprüfen müssen, ob das Menü vom Bildschirm verschwindet und seine Position entsprechend ändern, sonst macht das Menü keinen Sinn, wenn es abgeschnitten ist. – dfsq

+0

Gute Punkte. Ich habe vergessen, dass es an einer Stelle bleiben würde, wenn Sie mit "position: fixed" scrollen. XD –

4

Das Problem ist, dass, wenn Sie mit der rechten Maustaste klicken Sie dann links klicken Sie auf eine andere Stelle und dann mit der rechten Maustaste erneut, die Position ist falsch.

Der Grund des Problems ist, dass Sie den Offset festlegen, bevor das Element angezeigt wird. Es scheint, dass es jQuery verwirrt, wenn das Element auf display:none festgelegt ist und dann sein Offset geändert wird.

das Problem, das Sie die show und die offset Linien in Ihrem Code wechseln müssen zu beheben:

$(document).bind("contextmenu", function(e) { 
    $("#box").offset({left:e.pageX, top:e.pageY}); 
    $('#box').show(); 
    e.preventDefault(); 
}); 

wird

$(document).bind("contextmenu", function(e) { 
    $('#box').show(); 
    $("#box").offset({left:e.pageX, top:e.pageY}); 
    e.preventDefault(); 
}); 

Demo
und
Source

+0

Ist das ein Fehler in jQuery, dann? – Blazemonger

+0

@Blazonger Vielleicht. Ich bin mir nicht sicher, ob es behoben wird, da es nicht wirklich Sinn macht, den Offset eines versteckten Elements zu ändern. Aber ich habe leider keine definitive Antwort für Sie –

0

Try Position: Fest; mit Position von Änderungen Kontextmenü auf folgende Bedingung basiert -

var windowHeight = $(window).height()/2; 
var windowWidth = $(window).width()/2; 
if(e.clientY > windowHeight && e.clientX <= windowWidth) { 
    $("#contextMenuContainer").css("left", e.clientX); 
    $("#contextMenuContainer").css("bottom", $(window).height()-e.clientY); 
    $("#contextMenuContainer").css("right", "auto"); 
    $("#contextMenuContainer").css("top", "auto"); 
} else if(e.clientY > windowHeight && e.clientX > windowWidth) { 
    $("#contextMenuContainer").css("right", $(window).width()-e.clientX); 
    $("#contextMenuContainer").css("bottom", $(window).height()-e.clientY); 
    $("#contextMenuContainer").css("left", "auto"); 
    $("#contextMenuContainer").css("top", "auto"); 
} else if(e.clientY <= windowHeight && e.clientX <= windowWidth) { 
    $("#contextMenuContainer").css("left", e.clientX); 
    $("#contextMenuContainer").css("top", e.clientY); 
    $("#contextMenuContainer").css("right", "auto"); 
    $("#contextMenuContainer").css("bottom", "auto"); 
} else { 
    $("#contextMenuContainer").css("right", $(window).width()-e.clientX); 
    $("#contextMenuContainer").css("top", e.clientY); 
    $("#contextMenuContainer").css("left", "auto"); 
    $("#contextMenuContainer").css("bottom", "auto"); 
} 

http://jsfiddle.net/AkshayBandivadekar/zakn7Lwb/14/