I'm having trouble with redefining the height property of a div that acts as a background for a dropdown menu. The idea is that when you click on an item in the list, the nested list and background div slide out, and then if you click on another item in the main list, the first nested list and background div slide up, the new list and the background div then slide down. My touble is that the background div height isn't getting redefined, and it keeps the height of the first list. Here's my jquery:
$(function() {
$( "ul.hmenu li a" ).click(function() {
var parentUlHeight = $("ul.hmenu").outerHeight(true) - 1;
var newUlHeight, oldUlHeight;
// REMOVE OLD SELECTION
$(".currentSelection").siblings('ul').slideUp("fast"); //find old selection and slide up its sibling ul
oldUlHeight = $(".currentSelection").siblings('ul').height();
$('#subnavdiv').slideUp("fast");
$(".currentSelection").removeClass("currentSelection"); //remove the class from the old selection
// MAKE NEW CURRENT SELECTION
$(this).addClass("currentSelection");
newUlHeight = $(".currentSelection").siblings('ul').height(); //calc height of new current selection subnav
$(this).siblings('ul').slideDown("slow");
// ANIMATE DIV BACKGROUND
$('#subnavdiv').css( "top", parentUlHeight + "px" ); //position div at right height
$('#subnavdiv').height( newUlHeight ); // set height to new selection height -- NOT WORKING
$('#subnavdiv').slideDown("slow");
});
});
HTML:
<nav class="nav clearfix desktop-nav" style="left: 146px;">
<ul class="hmenu">
<li class="item-103 current active">Home
<li class="item-105 deeper parent">
Our Team
<ul class="hmenu-left-to-right" style="">
<li class="item-145">link</li>
<li class="item-146">link</li>
</ul>
</li>
</ul>
<div id="subnavdiv"></div>
CSS
#subnavdiv {
width: 900px;
background: #607852;
display: none;
position: absolute;
-webkit-border-radius: 0 0 25px 25px;
-moz-border-radius: 0 0 25px 25px;
border-radius: 0 0 25px 25px;
}
Any Help is much appreciated!
This should get you close to what you're looking for
http://jsfiddle.net/F9De4/
you might instead add a class name ".main-link" to your anchor tag instead of "ul.hmenu li a"
$(".main-link").toggle(function(){
var newUlHeight = $(this).parent().find(".hmenu-left-to-right").height();
$(this).parent().find(".hmenu-left-to-right").hide("fast");
$('#subnavdiv').hide();
$("#subnavdiv").css("height",newUlHeight);
$('#subnavdiv').slideDown("slow");
},function(){
var newUlHeight = $(this).parent().find(".hmenu-left-to-right").height();
$(this).parent().find(".hmenu-left-to-right").show("fast");
$('#subnavdiv').hide();
$("#subnavdiv").css("height",newUlHeight);
$('#subnavdiv').slideDown("slow");
});
Related
I'm currently working on a website and I'm having a trouble with anchors. My header is fixed and when I click on anchor it sends me on other page how it is supposed to be, but I'm missing 80 pixels which is height of my fixed header. There is a script that made accordion opened on new page when I click on anchor but it should scroll 80px less... here is some code I have over there in my .jsp file
<a href="${parentLink}#${menuItem.name}" class="${menuItem.classes[anchorClasses]}">
and there is a .js that makes my accordion opened on the new page
$(document).ready(function () {
if (location.hash != null && location.hash != "") {
$('.collapse').removeClass('in');
$(location.hash + '.collapse').collapse('show');
}
});
I think that you guys will need more info, so ask me anything that could help you. I'm new in this and I don't even know which code should I post here to help you guys realize what the problem is... Thank you (:
One common way is to add an invisible pseudo element to the original target element of the link via CSS, like this:
#your_anchor_id::before {
display: block;
content: " ";
margin-top: -80px;
height: 80px;
visibility: hidden;
pointer-events: none;
}
This will "extend" the element with that ID in a way which causes the anchor to be 80px above the main element, without causing any other visible changes.
Another idea is to use smooth scrolling with an offset. (View the example "Full Page" by clicking that link at top right of the snippet window)
$("nav ul li a").on('click', function(event) {
if (this.hash !== "") {
var myOffset = $('#myOff').val(); //get value from input (offset value)
if (myOffset==='') $('input').addClass('alert');
event.preventDefault(); // Prevent default anchor click behavior
var hash = this.hash; // Store hash
// jQuery animate() method for smooth page scroll
// 900 is the number of ms to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top - myOffset
}, 900);
} // End if
});
//$('div:contains(Section)').css('font-weight','bold');
html,body{margin:0;padding:0;font-family:Calibri;}
body{height:2500px;}
ul,li{margin:0;padding:0;}
*{box-sizing:border-box;}
section{
display: grid;
place-items: center;
width: 100%;
height: 500px;
}
nav{position:fixed;width:80vw;background:white;border:1px solid red;}
::placeholder{color:#ccc;}
nav ul li{
display: inline-block;
padding:0;
border: 1px solid rgba(200,200,200,0.3);
}
nav ul li:hover{background: #ddd;}
a{text-decoration:none;padding:10px 25px;display:inline-block;}
#one{background:palegreen; padding:50px;}
#two{background:palegoldenrod;}
#twa{background:lightblue;}
#fer{height:1500px;}
.alert{border:1px solid red;background:#ffc0cb99;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>NAV / HEADER:</li>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li><input id="myOff" type="text" placeholder="Offset (e.g. 75):" /></li>
</ul>
</nav>
<section id="one">
<div>
<div style="text-align:center">Section One</div>
<div>Directions:<br>(a) View as Full Page (link at top right)<br>(b) Enter offset number (for how many pixels the smooth-scroll will stop short)<br>(c) Click nav "Two" or "Three" and observe<br>(4) Repeat using a different offset value<br>Note: The fixed header is deliberately not full width in order to show the top of the next section scrolling UNDER the header (undesireable) The offset prevents that, and is what you are asking about.</div>
</div>
</section>
<section id="two">
Section Two
</section>
<section id="twa">
Section Three
</section>
<section id="fer">
Section Four
</section>
Example code ripped off from:
w3schools Company Theme example
I have div with fixed width and height. Div contains unordered list and has css overflow-y: scroll property. In javascript I have function which triggers when user click button below list, and that function adds one list item. When there is too much content inside div, new list items are added at the bottom of list and user needs to scroll list in order to see new list items. Is it possible somehow to make scroll bar auto scroll along with new content added, so that last added list item would be always visible?
Html:
<ul id="scroll">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
<button type="button" id="click">Click</button>
Css:
ul {
height: 100px;
width: 100px;
overflow-y: scroll;
border: 1px solid black;
}
Javascript:
function addListItem(){
var message = document.createElement('li');
message.innerHTML = 'd';
document.getElementById('scroll').appendChild(message);
}
document.getElementById('click').addEventListener('click', addListItem, true);
JS fiddle link: https://jsfiddle.net/8gjhatvt/2/
Set the Element.scrollTop property of the scrolling div to be the position of the new element in the page + the new element's offset in its parent.
For example in the addListItem() function add the following line:
document.getElementById('scroll').scrollTop = message.offsetHeight + message.offsetTop;
Working fiddle: https://jsfiddle.net/rvnj6mc3/
Add this code to addListItem() function:
var scroll=document.getElementById("scroll");
scroll.scrollTop = scroll.scrollHeight;
Currently, I have three tabs in my nav bar, BOARD, SKILLS, and ABOUT, all in one container with a boarder-bottom for the container. When I click on one of the divs, the appropriate div name is selected, to indicate which tab I am on. That is what is currently working and can be seen in my codePen.io:
What I have so far - click here
.
What I am trying to do is when I go from BOARD to SKILLS or BOARD to ABOUT, is to have a bar slide from one one tab to the next, rather than being static-like (which is what I have currently) e.g. a smooth scroller on click from one tab to the next. How can I go about doing this? I have no idea where to begin.
You can use this function to slide an element:
function scaleSlider(to) {
var $slider = $('.slider', '.tabs'),
$elSpan = to.find('span'),
width = $elSpan.width(),
left = $elSpan.position().left;
$slider.animate({
width: width,
left: left
});
}
In your HTML you need to add the .slider element:
<div class="col-md-8 tabs">
<div class="slider"></div>
<!-- your html here -->
</div>
CSS:
.tabs .slider {
position: absolute;
height:100%;
border-bottom: 4px solid grey;
}
So when you click a menu element you call scaleSlider:
$('.skills').on("click", function() {
//Your code here
scaleSlider($(this));
});
Please check out this demo: http://codepen.io/anon/pen/EyoBmg
I have a div that contains a ul with a lot of li's. The div's height is smaller than the height the li's cover so I have overflow auto on the css for div.
sample html
<div class="points-area">
<ul class="points-list">
<li class="point selected" id="startPoint">Start</li>
<li class="point" id="endPoint">End</li>
<li class="point" id="N">Nasion</li>
<li class="point" id="S">Stella center</li>
<li class="point" id="P">Porion</li>
<li class="point" id="ar">Artikulare</li>
<li class="point" id="T1">T1</li>
<li class="point" id="Me">Me</li>
<li class="point" id="Gn">Gnathion</li>
<li class="point" id="T2/MT1">T2/MT1</li>
</ul>
</div>
css
.points-list{
list-style: none;
padding: 0;
margin-top: 0;
}
li.point{
border-bottom: 1px solid black;
padding: 0.1em;
}
.points-area{
overflow: auto;
height: 20em;
border: 1px solid black;
}
li.point.selected,
li.point:hover{
background-color: blue;
}
I have some javascript that when something user adds a circle on a kineticjs stage the next li gets selected (toggled selected class).
if (! $("li.point.selected").is(":last-child")){
prevLi = $("li.point.selected");
prevLi.next().toggleClass('selected');
prevLi.toggleClass('selected');
toBeAdded = prevLi.next();
}
so in my javascript code after a circle is added it toggles the 'selected' class name on the next li.
My problem is that because points are more than div's hieght can handle, the scrollbar doesnt move when I move down the li's. So e.g
scroll area reaches as far as li with text value porion. All li's bellow that are not shown cause of scrollbar. I need when changing from Porion Artikulare (toggling selected class) the overflow to scroll down a bit so that the li can appear on the div area. How can this be achieved?
It is very simple. all you need to know is 'you div height', 'li height', scrolltop and scrollto functions in JS / JQ.
calculate the scrollTop using number of li's u need to scroll, and use scrollTo inorder to scroll to particular position on scroll bar!!
if you have your codes in plnkr / JSFiddle etc.. please share it, i can help you with it
I think I got it! This is the updated fiddle
I added this piece of code
var divHeight, liHeight, lisPerScrollPage;
divHeight = $(".points-area").height(); //caluclate divs height
liHeight = $("li.point").outerHeight(true);// calculate li's height with padding margin etc
lisPerScrollPage = parseInt(divHeight / liHeight); //calculate how many li's fits a scroll page
Then I just checked to see if the li i am selecting is inside the scroll area and if its not move the scroll area as much ase needed. If the scroll area is allready lower and it can be shown don't do nothing (in case user manually used the scrollbar)
index = $("li.point").index(toBeAdded) + 1;
if ($(".points-area").scrollTop() < liHeight *(index - lisPerScrollPage))
{
$(".points-area").scrollTop(liHeight *(index - lisPerScrollPage));
}
I think it works as I want to.
Working on creating a small jquery plugin for a client's website that is a simple breadcrumb system using anchor tags, that changes the last element in the breadcrumb list based on which anchor tag is currently visible. Further, I'm using HTML5 data- elements to store each page name, so that I can add that as the second element in the breadcrumb list as well.
For visibility, I'm using this plugin: https://github.com/zeusdeux/isInViewport
This is the fiddle I'm working with: http://jsfiddle.net/7F59C/4/
Here is the HTML:
<div class="header">head element
<div id="breadcrumbs" data-page="About">
<ul>
<li>Home</li>
<li class="currentpage"></li>
<li class="active"></li>
</ul>
</div>
</div>
<div class="spacer"></div>
<div class="gridContainer">
<div class="space">
take up some space<br />
<a class="crumb" id="About" href="#">About Us</a>
</div>
<div class="space">
take up more space<br />
<a class="crumb" id="Other_heading" href="#">Other heading</a>
</div>
</div>
The JS:
$(document).ready(function() {
$jbread();
});
$.fn.jbread = function () {
//set bc as breadcrumbs list
var bc = $("#breadcrumbs");
//BUILD CURRENT PAGE BREADCRUMB ITEM
//set currentpage to current page's data-page value
var currentpage = bc.data("page");
//set currentpage_link to current page's url
var currentpage_link = window.location.pathname;
//add currentpage as next li in breadcrumbs list
$(".currentpage").html('' + currentpage + '');
//UPDATE ACTIVE ITEM IN BREADCRUMB LIST
$.fn.updateCrumbs = function () {
var currentactive = $(e.target);
$(".active").html(currentactive);
}
//WORK WITH ISINVIEWPORT PLUGIN
$('div.gridContainer > a.crumb').updateCrumbs();
$('div.gridContainer > a.crumb:in-viewport(10)').updateCrumbs();
$(window).scroll(function() {
$('div.gridContainer > a.crumb').updateCrumbs();
$('div.gridContainer > a.crumb:in-viewport(250)').updateCrumbs();
});
//STYLE BREADCRUMB LIST
};
And, for good measure, CSS:
#breadcrumbs ul {
list-style: none;
float: left;
padding: 2px;
}
#breadcrumbs ul li a {
text-decoration: none;
color: black;
}
.space {
height: 500px;
background-color: red;
}
.header {
position: fixed;
height: 100px;
background-color: #FFF;
width: 100%;
margin-top: 0;
}
.spacer {
min-height: 100px;
}
INTENDED FUNCTIONALITY:
As the user is scrolling down the page, when one of the anchor tags with the class "crumb" comes intoViewport (which I have set as 250-350 pixels down the page), I would like the list item with the class of "active" to be updated with the anchor tag that just triggered the function. I'm not sure if I'm using $(e.target) correctly, or if it will even reference the correct thing.
I'm hoping to get this function working, and then I need to create an actual demo page to flesh out styling the list after it is populated. That's for another question.
Any thoughts, comments, or criticisms are welcome as I am very new to jQuery and am questioning my logic on this one.
Looks like you want something like
$.fn.updateCrumbs = function () {
var currentactive = this.text();
$(".active").text(currentactive);
}