I have a scrollable dropdown menu and I want to keep the last item fixed and always visible on top while all the other items would scroll. However, with my solution it's really jumpy. Here's what I have so far:
HTML:
<ul class="menu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li class="fixed">Item 10</li> <!-- this item will be fixed and always on top -->
</ul>
Javascript:
this.$('.menu').on('scroll', function() {
if (stickyItem = $('.fixed')) {
//get the y position of the parent
topHeight = stickyItem.parent().offset().top;
//how far apart the sticky item should always be from the top of the bar
heightDiff = stickyItem.parent().height() - stickyItem.height();
if ((stickyItem.offset().top - topHeight) < heightDiff) {
heightApply = heightDiff + ( heightDiff - (stickyItem.offset().top - stickyItem.parent().offset().top));
stickyItem.css('top', (heightApply)+'px');
}
}
});
CSS:
ul li.fixed {
position: absolute;
bottom: 0;
}
Is there an easier way to accomplish what I'm trying to do? Thanks!
I have not tested anywhere besides chrome, but here's a pure CSS solution for your problem:
html,body{height:100%; margin:0; padding:0}
ul {margin: 0; padding:0; height:auto;
/*this padding bottom allows the penultimate element to be displayed*/
padding-bottom:39px}
ul li {padding:10px; background:#eee; color:#333;
font-family:sans-serif; border-bottom:1px solid #CCC; }
ul li.fixed { /*you could also use the :last pseudo selector*/
width:100%;
position: fixed;
bottom: 0;
background:lightblue;
}
https://jsfiddle.net/patareco/kb99u78p/1/
Hope it does what you intended.
Related
I am attempting to use two selectable lists with the same selectable class, I want to toggle all the items irrespective of the parent list when a selection is made.
Currently when I select an item, only the selections from the same list get toggled/unselected, but the selected item from the other list remains selected.
Is there any way to have these as two separate lists but behave as the same one, for this specific function?
Any help would be appreciated. Thank You.
$( ".selectable" ).selectable();
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<style>
div {border:1px solid black;}
.selectable .ui-selecting { background: #FECA40; }
.selectable .ui-selected { background: #F39814; color: white; }
.selectable { list-style-type: none; margin: 0; width: 60%; }
.selectable li { margin: 3px; padding: 0.4em; font-size: 1.4em; height: 18px; }
</style>
<div id="div1">
<h4>List 1</h4>
<ul class="selectable">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
</ul>
</div>
<div id="div2">
<h4>List 2</h4>
<ul class="selectable">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
</ul>
</div>
I suppose what I was trying to achieve here is what is defined under a different widget, you would call menu.
Changing the script to:
$(".selectable").menu();
gave the desired result.
I'm in the process to create a Wordpress Template wheres on some point the user can add a list on the site with one picture.
The height of the img should be proportional as tall as the list
So the img can't have a statement like {object-position: cover}
The img and the list should be centered
i've been struggling with this since days..
I tried with img position absolute and height 100% but then the container doesn't center correctly because of the missing width of the img
I tried with HTML table
and basically everything that comes in my mind
I searched in the internet, but came up with no solution..
maybe i have to try to solving this Problem with javascript..
my problem in a pic
you can use display:table proprty of css to solve your issue. here is demo
CSS
.parent{
display:table; /* make it table*/
width:100%;
table-layout:fixed;
}
.parent > *{
display:table-cell; /* make it table-cell*/
height:100%;/* take max-height from both childs*/
width:50%;
border:1px solid #000;
vertical-align: top;
}
.parent > div img{
max-width:100%;
height:100%;
}
.parent ul{
padding:0;
}
.parent li{
padding:10px;
color:#000;
}
HTML
<div class="parent">
<div><img src="https://dummyimage.com/600x400/000/fff" alt="Image"></div>
<ul>
<li>List 1</li>
<li>List 2</li>
<li>List 5</li>
<li>List 1</li>
<li>List 2</li>
<li>List 5</li>
<li>List 6</li>
<li>List 7</li>
<li>List 8</li>
<li>List 9</li>
<li>List 10</li>
<li>List 11</li>
</ul>
</div>
Okay so here is a cut down of what I have so far JSFiddle. Hovering over 'Aviation' brings down the menu. I would like it so that when you open the menu the first menu item is already set to active but also need the current hovered selection to stay selected when they move over the the "Related Links" side of the drop down.
I know very little JS but this is what I have come up with so far to make the menu appear.
$(document).ready(function() {
$(".aviation").hover(function() {
$(".aviation-menu").toggleClass("active");
});
});
$(document).ready(function() {
$(".aviation-menu").hover(function() {
$(".aviation-menu").toggleClass("active");
});
});
$(document).ready(function() {
$("#top li").hover(function() {
$(this).addClass("active");
}, function() {
$(this).removeClass("active");
});
});
Any help would massively be appriciated thank you.
I think you can use it like below, I gave the Jsfiddle link at the bottom as well:
$(document).ready(function() {
$(".aviation").hover(function() {
$(".aviation-menu").toggleClass("active");
});
});
$(document).ready(function() {
$("li").hover(function() {
$("li").each(function() {
$(this).removeClass("active");
});
$(this).addClass("active");
});
});
JSFIDDLE
Basically you will be removing all the "active" classes on the other list items when any of them gets hovered, so it will have one active all the time.
Edit: You can also add this $("li").first().addClass("active"); at the beginning so it will have "Home" as active by default.
You should consider the following: There is no "hovering" on mobile devices and what you're doing with JS (adding a class on hover, but actually what you want is a visual change) can be done with CSS, which is nicer in my opinion.
Here is a great example of a pure CSS dropdown menu by Phil Hoyt: http://codepen.io/philhoyt/pen/ujHzd
HTML:
<h1>Simple Pure CSS Drop Down Menu</h1>
<nav id="primary_nav_wrap">
<ul>
<li class="current-menu-item">Home</li>
<li>Menu 1
<ul>
<li>Sub Menu 1</li>
<li>Sub Menu 2</li>
<li>Sub Menu 3</li>
<li>Sub Menu 4
<ul>
<li>Deep Menu 1
<ul>
<li>Sub Deep 1</li>
<li>Sub Deep 2</li>
<li>Sub Deep 3</li>
<li>Sub Deep 4</li>
</ul>
</li>
<li>Deep Menu 2</li>
</ul>
</li>
<li>Sub Menu 5</li>
</ul>
</li>
<li>Menu 2
<ul>
<li>Sub Menu 1</li>
<li>Sub Menu 2</li>
<li>Sub Menu 3</li>
</ul>
</li>
<li>Menu 3
<ul>
<li class="dir">Sub Menu 1</li>
<li class="dir">Sub Menu 2 THIS IS SO LONG IT MIGHT CAUSE AN ISSEUE BUT MAYBE NOT?
<ul>
<li>Category 1</li>
<li>Category 2</li>
<li>Category 3</li>
<li>Category 4</li>
<li>Category 5</li>
</ul>
</li>
<li>Sub Menu 3</li>
<li>Sub Menu 4</li>
<li>Sub Menu 5</li>
</ul>
</li>
<li>Menu 4</li>
<li>Menu 5</li>
<li>Menu 6</li>
<li>Contact Us</li>
</ul>
</nav>
CSS:
#primary_nav_wrap
{
margin-top:15px
}
#primary_nav_wrap ul
{
list-style:none;
position:relative;
float:left;
margin:0;
padding:0
}
#primary_nav_wrap ul a
{
display:block;
color:#333;
text-decoration:none;
font-weight:700;
font-size:12px;
line-height:32px;
padding:0 15px;
font-family:"HelveticaNeue","Helvetica Neue",Helvetica,Arial,sans-serif
}
#primary_nav_wrap ul li
{
position:relative;
float:left;
margin:0;
padding:0
}
#primary_nav_wrap ul li.current-menu-item
{
background:#ddd
}
#primary_nav_wrap ul li:hover
{
background:#f6f6f6
}
#primary_nav_wrap ul ul
{
display:none;
position:absolute;
top:100%;
left:0;
background:#fff;
padding:0
}
#primary_nav_wrap ul ul li
{
float:none;
width:200px
}
#primary_nav_wrap ul ul a
{
line-height:120%;
padding:10px 15px
}
#primary_nav_wrap ul ul ul
{
top:0;
left:100%
}
#primary_nav_wrap ul li:hover > ul
{
display:block
}
I have a menu-submenu-subsubmenu construction in HTML like this:
<menu>
<li>Item 1</li>
<li><ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li><ul>
<li>Sub-subitem 1</li>
<li>Sub-subitem 2</li>
<li>Sub-subitem 3</li>
</ul>
Subitem 3</li>
<li>Subitem 4</li>
</ul>
Item 2
</li>
<li>Item 3</li>
<li>Item 4</li>
...using whit this css formating:
menu {
display: block;
width: 200px;
}
/* hide subitems */
menu li ul,
menu li ul li ul {
display: none;
position: absolute;
}
/* set up positions */
menu li ul {
left: 200px;
width: 200px;
}
menu li ul li ul {
left: 400px;
width: 200px;
}
I use this jQuery code:
$(function() {
/* hide all submenu */
$('menu').find('ul').hide();
/* show submenu on mouseenter */
$('menu li a').mouseenter(function() {
$(this).parent().children('ul').show();
}).mouseleave(function() {
$(this).parent().children('ul').hide();
});
});
How can I detect mouse is leaving the element to their child? Or how can I get the child element to stay if it's necessary?
Change your code to be like this:
$(function() {
/* hide all submenu */
$('menu').find('ul').hide();
/* show submenu on mouseenter */
// here, just select the direct child
$('menu').find('li > a, li > ul').mouseenter(function() {
var time = new Date().getTime();
$(this).parent().find('ul').show().data('showing-time', time);
}).mouseleave(function() {
var leaveTime = new Date().getTime();
var $this = $(this);
window.setTimeout(function () {
var $ul = $this.parent().find('ul');
var beginTime = $ul.data('showing-time') || 0;
if (leaveTime > beginTime) {
$this.parent().find('ul').hide().data('showing-time', 0);
}
}, 100);
});
});
Hope this helps.
update
Code updated.
I suggest just put the sub menus next to the parent menu item(here, means li > a element) to get a better result.
Here's how I would go about it. You don't need javascript at all, at least not for simple hiding/showing. But, if you want to add delays, I would strongly suggest using jquery only to add/remove appropriate css classes with a settimeout.
css:
.menu {
position: relative;
display: inline-block;
}
.submenu {
display: none;
position: absolute;
left: 100%;
}
.menu li:hover > .submenu, .submenu.show {
display: inline-block;
}
html:
<ul class="menu">
<li>Item 1</li>
<li><ul class="submenu">
<li>Subitem 1</li>
<li>Subitem 2</li>
<li><ul class="submenu">
<li>Sub-subitem 1</li>
<li>Sub-subitem 2</li>
<li>Sub-subitem 3</li>
</ul>
Subitem 3</li>
<li>Subitem 4</li>
</ul>
Item 2
</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
js:
$('body').on('mouseleave','.submenu', function(e) {
var jTarget = $(e.currentTarget).addClass('show');
setTimeout(function() {
jTarget.removeClass('show');
}, 500);
})
Check out this jsfiddle with the js delay:
http://jsfiddle.net/LxL4N/1/
Guys, I have the following HTML. Is it possible for the #underdiv to scroll under the #topdiv? I want to achieve the effect of having a list of items and to be able to scroll it up and down while keeping the #topdiv always visible on top of it. Can it be done just with the CSS or do I have to add some Javascript magic? I also have JQuery and JQueryMobile (as this is meant for an iOS device) included in the file but I kept them out to make the HTML look simpler.
Thanks in advance for helping me out!
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
#underdiv {
background-color: red;
position: relative;
top: -40px;
width: 80%;
margin: 0 auto;
}
#topdiv {
background-color: yellow;
}
</style>
</head>
<body>
<div id="topdiv">
<h1>Random title</h1>
<p>This is a random paragraph bla bla bla bla yada yada yada</p>
</div>
<div id="underdiv">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
<li>Item 12</li>
<li>Item 13</li>
<li>Item 14</li>
<li>Item 15</li>
<li>Item 16</li>
<li>Item 17</li>
<li>Item 18</li>
<li>Item 19</li>
<li>Item 20</li>
</ul>
</div>
</body>
</html>
it's possible, though the scrollbar disappears under too;
ul {
margin: 0;
padding: 40px 0 0 30px;
}
#underdiv {
background-color: red;
width: 80%;
margin: 0 auto;
height: 200px;
overflow: auto;
margin-top: -40px;
}
#topdiv {
background-color: yellow;
padding: 1px; /* to stop margins collapsing */
position: relative;
}
remove position:relative from underiv and add position:fixed to topdiv.
Look at the resut here