2012-03-23 12 views
6

Tengo este problema en el que tengo un conjunto de 6 UL que tienen una clase común x. Cada una de ellas consta de una sección específica de la página. Ahora tengo 6 menús relacionados. a cada una de las secciones. Lo que tengo que hacer es resaltar el menú cuando su sección relacionada está en la vista de usuarios. Para esto pensé que podría ser jQuery posición(); o offset(); podría haber ayudado, pero dan la parte superior e izquierda del elemento.También intenté usar jQuery viewport plugin pero aparentemente el puerto de visualización es grande, puede mostrar más de una UL a la vez, por lo tanto, no puedo aplicar la lógica específica de elemento aquí.I No soy familiar a esto, pero ¿hay algún cambio de elemento en el desplazamiento? En caso afirmativo, ¿cómo acceder?Cómo obtener las coordenadas de un elemento en la página de desplazamiento

Por favor, comparta sus puntos de vista.

Saludos Himanshu Sharma.

Respuesta

0
  1. Usted puede obtener la anchura y la altura de la vista a través de $(document).width() y $(document).height()
  2. Usted puede obtener el número de píxeles de usuario se desplaza a través de $(document).scrollTop() y $(document).scrollLeft
  3. Combinando y , se puede calcular que el rectángulo de ventana gráfica es
  4. Puede obtener el rectángulo de un elemento usando $(element).offset(), $(element).width() y $(element).height()
  5. Así que lo único que le queda es determinar si rectángulo de la ventana contiene (o interactúa) rectángulo de los elementos

Así que todo el código puede verse como:

/** 
* Check wether outer contains inner 
* You can change this logic to matches what you need 
*/ 
function rectContains(outer, inner) { 
    return outer.top <= inner.top && 
     outer.bottom >= inner.bottom && 
     outer.left <= inner.left && 
     outer.right >= inner.right; 
} 

/** 
* Use this function to find the menu related to <ul> element 
*/ 
function findRelatedMenu(element) { 
    return $('#menu-' + element.attr('id')); 
} 

function whenScroll() { 
    var doc = $(document); 
    var elem = $(element); 
    var viewportRect = { 
     top: doc.scrollTop(), 
     left: doc.scrollLeft(), 
     width: doc.width(), 
     height: doc.height() 
    }; 
    viewportRect.bottom = viewportRect.top + viewportRect.height; 
    viewportRect.right = viewportRect.left + viewportRect.width; 

    var elements = $('ul.your-class'); 
    for (var i = 0; i < elements.length; i++) { 
     var elem = $(elements[i]); 
     var elementRect = { 
      top: elem.offset().top, 
      left: elem.offset().left, 
      width: elem.width(), 
      height: elem.height() 
     }; 
     elementRect.bottom = elementRect.top + elementRect.height; 
     elementRect.right = elementRect.left + elementRect.width; 

     if (rectContains(viewportRect, elementRect)) { 
      findRelatedMenu(elem).addClass('highlight'); 
     } 
    } 
} 

$(window).on('scroll', whenScroll); 
+0

Voy a intentarlo y luego se lo haré saber. –

+2

Demasiadas líneas para algo tan simple. –

+0

¿Por qué el enfoque medio modular? Aconsejaría usar un estilo de programación modular o no modular para descartar confusiones. ¿Y por qué usar un bucle for cuando puede usar jQuery.each() en la instancia de elementos de jQuery? Eso ya sería tres líneas más cortas. –

5

es muy fácil hágalo usando jQuery y un bloque HTML ficticio fijo que lo ayude a encontrar la posición actual de la ventana gráfica.

$(window).on("scroll load",function(){ 
    var once = true; 
    $(".title").each(function(ele, index){ 
     if($(this).offset().top > $("#viewport_helper").offset().top && once){    
      var index = $(this).index(".title"); 
      $(".current").removeClass('current')   
      $("#menu li").eq(index).addClass('current') 
      once = false; 
     } 
    });  
}) 

Salida un ejemplo de trabajo: http://jsfiddle.net/6c8Az/1/


También podría hacer algo similar con el plugin de jQuery, junto con el : Selector de primera:

$(window).on("scroll load",function(){ 
    $(".title:in-viewport:first").each(function(){ 
     var index = $(this).index(".title"); 
     $(".current").removeClass('current')   
     $("#menu li").eq(index).addClass('current') 
    }); 
}) 
+0

Puede mejorar el primer bloque de código con el enlace "uno" (http://api.jquery.com/one/). Se desharía de la var "una vez". – ramblinjan

+0

Uno es para el enlace de eventos, no para restringir un bucle "cada". –

+0

Ah, sí. Acabo de leer mal el código, lo siento. – ramblinjan

0

Veamos si entendí bien Tienes una página lo suficientemente larga para desplazarte, y hay un elemento que cuando aparece en la ventana gráfica, quieres hacer algo con ella. Por lo tanto, el único evento que se activa de forma segura en el momento en que el elemento ingresa en la ventana gráfica es el 'desplazamiento'. Entonces, si el elemento está en la página y el desplazamiento está en la ventana gráfica, lo que debe hacer es vincular una acción al evento de desplazamiento para verificar si el elemento está en la vista cada vez que se desencadena el evento. Más o menos así:

$(window).scroll(function() { 
    check_element_position(); 
}); 

Ahora, a fin de que usted pueda saber si el elemento está en la ventana gráfica, necesita 3 cosas. La parte superior de desplazamiento de ese elemento, el tamaño de la ventana gráfica y la parte superior de desplazamiento de la ventana.En caso de que más o menos el siguiente aspecto:

function check_element_position() { 
    var win = $(window); 
    var window_height = win.height(); 
    var element = $(your_element); 
    var elem_offset_top = element.offset().top; 
    var elem_height = element.height(); 
    var win_scroll = win.scrollTop(); 
    var pseudo_offset = (elem_offset_top - win_scroll); 
    if (pseudo_offset < window_height && pseudo_offset >= 0) { 
     // element in view 
    } 
    else { 
     // elem not in view 
    } 
} 

Aquí, (elem_offset_top - win_scroll) representan la posición del elemento si no hay desplazamiento. De esta manera, solo tienes que verificar si la parte superior del desplazamiento del elemento es más alta que la ventana de la ventana para ver si está a la vista o no. Finalmente, podría ser más preciso en sus cálculos al agregar la altura del elemento (la variable ya está allí) porque el código que acabo de ejecutar disparará el evento incluso si el elemento es visible solo por 1 píxel.

Nota: Acabo de hacer que en cinco minutos, por lo que podría tener que corregir algo de esto, pero esto le da una bastante bueno idea de lo que está pasando;)

no dude en comentar y hacer preguntas

+0

Absorbe su atención Bene.Pero estaré en esto algún tiempo después, y le haré saber. Si funciona, le otorgaré la recompensa. Gracias –

+0

Entonces, espero que funcione;) – Bene

Cuestiones relacionadas