Prevent BODY from scrolling when a modal is opened in angular application - javascript

I want my body to stop scrolling to top when I am trying to open popup modals. I am using both angular material and ng-bootstrap popup modals.
I've tried the piece of CSS code below, but the issue is still there, please help.
body.modal-open {
overflow: hidden;
position: fixed;
}

From what I read here here the position of the modal is set to default at the top. To completely remove the scrolling, use that to position the modal down. If you just want to be at the same position after the modal close, you can use this which I used from the comments: here
openModal() {
// Remember the current scroll position
let pos = (document.documentElement.scrollTop || document.body.scrollTop);
this.bsModalRef = this.modalService.show(ModalComponent);
this.modalHideSubscription = this.modalService.onHide.subscribe(() => {
//Return back to the position before opening modal
window.scrollTo(0,pos);
this.modalHideSubscription.unsubscribe();
});
}

Related

Scrolling issues with multiple bootstrap modals

I have a page with a modal with a lot of info so you need to scroll. This modal contains a link to a second modal.
When I
open modal 1
click on link to open modal 2 (modal 1 stays in background)
and then close modal 2 so that I am back on modal 1
modal 1 looses scrolling (there is still a scroll bar but it doesn't do anything). Instead the modal stays in the position it was at the time of opening modal 2.
I played around with closing the background modal with js first (but that messes up scrolling on the second modal). It appears that every time I try to open/close more than one modal I always get some issue with the scrolling.
Any suggestions on how to handle this?
Add
.modal { overflow: auto !important; }
To your CCS.
Without your code I went ahead and created this jsFiddle that recreates your issue, or at least a very similar one. Add your code and I will test if this works or not.
Adding that line to the CSS fixed the issue as demonstrated with this jsFiddle.
Solution taken from this thread on github which offers other solutions as well.
The solution that worked for me was:
$('.modal').on("hidden.bs.modal", function (e) {
if ($('.modal:visible').length) {
$('body').addClass('modal-open');
}
});
$(document).on('hidden.bs.modal', '.modal', function () {
$('.modal:visible').length && $(document.body).addClass('modal-open');
});
this is the solution:
<script>
$('#id_ofyou_secondary_modal').on('hidden.bs.modal', function (e) {
$('body').addClass('modal-open');
});
</script>
take care that "#idofyousecondarymodal" is the id of the secondary or tertiary or infinite modal. but NEVER write the ID of the first modal.
example i have 2 modal:
<div id="mymodal1" class="modal fade in" style="display:none;">
.
.
.
.
</div>
<div id="mymodal2" class="modal fade in" style="display:none;">
.
.
.
.
</div>
then the script will be:
<script>
$('#mymodal2').on('hidden.bs.modal', function (e) {
$('body').addClass('modal-open');
});
</script>
jus add this code and work fine.
I tried the previous solutions, and not working for my use case:
just adding css .modal { overflow: auto !important; }
This will cause the content below modal become scrollable. Not good when you want to keep the previous content position. especially in mobile browser.
Use javascript to track opened modal and keep the 'modal-open' class in body element using this jQuery selector $('.modal:visible').length. This is not working when there are multiple modal opened and closed fast. I use BS modal for my ajax spinner, so the $('.modal:visible') is not accurate.
This is the working one for me:
Use JS global variable to keep track/count of opened modal; instead of just using :visible selector
And I added css style so I don't have to recalculate backdrop z-index
https://stackoverflow.com/a/63473738/423356
var bootstrapModalCounter = 0; //counter is better then using visible selector
$(document).ready(function () {
$('.modal').on("hidden.bs.modal", function (e) {
--bootstrapModalCounter;
if (bootstrapModalCounter > 0) {
//don't need to recalculate backdrop z-index; already handled by css
//$('.modal-backdrop').first().css('z-index', parseInt($('.modal:visible').last().css('z-index')) - 10);
$('body').addClass('modal-open');
}
}).on("show.bs.modal", function (e) {
++bootstrapModalCounter;
//don't need to recalculate backdrop z-index; already handled by css
});
});
.modal {
/*simple fix for multiple bootstrap modal backdrop issue:
don't need to recalculate backdrop z-index;
https://stackoverflow.com/questions/19305821/multiple-modals-overlay/21816777 */
background: rgba(0, 0, 0, 0.5);
}
This is modified fiddle from #Keeleon for the fix https://jsfiddle.net/4m68uys7/
This is github issue https://github.com/nakupanda/bootstrap3-dialog/issues/70
Add following to your CSS :
.modal
{
overflow: scroll !important;
}

Dialog opens outside viewport

In case you're on a large page and you've scrolled all the way down. At the bottom is a button which opens a dialog. In my case this dialog opens outside the viewport at the top of the page
DEMO
JS:
var showDialogButton = document.getElementById('showDialogButton');
showDialogButton.addEventListener('click', function() {
var bronteDialog = document.getElementById('bronteDialog');
var anchorPoint = document.getElementById('anchor');
bronteDialog.show(anchorPoint);
});
It turns out that the show function accepts an argument which is an anchor for the dialog. But whatever I do, the dialog is at the top. Any help would be appreciated!
You can add this to the CSS:
dialog {
position: fixed;
}

how to reset scroll position in a div using javascript

I am working on a mobile hybrid application.
In my html page, I have 3 tabs. When clicking a tab, the content of the scrollable div gets changed. My problem is when I scroll down the content of div (view) and click another tab, the content disappears (but the content is there). Please help me so I can reset the div scroll position when clicking any tab.
Please give me suggestions only with JavaScript or CSS, not with JQuery as I am not using the JQuery library.
Without seeing code, i can just guess.
If you want to reset the scroll position you can simply use
window.scrollTo(0,0);
add this code to your each tab click functions so that when ever you click any tab, it resets to top.
If you have any specific div that has overflow property
var myDiv = document.getElementById('specificDiv');
myDiv.scrollTop = 0;
It is easy
<div id="test" style="height:150px; width:600px;overflow-y:auto;background-color:gray;">
<div style="width:150px;height:500px; background-color:green;"></div>
</div>
document.getElementById('test').scrollTop =0;
Finally this worked for me
function resetScrollPos(selector) {
var divs = document.querySelectorAll(selector);
for (var p = 0; p < divs.length; p++) {
if (Boolean(divs[p].style.transform)) { //for IE(10) and firefox
divs[p].style.transform = 'translate3d(0px, 0px, 0px)';
} else { //for chrome and safari
divs[p].style['-webkit-transform'] = 'translate3d(0px, 0px, 0px)';
}
}
}
resetScrollPos('.mblScrollableViewContainer');
Calling this function after transition between view ,will reset my scroll position.
i used this on my inverted comments section and it worked.
instead of id i had class.
i needed for scrollbar to be at the bottom each time user adds comment.
so i put this on submit button.
const myDiv = document.getElementsByClassName('comments-container');
myDiv[0].scrollTop = 0;

How to disable scroll bar nicely?

I created this javascript function which disables the scrolling of the page content when the side menu is shown: (like a fb on mobile app)
function disableScroll(){
var top = $(window).scrollTop();
var left = $(window).scrollLeft();
$('body').css('overflow', 'hidden');
$(window).scroll(function(){
$(this).scrollTop(top).scrollLeft(left);
});
}
However, whenever I try to scroll the side menu, the page content shows the scroll bar moving up and going back to its original position. How do I prevent that from showing cos it looks really ugly.
I tried fixed the scroll position using CSS but it will automatically bring my page to the top which is not what i want. i want it to stay at the position where the user last clicked the button for the side menu to appear.
You should also set overflow: hidden to the body element.. Then the scroll bar won't be shown at all. Return it back to the original overflow afterwards.
JQUERY
$('body').delegate('#element', 'click', function() {
$("body").css('overflow', 'hidden');
});
This could maybe fix your problem?

Adjusting the position of FB.ui() dialog box

I'm using Fb.ui() to post an update to user's wall but the dialog always appears in the same spot in my browser (center middle if scrolled up). The problem is that I'm opening the dialog from the bottom of the screen. Is there a way to get the dialog to show for the user's current scroll location?
The FB.ui() dialog should already be positionned relative to the place the user scroll currently is.
If not, you can simply position your #fb-root in CSS :
#fb-root { position:fixed; top:10%; }
That way, the pop-in will always be on the scroll position of the user and also follow it if he continue to scroll up or down the page.
I'm using this piece of code to set the dialog position to the top of the page, but you can use it to set the position anywhere you want. This code uses the jQuery library
setInterval(function(){
var dialog = $('.fb_dialog');
for(var i = 0; i < dialog.length; i++)
{
var d = $(dialog[i]);
if(parseInt(d.css('top')) > 0 && parseInt(d.css('top')) != 195)
{
d.css('top', '195px')
}
}
}, 500);
The facebook write the dialog html code to the <div class="fb-root"></div> so if you surround it with a <div style="position: absolute;"></div> the dialog appears where you put this code.
For example:
<div style="position: absolute">
<div class="fb-root"></div>
</div>

Categories