How can I scroll to an element inside a scrollable div? - javascript

I have a parent container which has two child elements. The left element is a list of items returned from a database query. The parent container has a fixed height, so any items returned in the left panel are scrollable within that left panel, not the body.
When navigating to this page, I would like for the left panel to be positioned at the point of a matching element ID. This ID i will handle through Angular's routing subscriptions, but for demo purposes I have hard coded it here.
I have tried the code below (primarily the JS) with no luck. Any assistance would be greatly appreciated.
var list = document.getElementById("list");
var targetLi = document.getElementById('myID');
list.scrollTop = (targetLi.offsetTop - 50);
#wrapper {
width:1280px;
height:600px;
border:1px solid #d9d9d9;
border-radius:5px;
display:flex;
margin:20px auto;
}
#list {
width:200px;
height:100%;
border-right:1px solid #d9d9d9;
display:flex;
overflow:hidden;
}
#right span {
color:#999;
font-size:12px;
font-family:helvetica;
}
ul {
width:100%;
margin:0;
padding:0;
list-style:none;
overflow-y: scroll;
}
li {
width:100%;
padding:20px 10px;
box-sizing:border-box;
border-bottom:1px solid #d9d9d9;
display:block;
font-family:helvetica;
color:#666;
}
<div id="wrapper">
<div id="list">
<ul>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li> <li>
Item
</li> <li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li>
Item
</li>
<li id="myID">
Item with ID
</li>
</ul>
</div>
<div id="right">
<button id="button">Demo purposes button</button>
<span> Note: this would instead be called in 'ngAfterViewInit' or after the firestore query has completed.
</div>
</div>

The best (and AFAIK only) option that will work across all browsers is to implement a hidden input element (like a checkbox for example) and set the focus to that element. This way the browser will scroll the container so that the focused input is visible. The trick is not to set the styling to display: none but only make the element optically invisible, for example:
opacity: 0;
width: 0;
height: 0;
display: block;

Related

Open child div on hover parent and close other child divs ( w/ Javascript)

