¿Cambiando la posición de los popovers de Bootstrap en función de la posición X del popover en relación con el borde de la ventana?

He recorrido Internet a lo largo y ancho y, aunque encontré esta publicación stackoverflow perspicaz, ¿es posible cambiar la posición de los popovers de Bootstrap en función del ancho de la pantalla? , todavía no respondió mi pregunta, probablemente debido a mi problema para entender la posición / compensación.

Esto es lo que estoy tratando de hacer. Quiero que la posición de Twitter Bootstap Popover sea CORRECTA a menos que el popover del punto de acceso se ubique más allá de la ventana gráfica, luego quiero que se coloque a la IZQUIERDA. Estoy creando una aplicación web para iPad que tiene zonas activas, cuando presionas un punto de acceso público, aparece información, pero no quiero que aparezca fuera de la ventana gráfica cuando el desplazamiento horizontal está bloqueado.

Estoy pensando que sería algo como esto:

$('.infopoint').popover({ trigger:'hover', animation: false, placement: wheretoplace }); function wheretoplace(){ var myLeft = $(this).offset.left; if (myLeft<500) return 'left'; return 'right'; } 

¿Pensamientos? ¡Gracias!

Me acabo de dar cuenta de que la opción de ubicación podría ser una cadena o una función que devuelve una cadena que hace el cálculo cada vez que hace clic en un enlace popover-able.

Esto hace que sea muy fácil replicar lo que hiciste sin la función $ .each inicial:

 var options = { placement: function (context, source) { var position = $(source).position(); if (position.left > 515) { return "left"; } if (position.left < 515) { return "right"; } if (position.top < 110){ return "bottom"; } return "top"; } , trigger: "click" }; $(".infopoint").popover(options); 

En función de la documentación, debería poder utilizar el auto en combinación con la ubicación preferida, por ejemplo, auto left

http://getbootstrap.com/javascript/#popovers : “Cuando se especifica” auto “, reorientará dinámicamente el popover. Por ejemplo, si la ubicación es” autoizquierda “, la información sobre herramientas se mostrará hacia la izquierda cuando sea posible, de lo contrario se mostrará bien “.

Intentaba hacer lo mismo y luego me di cuenta de que esta funcionalidad ya existía.

Para Bootstrap 3, hay

 placement: 'auto right' 

que es mas facil Por defecto, será correcto, pero si el elemento está ubicado en el lado derecho de la pantalla, se dejará el popover. Entonces debería ser:

 $('.infopoint').popover({ trigger:'hover', animation: false, placement: 'auto right' }); 

Así que descubrí una manera de hacer esto de manera efectiva. Para mi proyecto en particular, estoy construyendo un sitio web de iPad, así que sabía exactamente cuál sería el valor de píxel X / Y para llegar al borde de la pantalla. Sus valores de thisX y thisY variarán.

Dado que los popovers se están colocando en línea de todos modos, simplemente agarro los valores izquierdo y superior de cada enlace para decidir en qué dirección debe estar el popover. Esto se hace agregando valores de datos html5 que use .popover () al momento de la ejecución.

 if ($('.infopoint').length>0){ $('.infopoint').each(function(){ var thisX = $(this).css('left').replace('px',''); var thisY = $(this).css('top').replace('px',''); if (thisX > 515) $(this).attr('data-placement','left'); if (thisX < 515) $(this).attr('data-placement','right'); if (thisY > 480) $(this).attr('data-placement','top'); if (thisY < 110) $(this).attr('data-placement','bottom'); }); $('.infopoint').popover({ trigger:'hover', animation: false, html: true }); } 

Cualquier comentario / mejora es bienvenido, pero esto hace el trabajo si está dispuesto a poner los valores manualmente.

