side menu scroll lags on safari (ios) - javascript

I have a mobile website which has a simple side menu bar with scroll, when scrolling the menu on safari it lags a lot (struggle to scroll).
here is the html:
<body>
<div id="menu_background" onclick="toggleMenu()"></div>
<div id="menu">
<ul>
<li>
<div>item 1</div>
</li>
//other items goes here
</ul>
</div>
<div id="global_container">
//some content goes here
</div>
</body>
here is the css:
#menu
{
position: absolute;
top: 0px;
bottom: 0px;
z-index: 100;
overflow: hidden;
display:none;
width: 0%;
padding: 1%;
}
and the javascript :
var menuShown = false;
function toggleMenu(){
var menu = document.getElementById("menu");
var menuBackground = document.getElementById("menu_background");
var globalContainer = document.getElementById("global_container");
if(!menuShown){
menuShown = true;
menuBackground.style.visibility = "visible" ;
menu.style.width="60%";
menu.style.display="block";
menu.style.overflowY="auto";
globalContainer.style.position="fixed";
globalContainer.style.right="62%";
}
else{
menuShown = false;
menuBackground.style.visibility = "hidden" ;
menu.style.width="0%";
menu.style.display="none";
menu.style.overflowY="hidden";
globalContainer.style.position="static";
}
}
I didn't include the rest of html where there is a menu button with onclick action that trigger the toggleMenu() javascript function.
Also I don't want to use ready made jQuery plugins or other solutions.
any suggestions ?

Solved using the following in the css:
rather than using the following in the css #menu selector
overflow: hidden;
use this instead
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;

Related

Slide in hamburger menu adds horizontal scrollbar

The result should be a hamburger menu with slides in from the right on clicking the icon.
This is the code for the main menu where I translate it to the right 100% and when I click on the icon it translates back to 0% bringing it on screen
HTML
<div id="mobilenav" class="mobile-nav">
<div class="mobile-nav-header">
</div>
<div class="hamburger">
<button (click)="closeMenu()">
<img src="../../assets/icons/close-menu.svg" alt="" />
</button>
</div>
</div>
<ul class="links">
</ul>
<div class="socials">
</div>
</div>
.mobile-nav {
height: 100vh;
top: 0;
position: absolute;
transform: translateX(100%);
right: 0;
transition: 0.5s;
background: white;
z-index: 99;
}
The JS
openMenu() {
var mobile_menu = document.getElementById('mobilenav');
mobile_menu!.style.transform = 'translateY(0px)';
// mobile_menu!.style.display = 'block';
}
closeMenu() {
var mobile_menu = document.getElementById('mobilenav');
mobile_menu!.style.transform = 'translateX(100%)';
// mobile_menu!.style.display = 'none';
}
The issue is that when closed, it is still possible for the user to scroll horizontally to the right. That should not be possible as the menu should be hidden and there should be no possibility to scroll horizontally.
The simplest way is to replace position: absolute with position: fixed. This fixes the problem but still allows the page to be horizontally scrollable if needed.
Alternatively, you could add
body {
overflow-x: hidden;
}
to remove the horizontal scrollbar.

footnote with javascript: how hide it clicking anywhere

