Я рыскал по Интернету повсюду, и пока я нашел этот пост stackoverflow проницательным, можно ли изменить положение всплывающих окон Bootstrap в зависимости от ширины экрана? , он все еще не ответил на мой вопрос, вероятно, из-за моих проблем с пониманием позиции / смещения.
Вот что я пытаюсь сделать. Я хочу, чтобы положение всплывающего окна Bootstap в Twitter было ПРАВИЛЬНО, если только всплывающее окно горячей точки не будет располагаться за пределами области просмотра, тогда я хочу, чтобы оно было расположено ВЛЕВО. Я делаю веб-приложение для iPad, в котором есть горячие точки. Когда вы нажимаете на горячую точку, появляется информация, но я не хочу, чтобы она отображалась за пределами области просмотра, когда горизонтальная прокрутка заблокирована.
Я думаю, это будет примерно так:
$('.infopoint').popover({
trigger:'hover',
animation: false,
placement: wheretoplace
});
function wheretoplace(){
var myLeft = $(this).offset.left;
if (myLeft<500) return 'left';
return 'right';
}
Мысли? Благодаря!
auto
он не всегда работает идеально в зависимости от макета страницы и содержимого, которое вы помещаете во всплывающее окно.left 515
&top 110
Для Bootstrap 3 есть
placement: 'auto right'
что проще. По умолчанию он будет правым, но если элемент расположен в правой части экрана, всплывающее окно будет левым. Так и должно быть:
$('.infopoint').popover({ trigger:'hover', animation: false, placement: 'auto right' });
источник
Основываясь на документации, вы должны иметь возможность использовать
auto
в сочетании с предпочтительным размещением, напримерauto left
http://getbootstrap.com/javascript/#popovers : «Если указано« auto », всплывающее окно будет динамически переориентировано. Например, если для размещения установлено« auto left », всплывающая подсказка будет отображаться слева, когда это возможно, в противном случае он будет отображаться правильно ".
Я пытался сделать то же самое, но потом понял, что эта функция уже существует.
источник
viewport
если не хотите, чтобы он вычислялся на основе родительского элемента.Так что я нашел способ сделать это эффективно. Для своего конкретного проекта я создаю веб-сайт для iPad, поэтому я точно знал, каким будет значение X / Y в пикселях, чтобы достичь края экрана. Ваши значения thisX и thisY будут различаться.
Поскольку всплывающие окна в любом случае размещаются с помощью встроенного стиля, я просто беру значения left и top для каждой ссылки, чтобы решить, в каком направлении должно быть всплывающее окно. Это делается путем добавления значений данных html5, которые использует .popover () при выполнении.
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 }); }
Любые комментарии / улучшения приветствуются, но это выполнит свою работу, если вы хотите ввести значения вручную.
источник
Ответ bchhun направил меня на правильный путь, но я хотел проверить фактическое пространство, доступное между источником и краем области просмотра. Я также хотел уважать атрибут размещения данных как предпочтение с соответствующими запасными вариантами, если не было достаточно места. Таким образом, «правильно» всегда будет идти вправо, если, например, не было достаточно места для отображения всплывающего окна с правой стороны. Так я с этим справился. У меня это работает, но кажется немного громоздким. Если у кого-то есть идеи более чистого и лаконичного решения, мне было бы интересно их увидеть.
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);
источник
Вы также можете попробовать это,
==> Получить целевую / исходную позицию в окне просмотра
==> Проверить, меньше ли пространство снизу, чем высота всплывающей подсказки
==> Если пространство снизу меньше высоты всплывающей подсказки, просто прокрутите страницу вверх
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"; }
источник
Вы можете использовать auto в размещении данных, например data-Placement = "auto left". Он будет автоматически настроен в соответствии с размером вашего экрана, а размещение по умолчанию останется.
источник
В дополнение к отличному ответу bchhun, если вы хотите абсолютное позиционирование, вы можете сделать это
var options = { placement: function (context, source) { setTimeout(function () { $(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px') },0) return "top"; }, trigger: "click" }; $(".infopoint").popover(options);
источник
Я решил свою проблему в AngularJS следующим образом:
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 };
Эта функция устанавливает позицию всплывающего всплывающего окна Bootstrap в лучшую позицию в зависимости от позиции элемента.
источник
$scope.popoverPostion = function(event){ $scope.pos = ''; if(event.x <= 207 && event.x >= 140){ $scope.pos = 'top'; event.x = ''; } else if(event.x < 140){ $scope.pos = 'top-left'; event.x = ''; } else if(event.x > 207){ $scope.pos = 'top-right'; event.x = ''; } };
источник
Вы также можете попробовать это, если вам это нужно почти во всех местах страницы.
Вы можете настроить его в общем виде, а затем просто использовать.
Таким образом, вы также можете использовать элемент HTML и все, что хотите :)
$(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>
Дополнение
Обновить
Если и хотите , всплывающее окно после щелчка, и может изменить параметр JS для
trigger: "click"
как this-return ..; } ...... , trigger: "click" ...... };
Вы также можете настроить его в HTML-объявлениях
data-trigger="click"
следующим образом:<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>
Я думаю, это будет более ориентированный код, более пригодный для повторного использования и полезный для всех :).
источник