La respuesta de bchhun me puso en el camino correcto, pero quería verificar el espacio real disponible entre la fuente y el borde de la ventana gráfica. También quería respetar el atributo de ubicación de datos como una preferencia con retrocesos apropiados si no había suficiente espacio. De esa manera, “correcto” siempre iría bien a menos que no haya suficiente espacio para que el popover se muestre en el lado derecho, por ejemplo. Esta fue la forma en que lo manejé. Funciona para mí, pero se siente un poco engorroso. Si alguien tiene alguna idea para una solución más limpia y concisa, me gustaría verla.

 var options = { placement: function (context, source) { var $win, $source, winWidth, popoverWidth, popoverHeight, offset, toRight, toLeft, placement, scrollTop; $win = $(window); $source = $(source); placement = $source.attr('data-placement'); popoverWidth = 400; popoverHeight = 110; offset = $source.offset(); // Check for horizontal positioning and try to use it. if (placement.match(/^right|left$/)) { winWidth = $win.width(); toRight = winWidth - offset.left - source.offsetWidth; toLeft = offset.left; if (placement === 'left') { if (toLeft > popoverWidth) { return 'left'; } else if (toRight > popoverWidth) { return 'right'; } } else { if (toRight > popoverWidth) { return 'right'; } else if (toLeft > popoverWidth) { return 'left'; } } } // Handle vertical positioning. scrollTop = $win.scrollTop(); if (placement === 'bottom') { if (($win.height() + scrollTop) - (offset.top + source.offsetHeight) > popoverHeight) { return 'bottom'; } return 'top'; } else { if (offset.top - scrollTop > popoverHeight) { return 'top'; } return 'bottom'; } }, trigger: 'click' }; $('.infopoint').popover(options); 

También puedes probar este,

==> Obtener la posición de destino / fuente en la ventana gráfica
==> Compruebe si el espacio del fondo es menor que la altura de su información sobre herramientas
==> Si el espacio del fondo es inferior a la altura de su información sobre herramientas, simplemente desplácese hacia arriba

 placement: function(context, source){ //get target/source position in viewport var bounds = $(source)[0].getBoundingClientRect(); winHeight = $(window).height(); //check wheather space from bottom is less that your tooltip height var rBottom = winHeight - bounds.bottom; //Consider 180 == your Tooltip height //if space from bottom is less that your tooltip height, this will scrolls page up //We are keeping tooltip position is fixed(at bottom) if (rBottom < 180){ $('html, body').animate({ scrollTop: $(document).scrollTop()+180 }, 'slow'); } return "bottom"; } 

Puede usar auto en la colocación de datos como data-placement = “auto left”. Se ajustará automáticamente de acuerdo con el tamaño de tu pantalla y se dejará la ubicación predeterminada.

Además de la gran respuesta de bchhun, si quieres un posicionamiento de absoulte, puedes hacer esto

 var options = { placement: function (context, source) { setTimeout(function () { $(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px') },0) return "top"; }, trigger: "click" }; $(".infopoint").popover(options); 

Solucioné mi problema en AngularJS de la siguiente manera:

 var configPopOver = { animation: 500, container: 'body', placement: function (context, source) { var elBounding = source.getBoundingClientRect(); var pageWidth = angular.element('body')[0].clientWidth var pageHeith = angular.element('body')[0].clientHeith if (elBounding.left > (pageWidth*0.34) && elBounding.width < (pageWidth*0.67)) { return "left"; } if (elBounding.left < (pageWidth*0.34) && elBounding.width < (pageWidth*0.67)) { return "right"; } if (elBounding.top < 110){ return "bottom"; } return "top"; }, html: true }; 

Esta función hace que la posición del flotador Popover de Bootstrap esté en la mejor posición, según la posición del elemento.

También puedes probar este si lo necesitas en casi todos los lugares de la página.

U puede configurarlo de manera general y luego usarlo.

De esta manera, también puedes usar el elemento HTML y todo lo que quieras 🙂

 $(document).ready(function() { var options = { placement: function (context, source) { var position = $(source).position(); var content_width = 515; //Can be found from a JS function for more dynamic output var content_height = 110; //Can be found from a JS function for more dynamic output if (position.left > content_width) { return "left"; } if (position.left < content_width) { return "right"; } if (position.top < content_height) { return "bottom"; } return "top"; } , trigger: "hover" , animation: "true" , html:"true" }; $('[data-toggle="popover"]').popover(options); }); 
    

Popover Example

Toggle popover