I have a website with several papers with footnotes.
So far I have adopted the classic system of referring to the footnotes at the bottom of the article with an internal link, from which you then return to the body of the paper by clicking on the note number.
But I found that it is possible with javascript to have a more comfortable system that keeps the footnote inside the screen you are reading on.
The code is this:
function toggleDiv (divId) {
$ ("#" + divId) .toggle ();
}
.dynamicnote {display: none;
position: fixed;
bottom: 2%;
margin-left: auto;
margin-right: auto;}
1
<p id = "n1" class="dynamicnote"> 1 [sometext] </p>
The problem is that this works perfeclty if I click on the anchor (once read the note), and then the footnote disappears; otherwise, if I click the next anchor the new footnote goes over the previous one, and it is ugly and confusing.
You can see this script at this url
How to fix? Perhaps with a javascript command to hide the div shown clicking anyywhere?
updated answer: If this is worse let me know and i'll put the old one back.
update two: This works only on the second click, so the first link will not have the animation (but still works like in the first one). I am still working on the solution for the first click. Again, if this is worse, let me know.
var currDiv = 'footNote';
function toggleDiv(divId) {
if(currDiv=='footNote'){
document.getElementById('footTwo').classList.add('no-height');
document.getElementById('footTwo').innerHTML='';
document.getElementById('footNote').classList.remove('no-height');
var elem = document.getElementById(divId).cloneNode(true);
elem.id = 'fntext';
document.getElementById('footNote').appendChild(elem);
var ftnt= document.getElementById('fntext');
ftnt.replaceWith(...ftnt.childNodes);
currDiv=0;
}else{
document.getElementById('footNote').classList.add('no-height');
document.getElementById('footNote').innerHTML='';
document.getElementById('footTwo').classList.remove('no-height');
var elem = document.getElementById(divId).cloneNode(true);
elem.id = 'fntext';
document.getElementById('footTwo').appendChild(elem);
var ftnt= document.getElementById('fntext');
ftnt.replaceWith(...ftnt.childNodes);
currDiv = 'footNote';
}
}
document.addEventListener("click", e => {
if(e.target.className!=='href'){
document.getElementById('footNote').innerHTML = '';
document.getElementById('footTwo').innerHTML = '';
}
});
.ftn {
position: fixed;
bottom: 10%;
margin-left: auto;
margin-right: auto;
max-height: 100%;
overflow: hidden;
transition: max-height 0.8s ease-in-out;
}
.no-height {
max-height:0;
transition: max-height 0.8s ease-in-out;
overflow-y: hidden;
}
.hide {
display: none;
color: red;
}
<a href="#1a" onclick='toggleDiv("n1")' id="1a" class='href'> 1 </a>
<div id="n1" class="hide">
1 [sometext]
</div>
<br>
<a href="#2a" onclick='toggleDiv("n2")' id="2a" class='href'> 2 </a>
<div id="n2" class="hide">
2 [sometext2]
</div>
<div id='footNote' class='ftn'> </div>
<div id='footTwo' class='ftn'> </div>

Hiding scrollbar and making custom scrollbar

So I wanted to make a page like https://www.guillaumetomasi.com/ .How can I hide the scrollbar and make a custom one like that in the page.
With CSS attributes like overflow-x: hidden and overflow-y: hidden you can hide scrollbars.
The custom scrollbar and the scrolling proccess is controlled by Javascript via and events.
The thing is simple and that's, they are not using any scrolling at all, but what you feel is a modified scroll for those slides is actually a slideshow built by JavaScript functionalities. These side slideshow are nowadays in trend and gives you a feel of pseudo scroll. It will be better if you would ask how to achieve that slideshow in a web page instead of that scrolling...
The scroll bar can be hidden with css ::-webkit-scrollbar {width: 0px;}
The custom scroll bar is made with javascript. Here's an example of how it could be done:
window.addEventListener("scroll", function() {
var section1 = document.getElementById("section1");
var section2 = document.getElementById("section2");
var section3 = document.getElementById("section3");
var indicator = document.getElementById("scroll-indicator");
if (window.scrollY < section2.offsetTop ) { // If scroll height is above section 2
indicator.innerText = "1"
}
if (window.scrollY > (section1.offsetTop + section1.offsetHeight)) { // If scrolled past section 1
indicator.innerText = "2"
}
if (window.scrollY > (section2.offsetTop + section2.offsetHeight)) {// If scrolled past section 2
indicator.innerText = "3"
}
});
p {
position: fixed;
right: 15%;
top: 50%;
color: black;
font-size: 24px;
font-family: arial;
}
::-webkit-scrollbar {
width: 0px; /*This removes the scroll bar*/
}
<div id="section1" style="height: 500px; background-color: lightblue">Scroll Down</div>
<div id="section2" style="height: 500px; background-color: pink">Keep scrolling</div>
<div id="section3" style="height: 500px; background-color: Khaki">Almost there</div>
<p id="scroll-indicator">1</p>

