Changer la position des popover Bootstrap en fonction de la position X du popover par rapport au bord de la fenêtre?

j'ai parcouru L'Internet loin et large et bien que j'ai trouvé ce post empileur perspicace est-il possible de changer la position de Bootstrap popovers basé sur la largeur de l'écran? , il n'a toujours pas répondu à ma question, probablement en raison de ma difficulté à comprendre la position/compensation.

voilà ce que j'essaie de faire. Je veux que la position du Popover de Bootstap Twitter soit correcte à moins que le popover de hotspot ne soit positionné au-delà du viewport, alors je voulez qu'il soit positionné à GAUCHE. Je fais une application web iPad qui a des points chauds, quand vous poussez sur un point chaud, l'information apparaît mais je ne veux pas qu'elle apparaisse en dehors du viewport quand le défilement horizontal est verrouillé.

je pense que ça ferait quelque chose comme ça:

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

        if (myLeft<500) return 'left';
        return 'right';
    }

? Merci!

76
demandé sur Community 2012-03-31 18:55:34

10 réponses

je viens de remarquer que l'option placement pourrait être une chaîne de caractères ou une fonction retournant une chaîne de caractères qui fait le calcul chaque fois que vous cliquez sur un lien popover-able.

cela rend très facile de répliquer ce que vous avez fait sans le $initial.chaque fonction:

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);
167
répondu bchhun 2012-09-29 20:22:47

sur la base de la documentation, vous devriez pouvoir utiliser auto en combinaison avec le placement préféré par exemple auto left

http://getbootstrap.com/javascript/#popovers :" quand "auto" est spécifié, il réoriente dynamiquement le popover. Par exemple, si le placement est "auto left", le tooltip s'affichera à gauche lorsque c'est possible, sinon il s'affichera à droite."

j'essayais de faire la même chose chose et alors réalisé que cette fonctionnalité existait déjà.

29
répondu Hamish Rouse 2013-11-07 03:05:20

pour Bootstrap 3, Il y a

placement: 'auto right'

ce qui est plus facile. Par défaut, il sera juste, mais si l'élément est situé dans le côté droit de l'écran, la liste sera à gauche. Il devrait en être ainsi:

$('.infopoint').popover({
   trigger:'hover',
   animation: false,
   placement: 'auto right'
});
28
répondu Hans Tiono 2015-04-08 08:54:43

donc j'ai trouvé un moyen de le faire efficacement. Pour mon projet particulier je suis en train de construire un site web iPad donc je savais exactement ce que la valeur pixel X/Y serait pour atteindre le bord de l'écran. Vos valeurs de thisy et de thisy varieront.

puisque les popover sont placés par style inline de toute façon, je prends simplement les valeurs de gauche et de haut pour chaque lien pour décider quelle direction le popover devrait être. Ceci est fait en ajoutant html5 données - valeurs .liste() utilise lors de l'exécution.

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
    });
}

n'importe quels commentaires/améliorations sont les bienvenus mais cela obtient le travail fait si vous êtes prêt à mettre les valeurs manuellement.

5
répondu j0e 2012-04-09 15:38:21

la réponse de bchhun m'a mis sur la bonne voie, mais je voulais vérifier l'espace disponible entre la source et le bord du viewport. Je voulais également respecter l'attribut de placement de données comme une préférence avec des retombées appropriées s'il n'y avait pas assez d'espace. De cette façon "droit" irait toujours à droite à moins qu'il n'y ait pas assez d'espace pour le popover de montrer sur le côté droit, par exemple. C'était la façon dont j'ai géré ça. Il fonctionne pour moi, mais il se sent un peu lourd. Si quelqu'un a toutes les idées pour une solution plus propre, plus concise, je serais intéressé de le voir.

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);
1
répondu chasingmaxwell 2014-09-28 05:22:48

, Vous pouvez aussi essayer celui-ci,

==> Obtenir de cible et la position de la source dans la fenêtre d'affichage

= = > Vérifier si l'espace depuis le bas est inférieur à la hauteur de votre tooltip

= = > Si l'espace depuis le bas est inférieur à la hauteur de votre tooltip, faites simplement défiler la page vers le haut

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";
}
1
répondu Mohan Dere 2016-02-26 13:30:50

vous pouvez utiliser auto dans le placement de données comme data-placement="auto left". Il s'ajustera automatiquement en fonction de la taille de votre écran et le placement par défaut sera laissé.

0
répondu Abhishek Anand 2015-06-15 09:20:20

en plus de la grande réponse de bchhun, si vous voulez positionnement absoulte, vous pouvez le faire

var options = {
    placement: function (context, source) {
         setTimeout(function () {
               $(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px')
         },0)
         return "top";
    },
    trigger: "click"
};
$(".infopoint").popover(options);
0
répondu apple16 2015-09-12 17:39:24

j'ai résolu mon problème à AngularJS comme suit:

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
    };

cette fonction fait la position du flotteur popover Bootstrap à la meilleure position, basée sur la position de l'élément.

0
répondu Gustavo Benício 2016-02-02 17:57:56

vous pouvez également essayer celui-ci si vous en avez besoin dans presque tous les endroits de la page.

U peut le configurer d'une manière générale alors il suffit de l'utiliser.

de cette façon, vous pouvez également utiliser L'élément HTML et tout ce que vous voulez:)

$(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);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>


<div class="container">
	<h3>Popover Example</h3>
	<a id="try_ppover" href="#" data-toggle="popover" title="Popover HTML Header" data-content="<div class='jumbotron'>Some HTML content inside the popover</div>">Toggle popover</a>
</div>

Plus


pour définir plus d'options, vous pouvez aller ici .

encore plus peut être trouvé ici .

mise à Jour


si vous voulez le popup après clic, vous pouvez changer l'option JS à trigger: "click" comme ceci -

        return ..;
    }
    ......
    , trigger: "click"
    ......
};

U peut également le personnaliser en HTML ading data-trigger="click" comme ceci -

<a id="try_ppover" href="#" data-toggle="popover" data-trigger="click" title="Popover Header" data-content="<div class='jumbotron'>Some content inside the popover</div>">Toggle popover</a>

je crois sera plus orienté de code et plus de ré-utilisable et plus utile à tous :).

-2
répondu Abrar Jahin 2016-03-06 05:15:13