When I open a child div on hover with Javascript it works, also when I hover over the next parent div that child div opens but when I go back to the first parent the second one stays open (on top) and doesn't fade-out.
What I would like is that the other child div('s) close when hovering to a new one. Maybe good to know is that I only want the other child div(s) to close when hovering to a new parent with a child div not when im just hovering out of the current parent.
Does anyone know the trick?
$('li.menu-item-has-children').hover(function () {
$('ul.dropdown-menu-main', this).fadeIn('slow');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
I found the solution when 'parent()' and 'children()' are not 'this'.
$('li.menu-item-has-children').hover(function () {
$('ul.dropdown-menu-main', this).fadeIn('slow');
$(this).parent().children().not(this).find('ul.dropdown-menu-main').fadeOut('fast');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
Sorry have just re-read your question and realised you wanted the menu to stay active. I've created a demonstration which does this by adding an .active class and toggling the submenus are you initially wanted using fadeIn and fadeOut. This will also allow you to attribute css styles to the dropdown if you would rather use that rather than jquery.
// Toggle function on hover, ignore if already active
$(".menu-item-has-children:not('.active')").hover( function() {
// Remove active class from all menus
$(".menu-item-has-children.active").toggleClass();
// Add toggle class to this menu
$(this).toggleClass("active");
// Fade out existing dropdown menus
$(".dropdown-menu-main").fadeOut('slow');
// Fade in this child dropdown menu
$(this).find(".dropdown-menu-main").fadeIn('slow');
});
The second example I will leave up for others, it shows how to do a more traditional dropdown where it fades out once the hover leaves the parent. You can use the exit function as well as the entry function of hover, the first function you provide is ran on mouseenter and the second on mouseleave.
Jquery .hover()
EXAMPLE WITH PERSISTENT DROPDOWNS
// Toggle function on hover, ignore if already active
$(".menu-item-has-children:not('.active')").hover( function() {
// Remove active class from all menus
$(".menu-item-has-children.active").toggleClass();
// Add toggle class to this menu
$(this).toggleClass("active");
// Fade out existing dropdown menus
$(".dropdown-menu-main").fadeOut('slow');
// Fade in this child dropdown menu
$(this).find(".dropdown-menu-main").fadeIn('slow');
});
ul, ul li {
list-style:none;
padding:0;
margin:0;
}
li {
display: inline-block;
position: relative;
margin-right:20px !important;
}
ul.dropdown-menu-main {
display:none;
position:fixed;
top:0px;
left:0px;
width:100%;
height:100vh;
background:black;
z-index:-1;
padding:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>
EXAMPLE WITH TRADITIONAL DROPDOWNS
These collapse when the hovering over the parent ends.
// Hover function
$('li.menu-item-has-children').hover(
// Hover in function
function() {
$('ul.dropdown-menu-main', this).fadeIn('slow');
},
// Hover exit function
function() {
$('ul.dropdown-menu-main', this).fadeOut('slow');
}
);
ul,
ul li {
list-style: none;
padding: 0;
margin: 0;
}
li {
display: inline-block;
position: relative;
margin-right: 20px !important;
}
ul.dropdown-menu-main {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100vh;
background: black;
z-index: -1;
padding: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="menu-item-has-children">
<a href="#">Main 1</div>
<ul class="dropdown-menu-main">
<li>Sub 1</li>
</ul>
</li>
<li class="menu-item-has-children">
<a href="#">Main 2</div>
<ul class="dropdown-menu-main">
<li>Sub 2</li>
</ul>
</li>
</ul>

Dropdown menu hidden within navbar

i'm doing a project in which I have to make a website from scratch using no frameworks. The problem i'm having is that I'd like to make a navigation bar that can collapse down on mobile devices aswell as have a dropdown menu on a desktop.
I've managed to get it properly working for mobile devices, but when on a desktop the dropdown menus just hide within the nav bar container. I believe this is a problem where the height isn't adjusting for the dropdown, but i'm not too sure how i'd fix it. The navigation bar has to be fixed to the top, collapse when below 900px and the dropdowns must be visible when hovering over them.
The Website in question is
http://www.ico.mmu.ac.uk/13143651/webdev/
CSS
nav {
background-color: #b8b8b8;
font-family: arial;
position: fixed;
top: 0;
z-index:999;
text-decoration: none;
width: 100%;
padding:0px;
overflow:auto;
margin:0px;
clear:both;
}
HTML
<nav role="navigation">
<ul class="slimmenu" id="navigation">
<li>
Courses
<ul>
<li>Digital Media</li>
<li>Web Development</li>
<li>Journalism</li>
<li>Information Communications</li>
</ul>
</li>
<li>
Facilities
<ul>
<li>Societies</li>
<li>Jobs and Placements</li>
<li>Library</li>
</ul>
</li>
<li>
Manchester and Student Life
<ul>
<li>Travel</li>
<li>Attractions</li>
<li>Nightlife</li>
</ul>
</li>
<li>
Student Help
<ul>
<li>Finance</li>
<li>Student Union</li>
<li>Assistance</li>
</ul>
</li>
<li>Contact</li>
</nav>
Thanks in advance.
In your css, change your .nav overflow rule.
From
overflow: auto
to
overflow: visible
It's hard to know what the desired behaviour is, but you can try variations on this:
ul.slimmenu li > ul{
position: fixed;
top: 50px;
left: none;
}

Can you set css min-width relative to another element?

I have a nav menu of links and sub menu. I want the submenu min width to be that of the link. Is this possible in CSS? I'm using LESS if that helps at all.
<ul>
<li>
Item FooBarBaz
<ul class="submenu">
<li><a>sub1</a></li>
<li><a>sub2</a></li>
<li><a>sub3</a></li>
</ul>
</li>
<li>
Item FooBarBazZipBamBop
<ul class="submenu">
<li><a>sub1</a></li>
<li><a>sub2</a></li>
<li><a>sub3</a></li>
</ul>
</li>
</ul>
I want each ul.submenu to have the min-width of the previous sibling anchor. Obviously this would be a potentially different value for each submenu. Is this possible in CSS? Or is jquery, javascript a better solution here?
Sure. Here is an example: http://jsfiddle.net/SeKT9/
ul
{
margin:0;
padding:0;
list-style:none;
}
body > ul > li
{
float: left;
position: relative;
}
ul > li a
{
display: block;
margin: 5px;
}
ul > li:hover > ul
{
display: block;
}
ul > li > ul
{
position: absolute;
min-width: 100%;
background-color: green;
display: none;
}
ul > li > ul > li
{
display: block;
}
Maybe just adding an inline-block div around each submenu is quicker/easier? I'm always hesitant to add many lines of code for a small simple effect.
<ul>
<li>
<div style='display:inline-block;'>
Item FooBarBaz
<ul class="submenu">
<li><a>sub1</a></li>
<li><a>sub2</a></li>
<li><a>sub3</a></li>
</ul>
</div>
</li>
<li>
<div style='display:inline-block;'>
Item FooBarBazZipBamBop
<ul class="submenu">
<li><a>sub1</a></li>
<li><a>sub2</a></li>
<li><a>sub3</a></li>
</ul>
</div>
</li>
</ul>

How to make a drop-right menu?

I have a Menu with ToolGroups:
I want to let appear a sub-menu on the right side of an hovered toolgroup div. How can I realize this with html5, javascript(also jQuery) and CSS?
EDIT: Source code on JsFiddle
<div id="menu">
<center><h1>Toolbox</h1></center>
<hr/>
<div class="toolGroup">MyToolGroup&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup2&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup3&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup4&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup5&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup6&Rightarrow;</div>
<hr/>
<div class="toolGroup">MyToolGroup7&Rightarrow;</div>
<hr/>
<br/>
</div>
#menu
{
position: absolute;
top: 20px;
left: 20px;
background-color: #c0c0c0;
border-radius: 8px;
padding: 10px 10px 10px 10px;
}
.toolGroup
{
cursor: pointer;
text-align: center;
font-size: 18px;
font-weight: bold;
}
Here is the simple css solution for it http://jsfiddle.net/Mohinder/UJErC/
HTML
<ul class="toolgroup">
<li>Toolgroup
<ul>
<li>Toolgroup
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
</li>
</ul>
</li>
<li>Toolgroup
<ul>
<li>Toolgroup
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
</li>
</ul>
</li>
<li>Toolgroup
<ul>
<li>Toolgroup
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
</li>
</ul>
</li>
<li>Toolgroup
<ul>
<li>Toolgroup
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
<li>Toolgroup</li>
</li>
</ul>
</li>
</ul>
CSS
body,ul,li { margin:0px; padding:0px; }
.toolgroup,.toolgroup li ul { padding:0px; list-style:none; width:150px; background:#ccc; border:1px solid #000; }
.toolgroup li,.toolgroup li ul li { width:100%; position:relative; }
.toolgroup li a,.toolgroup li ul li a { padding:7px 10px; display:block; border-bottom:1px solid #000; }
.toolgroup li ul { display:none; position:absolute; left:150px; top:0px; }
.toolgroup li:hover ul { display:block; }
You could use a hover event on some child lists:
http://jsfiddle.net/qAZFC/1/
HTML:
<div class="toolGroup">MyToolGroup4&Rightarrow;
<ul>
<li>Test item</li>
<li>Test item</li>
<li>Test item</li>
</ul>
</div>
CSS:
.toolGroup ul {
display:none;
}
.toolGroup:hover ul {
display:block;
}
Or with jQuery, bind a mouseenter/mouseout event and fade in:
http://jsfiddle.net/7TPab/1/
You need to have the menus on the right already existing and formatted via HTML and CSS. Once this is done, set them all to display:none via CSS.
Now we move on to javascript (I'll show you a jQuery solution because it's easier and you suggested it).
Something like this should accomplish your task:
$(function(){
$(MyToolGroup).hover(function(){
$(MyToolGroupSubMenu).css("display","box")
},function(){
$(MyToolGroupSubMenu).css("display","none")
})
})
This is a VERY simple, stripped down version just to get you moving in the right direction.
The important thing is to next your sub-menu inside of each relating toolgroup, this way the hover handler applies to both the menu item as well as the sub-menu item.
Please note that the selectors in the code above are just pseudo code, I can't use your code because you did not supply it, but replace them as applicable.
Here's a basic jsfiddle http://jsfiddle.net/rsEGZ/1/
The only reason I recommend javascript (and jQuery) instead of CSS is because it allows for the freedom to grow this into something more intricate through animations and callbacks.
BUT, here is the CSS solution http://jsfiddle.net/rsEGZ/2/

CSS Menu disappear

I created a menu in html/css but where I wanted the subitems to be shown on parent item hover. The problem is when I hover on it in IE it only shows it's subitems when I hover on the text in the menu item, If I hover over the element and not the text the subitems disappear again. So if I hover and want to move my mouse to my submenu the submenu disappears unless I'm fast enough. This is very annoying, does anyone know how I can solve this?
MY menu code is like so:
<ul id="leftnav">
<li><a>Item1</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</ul>
The menu should be a left sided menu which shows it's subitems only on hover, so I used css to achieve this with the following code:
#leftnav, #leftnav ul
{
padding: 0;
margin: 0;
}
#leftnav ul li
{
margin-left: 102px;
position: relative;
top: -19px; /*sets the childitems on the same height as the parent item*/
}
#leftnav li
{
float: left;
width: 100px;
}
#leftnav ul
{
position: absolute;
width: 100px;
left: -1000px; /*makes it disappear*/
}
#leftnav li:hover ul, #leftnav li.ie_does_hover ul
{
left: auto;
}
#leftnav a
{
display: block;
height: 15px;
margin-top: 2px;
margin-bottom: 2px;
}
Since this only works with firefox I also had to insert a javascript to get this to work in IE using code:
<script language="JavaScript">
sfHover = function()
{
var sfElsE = document.getElementById("leftnav").getElementsByTagName("LI");
for (var i=0; i<sfElsE.length; i++)
{
sfElsE[i].onmouseover=function()
{
this.className+=" ie_does_hover";
}
sfElsE[i].onmouseout=function()
{
this.className=this.className.replace(new RegExp(" ie_does_hover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
</script>
Many many many thanks for replies
In your CSS you have:
#leftnav li:hover ul
Which would mean the rule is applied to ul elements that are children of li elements when that parent li is hovered.
But in your HTML, you have:
<li><a>Item2</a></li>
<ul>
<li><a href='#'>SubItem1</a></li>
</ul>
So the sub item ul is not a child of the item ul, so that rule never comes true. You need to make the sub-items nested to the items. Like this:
<ul id="leftnav">
<li><a>Item1</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
<li><a>Item2</a>
<ul>
<li><a href='#'>SubItem1</a></li>
<li><a href='#'>SubItem2</a></li>
<li><a href='#'>SubItem3</a></li>
</ul>
</li>
</ul>
Notice how I don't close the list item until after the sub-list.
Reinventing the wheel: http://www.htmldog.com/articles/suckerfish/ teaches you about it. They even have a great example.

Categories