Disable and Enable Scroll Window when resizing viewports in jquery

I have here a navbar with a dropdown menu and I wanted the page to stop scrolling when I stretch out the whole screen to another resolution. I have reviewed my code and I think the problem is the conditions in my if-else statement. I am stuck in this for hours now and I cannot formulate a solution to my problem. I also added a label in my html aria-label="hidden" to use for enabling and disabling the whole page scroll. Can someone enlighten me with this problem I am currently having now?
Here is my code snippet:
<div class="c-dropdown-btn"><i class="fas fa-bars c-grey-pill"></i></div>
<div id="c-nav-mobile" aria-label="hidden">
<ul class="c-nav-links2">
<li>カテゴリ1</li>
<li>カテゴリ2</li>
<li>カテゴリ3</li>
<li>カテゴリ4</li>
</ul>
<div class="c-img-cont2">
<div class="c-image-res3"></div>
<div class="c-consult-cont2">
<div class="c-con-rel"><span class="c-consult-text2">自分のキャリアに合った留学を選ぶための無料相談会実施中</span>
<button class="c-btn c-btn-primary consult-text">詳しくはこちら→</button>
</div>
</div>
</div>
</div>
And here is my jquery code for this:
$('.c-dropdown-btn i').click(function () {
$(this).toggleClass('fa-times');
$('#c-nav-mobile').fadeToggle("on");
bodyStyle();
});
$(window).resize(function(){
bodyStyle();
});
function bodyStyle() {
var viewportWidth = $(window).width();
var navMobile = $("#c-nav-mobile");
if(viewportWidth < 768 && navMobile.attr("aria-label") == "hidden") {
$("body").css("overflow", "hidden");
console.log("abc");
} else if (viewportWidth > 769 && navMobile.attr("aria-label") == "hidden"){
$("body").css("overflow", "none");
console.log("123");
}
}
for scss snippet (for #c-nav-mobile)
#c-{
&nav-mobile {
display: none;
position: absolute;
left: 0;
z-index: 1;
top: 41px;
width: 100%;
height: 523px;
padding: 25px 32px 34px 31px;
background: rgba(0,0,0,0.5);
#include mq('md') {
display: none !important;
}
&.on {
display: block;
}
}
}
I declared a function and called it inside resize and also to my click event.
#c-nav-mobile add this:
box-sizing: border-box;
CSS media queries do most of the work for you.
You can eliminate much of the JS here by using css rules inside a class. Then only use JS to toggle the tag - which you are already doing but do so on the body tag.
HTML (just added the body tag for completeness)
<body>
<div class="c-dropdown-btn"><i class="fas fa-bars c-grey-pill"></i></div>
<div id="c-nav-mobile" aria-label="hidden">
<ul class="c-nav-links2">
<li>カテゴリ1</li>
<li>カテゴリ2</li>
<li>カテゴリ3</li>
<li>カテゴリ4</li>
</ul>
<div class="c-img-cont2">
<div class="c-image-res3"></div>
<div class="c-consult-cont2">
<div class="c-con-rel"><span class="c-consult-text2">自分のキャリアに合った留学を選ぶための無料相談会実施中</span>
<button class="c-btn c-btn-primary consult-text">詳しくはこちら→</button>
</div>
</div>
</div>
</div>
</div>
</body>
CSS
// code below works if it's the body that is doing the scrolling
// if not, use the scrolling element instead here and the JS click
#media only screen and (max-width: 768px) {
body.fa-times {
overflow: hidden;
// might need to set a height
height: 100vh;
}
}
JS
$('.c-dropdown-btn i').click(function () {
$('body').toggleClass('fa-times');
$('#c-nav-mobile').fadeToggle("on");
});

How to add in- and -out transition effect to multiple modals at once using CSS and JS?

