2010-06-21 4 views
4

J'ai un simple menu déroulant basé sur CSS avec multi-niveaux. Le deuxième ou troisième niveau peut sortir de la fenêtre visible, avec certaines combinaisons de résolution et de taille de fenêtre.Détecter si un site Web, menu déroulant va afficher hors écran

Certaines commandes de menus préconfigurées ouvrent simplement la liste déroulante vers la gauche au lieu de la droite, si elles détectent cette situation.

Comment puis-je tester (avec JS/jQuery) pour cette situation?

+3

Ron, je ne vais pas écrire une grande réponse, mais assurez-vous que tout ce que vous réglez sur les comptes pour le cas où quelqu'un ouvre votre page déjà défilée (ie via une ancre, ou leur navigateur "se souvenant" du précédent position). Cela étant dit, l'utilitaire Position de jQuery UI peut être ce que vous voulez. Il gère les «collisions» du type qui vous inquiète. – Ryley

Répondre

1

Vous devez afficher l'élément pour obtenir la taille afin d'afficher le sous-menu hors écran. Obtenir la largeur/hauteur de l'élément, calculer les positions d'affichage attendues (droite/bas), comparer à la largeur/hauteur de l'écran, décider de l'emplacement à afficher et déplacer l'élément vers la position finale.

(exemple non testé)

function displaysOffPageRight(defaultLeft){ 
    $('#submenu1').addClass('displayOffScreen'); 
    var offPage = defaultLeft + $('#submenu1').width() > screen.width; 
    $('#submenu1').removeClass('displayOffScreen'); 
    return offPage; 
} 
+0

Vous pouvez également changer l'affichage de l'élément dans jQuery, saisir sa hauteur, puis le remettre à l'état caché. Cela devrait fonctionner très bien. –

2

Vous pouvez tester si un élément de menu est Offscreen avec la fonction suivante:

/*--- function bIsNodeClippedOrOffscreen returns true if a node 
     is offscreen (without scrolling). 
     Requires jQuery. 
*/ 
function bIsNodeClippedOrOffscreen (zJnode) 
{ 
    var aDivPos    = zJnode.offset(); 
    var iLeftPos   = aDivPos.left; 
    var iTopPos    = aDivPos.top; 

    var iDivWidth   = zJnode.outerWidth (true); 
    var iDivHeight   = zJnode.outerHeight (true); 

    var bOffScreen   = CheckIfPointIsOffScreen (iLeftPos, iTopPos); 
    var bClipped   = CheckIfPointIsOffScreen (iLeftPos + iDivWidth, iTopPos + iDivHeight); 

    return (bOffScreen || bClipped); 
} 


function CheckIfPointIsOffScreen (iLeftPos, iTopPos) 
{ 
    var iBrowserWidth  = $(window).width() - 16; //-- 16 is fudge for scrollbars, refine later 
    var iBrowserHeight  = $(window).height() - 16; //-- 16 is fudge for scrollbars, refine later 
    var bOffScreen   = false; 

    if (iLeftPos < 0 || iLeftPos >= iBrowserWidth) 
     bOffScreen   = true; 

    if (iTopPos < 0 || iTopPos >= iBrowserHeight) 
     bOffScreen   = true; 

    return bOffScreen; 
} 

.
Exemple d'utilisation:

<li id="SomeMenuItem"> Get your shopping cart for free! 
... 
... 

var Node   = $("#SomeMenuItem"); 

var NeedToMoveIt = bIsNodeClippedOrOffscreen (Node); 
1

Lorsque le menu est pas encore affiché, vous ne pouvez pas obtenir ses dimensions. pour définir sa position. Si vous définissez CSS visibility: invisible et display: none, le menu ne sera pas affiché mais aura ses dimensions définies. Ensuite, vous pouvez obtenir sa position en utilisant jQuery.offset et sa hauteur/largeur avec jQuery.outerWidth/outerHeight (attention aux options margin pour les dernières fonctions). Oh, et faites attention si vous utilisez des marges négatives, cela nécessiterait une manipulation spéciale.

Obtenez les dimensions de la fenêtre avec jQuery(window).height() et .width() et vous devriez être en mesure de comprendre les maths à partir de là.