Could you please give me tips how to make drop-down menu disappear on scroll up and down?
It is a little bit hard to find it in pure js. Just what path to follow and I will figure out myself.
window.onsrcoll = function(){
var position = 0;
var scPos = (this.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0);
position += scPos;
if(position > scPos) {
// code here to hide drop-down menu.
}
}
/* on smaller size screens when it becomes drop down menu */
#media(max-width: 880px) {
#navi {
display: none;
}
.navWrapper label[for="mygtukas"] {
background: url(images/open.png);
background-size: 100% 100%;
display: block;
width: 55px;
height: 45px;
cursor: pointer;
position: absolute;
right: 2%;
filter: invert(85%);
transition: all 0.5s;
}
.navWrapper input[type="checkbox"]:checked ~ #navi {
display: block;
user-select: none;
position: absolute;
}
<div class="navWrapper" >
<h1 id="myLogo"><span class="initial">E.</span><span class="name">Erlandas</span> Petronis</h1>
<div class="shadow"></div>
<label for="mygtukas" id="icon"></label>
<input type="checkbox" id="mygtukas">
<ul id="navi">
<li id="li"><a id="link" class="active" href="#home">Home</a></li>
<li id="li"><a id="link" href="#about">About</a></li>
<li id="li"><a id="link" href="#portfolio">Portfolio</a></li>
<li id="li"><a id="link" href="#contact">Contact</a></li>
</ul>
</div>
JS does not work, at least does not make sense or am i off the track here?
As I can see that you want to make the drop-down menu disappear when scrolling down.
One way to do it would be by using Javascript.
What you can do is take the getElementById to change the style top of the navbar to make it disappear when scrolling down.
You can do something like this in javascript :
var position = window.pageYOffset;
window.onsrcoll = function(){
var scPos = window.pageYOffset;
if(position>scPos) {
document.getElementById("navbar").style.top = "0";
} else {
document.getElementById("navbar").style.top = "-50px";
}
position = scPos;
}
For this to work, you'll have to give your navbar a position: fixed; and top: 0;
Hide menu on scroll
Related
I have got a video that appears in a light box from you tube, a custom one not a plugin.
On mobile when displayed portrait the video spans the full page width which looks nice and leaves some room at the top and bottom to click out.
The issue is when I go landscape the video fills the full screen and you cannot get back onto the page. My initial reaction was to hit the phones back button but I don't know a way of getting this to simply remove my lightbox. Is there a way in JS of getting a onclick off the phones back button?
The reason it goes full screen is because I am keeping the aspect ratio
var width: number = $('.youtube-video-lightbox').outerWidth();
var height: number = (width / 16) * 9;
$('.youtube-video-lightbox').height(height);
You can try using the following code:
You need to listen to navigation event and state.direction.
$(window).on("navigate", function (event, data) {
var direction = data.state.direction;
if (direction == 'back') {
// close the light box here
}
if (direction == 'forward') {
// do something else
}
});
More details in this link
Tested the above code in my mobile and it works fine. You might need to stop the program flow after closing the light box so that default navigation of the back button is stopped.
Weave: http://kodeweave.sourceforge.net/editor/#e110ed7e89c3a38335739656a02f9850
Have you thought of trying a Pure CSS Based Lightbox?
$('[data-target]').on('click', function() {
$('.page').attr('src', $(this).attr('data-target'));
});
$('#call').on('change', function() {
(this.checked) ? "" : $('.page').attr('src', '');
});
input[id=call] {
display: none;
}
a {
margin: 1em;
}
.bg,
.content {
opacity: 0;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transition: all ease-in 150ms;
}
.bg {
background: #515151;
background: rgba(0, 0, 0, 0.58);
}
.content {
margin: 2.6352em;
padding: 1em;
background: #fff;
}
input[id=call]:checked ~ .bg,
input[id=call]:checked ~ .content {
visibility: visible;
opacity: 1;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="call" type="checkbox" />
<p>
<a href="javascript:void(0)" data-target="http://bing.com/" class="pointer block">
<label for="call" class="pointer">Bing</label>
</a>
<a href="javascript:void(0)" data-target="http://duckduckgo.com/" class="pointer block">
<label for="call" class="pointer">DuckDuckGo</label>
</a>
</p>
<label for="call" class="bg pointer"></label>
<div class="content">
<iframe width="100%" height="100%" frameborder="0" class="page"></iframe>
</div>
I have a ul with fixed height, which contian dynamic number of li elements, if too many a scrollbar appaers. You can select a lielement by clicking on it.
What I want is the lielement that is active to be fixed at the top if scrolling aboveit or fixed at the bottom if scrolling below it, so the active li element is always showing, and the other li elements just scrolls past the active one.
I have made a plunker. I am using Angular, and I dont know if this can be solved just using CSS or if I need a directive etc. for this.
Html:
div class="parent">
<div class="child1">
<input ng-model="vm.query" type="text" placeholder="Search" />
<ul >
<li ng-repeat="todo in todos" ng-class="{'active': todo.active}" ng-click="activeTodo($index)">
<a>{{todo.name}}</a>
</li>
</ul>
</div>
CSS:
.parent{
display: flex;
}
.child1{
background-color: #eeeeee;
height: 500px;
overflow:scroll;
}
.active{
background-color: red;
position:fixed;
}
Thanks in advance!
I managed this using some CSS and making a directive.
Made a plunker here.
I made a directive which every li element got. Then with jquery in the directive I get the necessary elements like the div which have the scroll, the current li element etc.
Two booleans for checking if the li is fixed at the top or bottom. And then just check if the current scrollPosition(scrollTop) is higher or lower then the current li element. And it also check so the li element got the active boolean attached too it.
return {
restrict: 'A',
link: function($scope, element, attributes){
var scrollDiv = $('#scrollDiv'),
liElement = element,
liElementTop = parseInt(liElement.offset().top),
scrollDivTop = parseInt(scrollDiv.offset().top),
isFixedTop = false,
isFixedBottom = false;
liElement.width(scrollDiv.width());
scrollDiv.on('scroll', function(){
var scrollTop = scrollDiv.scrollTop();
if (!isFixedBottom && !isFixedTop && scrollTop <= liElementTop - (scrollDivTop+(scrollDiv.height()-liElement.height())) && liElement.hasClass("active")) {
isFixedBottom = true;
liElement.css({'position': 'fixed', 'top': scrollDivTop+(scrollDiv.height()-liElement.height()+1),'list-style-type':'none','z-index':'10'});
} else if (isFixedBottom && !isFixedTop && scrollTop >= liElementTop - (scrollDivTop+(scrollDiv.height()-liElement.height()))) {
isFixedBottom = false;
liElement.css({'position': 'static', 'top': 0});
}
else if (!isFixedTop && !isFixedBottom && scrollTop >= liElementTop - scrollDivTop && liElement.hasClass("active")) {
isFixedTop = true;
liElement.css({'position': 'fixed', 'top': scrollDivTop,'list-style-type':'none','z-index':'10'});
}
else if (isFixedTop && !isFixedBottom && scrollTop <= liElementTop - scrollDivTop) {
isFixedTop = false;
liElement.css({'position': 'static', 'top': 0});
}
})
}
};
The consideration of using pure CSS: One of the best solution is this, because those who perhaps want to make an element remain fixed while it is scrolling up and down!
body {
margin: 10px;
}
ul {
display: block;
width: 210px;
max-height: 120px;
overflow-y: auto;
margin: 0;
padding: 0;
}
li {
padding: 8px 10px;
display: block;
font-size: 13px;
cursor: pointer;
background-color: #ddd;
}
li.fixed {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background-color: #111;
color: #f2f2f2;
}
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
<li>Item6</li>
<li>Item7</li>
<li>Item8</li>
<li>Item9</li>
<li>Item10</li>
<li>Item11</li>
<li>Item12</li>
<li>Item13</li>
<li>Item14</li>
<li>Item15</li>
<li>Item16</li>
<li>Item17</li>
<li>Item18</li>
<li>Item19</li>
<li>Item20</li>
<li>Item21</li>
<li>Item22</li>
<li>Item23</li>
<li>Item24</li>
<li>Item25</li>
<li>Item26</li>
<li>Item27</li>
<li>Item28</li>
<li>Item29</li>
<li>Item30</li>
<li>Item31</li>
<li>Item32</li>
<li>Item33</li>
<li>Item34</li>
<li>Item35</li>
<li>Item36</li>
<li>Item37</li>
<li>Item38</li>
<li>Item39</li>
<li>Item40</li>
<li>Item41</li>
<li>Item42</li>
<li>Item43</li>
<li>Item44</li>
<li>Item45</li>
<li>Item46</li>
<li>Item47</li>
<li>Item48</li>
<li>Item49</li>
<li>Item50</li>
<li class="fixed">HEADER</li>
</ul>
If I understood you correctly you like the active div on top.
to solve this in css
use position:relative on parent and position:absolute on the child element with top:0
I'm trying about effect like "news", where the text will every 5 second fadeOut and next text will show on previous position. But, i have link in arrays and i cant click on it and select it too. Like the text wouldnt be text and be image or slider.
Here is my code:
$(document).ready(function() {
var pages = ["<li class='active'><a id='click' href='http://www.seznam.cz'>link1</a></li>", "<li class='active'><a href='#'>link2</a></li>", "<li class='active'><a href='#'>link3</a></li>"]
var index = 0;
setInterval(function() {
$("#ul_news").html(pages[index]);
index++;
if (index >= pages.length){
index = 0;
}
$(".active").delay(4000).fadeOut(1000);
}, 5000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul_news">
</ul>
Here it's working, but it doesnt work on my website: My Website
Can you tell me what is different between this code and code on my website?
It's not working because there's a div overlapping it. (<div class="Menu">)
Change the height of .Menu to the proper height instead of 768px.
.Menu {
height: 80px;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 18;
}
In your website <div class="menu"> is overlapping the links , set the height of .Menu to auto
.Menu {
height: auto;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 18;
}
I have a responsive design that when viewed on a device less than 600px wide, uses drop down multi-level navigation. It is nested inside a header that is set to position: fixed. The problem is, that when you drop down the menu the menu overflows downward and does not scroll (because the header is fixed), so the tabs are not visible. Is there a way (using Javascript, jQuery or PHP) to dynamically set it so that when the drop down menu (by way of clicking on the hamburger menu icon in the top right or left), it changes the header's position from fixed to relative?
A good example would be www.dribbble.com. When it's less than 800px wide, the header is sticky (fixed), then when you click on the menu in the top left, it's obvious that the header's position automatically changes to relative.
HTML
<header role="banner" class="secondary">
<em>Menu</em> <span aria-hidden="true"></span>
<nav id="nav" role="navigation">
<ul class="menu set">
<li class="subnav">
Link
<ul class="sub-menu">
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
</ul>
</nav>
</header>
CSS
header[role="banner"] {
width: 100%;
background: #fff;
display: block;
margin: 0 auto;
padding: 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.25);
z-index: 10000;
}
#media all and (min-width: 500px) {
header[role="banner"] {
position: fixed;
top: 0;
left: 0;
clear: both;
height: auto;
display: block;
}
}
#media all and (max-width: 499px) {
header[role="banner"] {
position: fixed;
}
}
JavaScript
$(document).ready(function() {
$('body').addClass('js');
var $menu = $('#nav'),
$menulink = $('.menu-toggle'),
$menuTrigger = $('.subnav > a');
$menulink.click(function(e) {
e.preventDefault();
$menulink.toggleClass('active');
$menu.toggleClass('active');
});
var add_toggle_links = function() {
if ($('.menu-toggle').is(":visible")){
if ($(".toggle-link").length > 0){
}
else{
$('.subnav > a').before('<span class="toggle-link">Open</span>');
$('.toggle-link').click(function(e) {
var $this = $(this);
$this.toggleClass('active').siblings('ul').toggleClass('active');
});
}
}
else{
$('.toggle-link').empty();
}
}
add_toggle_links();
$(window).bind("resize", add_toggle_links);
});
Well, if you have a custom id or some other kind of attribute for a selector than you can change the position CSS property in multiple ways.
CSS3
#media all and (max-width: 800px) {
header[role="banner"] {
position: relative;
}
}
jQuery
$(document).ready(function() {
$('.menu-toggle').click(function() {
if ($( document ).width() < 499)
$('header[role="banner"]').css('position', 'relative');
else
$('header[role="banner"]').css('position', 'fixed');
});
});
Note: You edited your post. Did you realized that you used position: fixed; in both of your CSS #media rules? Change the second to position: relative;.
I have a slide down menu. In HTML I have:
<menu>
<li id="vysledky">Výsledky
<ul class="menu2">
<li>2008
<ul class="menu3">
<li>21.08. - MMSR SCg</li>
<li>R SCOOechová Potôň SK</li>
<li>SCOOTER Brezová /Visonta/ HU</li>
</ul>
</li>
<li>2010</li>
<li>2011<</li>
</ul>
</li>
<li id="forum"><span>Fórum</span></li>
</menu>
And now i want to automaticly set the width of each 3rd level of menu (menu3) by the longest text in it. So in this example the width of this .menu3 will be the width of text "SCOOTER Brezová /Visonta/ HU".
I can't use css because the width of menu2 is stable and if it will be longer than menu2 its set to width of menu2 (cascade)
So i would use javascript (jquery). I have this code:
var i;
var podm;
$('menu>li').each(function() {
podm = 0;
if($(this).children('ul').size()) {
$(this).each(function() {
if($(this).children('ul').size()) {
$(this).each(function() {
podm++;
i = 60;
$(this).find('li a').each(function() {
var w = $(this).text();
$('#js').text(w);
w = $('#js').width();
if(w > i) {
i = w;
}
});
$(this).find("ul.menu3").css("width");
});
}
});
}
});
But this code works bad :-(.
Web: Here
You set the width of the menu3 ul to 345px which causes longer text to overlap. The Javascript just sets this width again.
<ul class="menu3" style="width: 345px; display: block; opacity: 0.13">
Try to remove the width specification and the jQuery code and check if it works. If you need a specific minimum width for the level 3 menu, you can use the min-width CSS attribute.
EDIT:
Ok, spotted it. The problem is the position: relative attribute in .menu3. The CSS for .menu3 should look like this:
.menu3 {
display: none;
position: absolute; /* This changed */
padding: 0;
margin: 0;
list-style: none;
left: 100px;
top: 0px; /* This changed */
background: #464646 url('3menu-po.png') repeat-y;
display: none;
white-space: nowrap;
}
Note the position: absolute. This takes the submenu out of the document flow and therefore it is not affected by the width set in .menu2.