First post, so hopefully it is clear enough.
I have been tasked to create a modal object that overlays a multi-column/-row grid layout on a page. The modal should appear on hover of a particular grid item. When the modal appears, the background of the grid area only should dim. I was asked not to use any additionally libraries (e.g., jQuery).
To complete this task, I added two modal objects, one for the actual modal window and the other for the dimmer object. I could not get the CSS hover to work for both objects on the hover of the item in question, so I used JavaScript to add the CSS changes.
The transition effect works for the transition in but not the transition out. I assume I am overthinking this task so appreciate any suggestions.
<style type="text/css">
.container {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 10px;
margin: 0;
padding: 0;
}
.column {
background-color: hsl(0,80%,70%);
}
#modal_maker {
font-size: 5vw;
height: 100%;
width:100%;
display:flex;
align-items: center;
justify-content: center;
}
#modal_maker, #modal {
z-index: 2;
}
#modal {
visibility: hidden;
background-color: hsl(200,50%,70%);
width: 80%;
height: 80%;
position: absolute;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
opacity: 0;
transition: opacity 1s;
}
#background-dimmer {
visibility: hidden;
background-color: black;
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
opacity: 0;
transition: opacity 0.5s;
}
</style>
<body>
<div class="container">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column" id="modal_maker">Hover Here</div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
<div id="modal"></div>
<div id="background-dimmer"></div>
</div>
<script type="text/javascript">
document.querySelector(".container").addEventListener("mouseover", function(el) {
if (el.target.id=="modal_maker" || el.target.id=="modal") {
document.getElementById("modal").style.cssText = "visibility:visible; opacity: 1;"
document.getElementById("background-dimmer").style.cssText = "visibility:visible; opacity: 0.75;"
} else {
document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="opacity: 0; visibility:hidden;")
}
})
</script>
</body>
Its all because of visibility:hidden
in js
...
} else {
document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="opacity: 0; visibility:hidden;")
}
...
in instant way you change opacity to 0 but also visibility:hidden so there is no time for transition, right away when code fires element is hiding.
You use cssText to change properties of element so visibility:visible won't be there when you move mouse on the other element, instead there will be visibility:hidden from the css(so you need to delete that also).
I know that it casues #modal to capture mouseover event then... thats the problem to figure out
I don't know if this solution is on purpose to hide modal when you mouseover other element only, what if I will leave mouse entirely from the table, the modal will stay... just wanted to mention maybe its not relevent.
I made fiddle based on your code: https://jsfiddle.net/svh6dpfk/1/
One idea to fix this #modal capturing event is adding proper visibility as a callback(there is transitionend event which will capture moment when animation is done, so something like this would help:
document.querySelector("#modal, #background-dimmer").addEventListener("transitionend", function(el) {
if(parseFloat(el.target.style.opacity) > 0){
el.target.style.cssText = "visibility:visible;opacity:1";
alert("animation end visible");
}else{
el.target.style.cssText = "visibility:hidden;opacity:0";
alert("animation end unvisible");
}
});
Update
it does work right now for me...
its a bit tricky, your css needs to have visibility:hidden for modal and background-dimmer(like your code has)
this seems to work for me:
document.querySelector(".container").addEventListener("mouseover", function(el) {
if (el.target.id=="modal_maker" || el.target.id=="modal") {
document.getElementById("modal").style.cssText = "visibility:visible;opacity: 1;"
document.getElementById("background-dimmer").style.cssText = "visibility:visible;opacity: 0.75;"
} else {
if(document.getElementById("modal").style.opacity == "1"){
document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="visibility:visible;opacity: 0; ")
}
/* alert("should be on leave") */;
}
})
this part .forEach(x => x.style.cssText="visibility:visible;opacity: 0; ") changes because your css has always visibility:hidden, so you need to perform transition always on visible.
full example:
https://jsfiddle.net/Loary65w/1/
you need to remember to have cross browser support you need to cover all those events
webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend
Hope it helps. Maybe there is better solution much simpler and I overcomplicated that one :F

Categories

Resources