Przeszukałem Internet daleko i szeroko i chociaż znalazłem ten post z przepełnieniem stosu jako wnikliwy Czy można zmienić pozycję wyskakujących okienek Bootstrap na podstawie szerokości ekranu? , nadal nie odpowiedział na moje pytanie, prawdopodobnie z powodu problemów ze zrozumieniem pozycji / przesunięcia.
Oto, co próbuję zrobić. Chcę, aby pozycja Popover w usłudze Twitter Bootstap była PRAWA, chyba że popover hotspotu zostanie umieszczony poza widocznym obszarem, a następnie chcę, aby był ustawiony w LEWO. Tworzę aplikację internetową na iPada, która ma hotspoty, kiedy naciskasz na hotspot, pojawiają się informacje, ale nie chcę, aby pojawiały się poza widocznym obszarem, gdy przewijanie w poziomie jest zablokowane.
Myślę, że to wyglądałoby tak:
$('.infopoint').popover({
trigger:'hover',
animation: false,
placement: wheretoplace
});
function wheretoplace(){
var myLeft = $(this).offset.left;
if (myLeft<500) return 'left';
return 'right';
}
Myśli? Dzięki!
auto
nie zawsze działa idealnie w zależności od układu strony i treści, które umieścisz w wyskakującym okienku.left 515
&top 110
W przypadku Bootstrap 3 jest
placement: 'auto right'
co jest łatwiejsze. Domyślnie będzie to prawe, ale jeśli element znajduje się po prawej stronie ekranu, popover pozostanie. Więc powinno być:
$('.infopoint').popover({ trigger:'hover', animation: false, placement: 'auto right' });
źródło
Na podstawie dokumentacji powinieneś być w stanie użyć
auto
w połączeniu z preferowanym miejscem docelowym, npauto left
http://getbootstrap.com/javascript/#popovers : „Po określeniu„ auto ”dynamicznie zmieni orientację okna popover. Na przykład, jeśli umieszczenie jest ustawione na„ automatycznie w lewo ”, etykietka zostanie wyświetlona w lewo, jeśli to możliwe, w przeciwnym razie wyświetli się po prawej ”.
Próbowałem zrobić to samo, a potem zdałem sobie sprawę, że ta funkcja już istnieje.
źródło
viewport
jeśli nie chcesz, aby był obliczany na podstawie elementu nadrzędnego elementu.Więc wymyśliłem sposób, aby zrobić to skutecznie. Na potrzeby mojego konkretnego projektu tworzę witrynę na iPada, więc dokładnie wiedziałem, jaka będzie wartość piksela X / Y, aby osiągnąć krawędź ekranu. Twoje wartości thisX i thisY będą się różnić.
Ponieważ popover i tak jest umieszczany za pomocą stylu wbudowanego, po prostu chwytam lewą i górną wartość dla każdego linku, aby zdecydować, w którym kierunku powinno być popover. Odbywa się to poprzez dołączenie wartości danych html5, których .popover () używa podczas wykonywania.
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 }); }
Wszelkie komentarze / ulepszenia są mile widziane, ale można to zrobić, jeśli chcesz ręcznie wprowadzić wartości.
źródło
Odpowiedź bchhun zaprowadziła mnie na właściwą ścieżkę, ale chciałem sprawdzić rzeczywistą przestrzeń dostępną między źródłem a krawędzią widoku. Chciałem również uszanować atrybut umieszczania danych jako preferencji z odpowiednimi rezerwami, jeśli nie było wystarczającej ilości miejsca. W ten sposób „w prawo” zawsze będzie przebiegać w prawo, chyba że na przykład nie było wystarczająco dużo miejsca, aby popover był wyświetlany po prawej stronie. Tak sobie z tym radziłem. U mnie to działa, ale wydaje się trochę uciążliwe. Jeśli ktoś ma jakieś pomysły na czystsze, bardziej zwięzłe rozwiązanie, byłbym zainteresowany.
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);
źródło
Możesz też spróbować tego,
==> Uzyskaj pozycję docelową / źródłową w widoku
==> Sprawdź, czy przestrzeń od dołu jest mniejsza niż wysokość etykiety narzędzia
==> Jeśli przestrzeń od dołu jest mniejsza niż wysokość etykiety, po prostu przewiń stronę w górę
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"; }
źródło
Możesz użyć auto w rozmieszczaniu danych, na przykład data-placement = "auto left". Automatycznie dostosuje się do rozmiaru ekranu i pozostanie domyślne położenie.
źródło
Oprócz świetnej odpowiedzi bchhun, jeśli chcesz pozycjonować absoulte, możesz to zrobić
var options = { placement: function (context, source) { setTimeout(function () { $(context).css('top',(source.getBoundingClientRect().top+ 500) + 'px') },0) return "top"; }, trigger: "click" }; $(".infopoint").popover(options);
źródło
Rozwiązałem swój problem w AngularJS w następujący sposób:
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 };
Ta funkcja ustawia pozycję pływającego popover Bootstrap do najlepszej pozycji na podstawie pozycji elementu.
źródło
$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 = ''; } };
źródło
Możesz także wypróbować ten, jeśli potrzebujesz go w prawie wszystkich miejscach na stronie.
Możesz go skonfigurować w ogólny sposób, a następnie po prostu go użyć.
W ten sposób możesz również użyć elementu HTML i wszystkiego, co chcesz :)
$(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>
Dodanie
Aktualizacja
Jeśli chcesz, aby wyskakujące okienko po kliknięciu, możesz zmienić opcję JS na
trigger: "click"
to-return ..; } ...... , trigger: "click" ...... };
Możesz również dostosować go w reklamach HTML,
data-trigger="click"
takich jak ta-<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>
Myślę, że będzie to bardziej zorientowany kod, bardziej nadający się do ponownego wykorzystania i bardziej pomocny dla wszystkich :).
źródło