2013-04-03 109 views
7

我想用jQuery定位自定義上下文菜單。
第一次出現在正確的位置(鼠標座標),但是當前位置正在與新位置相加,以便菜單從屏幕上消失。
這裏是JavaScript:定位上下文菜單

<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

順便提及,['。對()'](http://api.jquery.com/on)已經取代' .bind()'在最近版本的jQuery中。 – Blazemonger 2013-04-03 18:36:28

回答

8

不要使用offset方法,嘗試css代替,定位上下文菜單絕對:

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

CSS:

#box { 
    ... 
    position: absolute; 
} 

http://jsfiddle.net/smxLk/

+0

我其實很喜歡這個。正確理解CSS並相應地設置它總比使用jQuery好,但我會做一個校正。我會用'fixed'而不是'absolute'。這種方式不會受到非靜態父級的影響,並且不會導致滾動條。 – 2013-04-03 18:50:57

+1

@JosephMarikle使用'position:fixed'會導致上下文菜單行爲奇怪:http://jsfiddle.net/smxLk/1/頁面長頁面內容。 'position:absolute' works fine:http://jsfiddle.net/smxLk/2/。 我也認爲在顯示之前我們必須檢查菜單是否離開屏幕並按照其位置修正其位置,否則如果剪輯菜單沒有意義的話。 – dfsq 2013-04-03 19:02:25

+0

好點。當你用'position:fixed'滾動時,我忘記了它會停留在一個地方。 XD – 2013-04-03 19:05:11

4

問題是,當你右鍵單擊然後左鍵單擊其他地方,然後再次右鍵單擊,位置不正確。

問題的根源在於您在顯示元素之前設置了偏移量。看起來,如果將元素設置爲display:none,然後改變它的偏移量,它會混淆jQuery。

要解決,你需要的showoffset條線開關在你的代碼的問題:

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

成爲

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

Demo

Source

+0

這是jQuery中的一個bug嗎? – Blazemonger 2013-04-03 18:46:28

+0

@Blazemonger也許吧。但我不確定它會得到修正,因爲改變隱藏元素的偏移量並沒有意義。但不幸的是,我沒有確定的答案 – 2013-04-03 18:48:39

0

嘗試位置:固定;用的基於下述條件上下文菜單改變位置 -

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/