Navigation sliding line on hover (and active state) - javascript

I'd spinning this off this original post: https://stackoverflow.com/a/65040903/1406440
I used something similar years ago (https://codepen.io/moy/pen/pZdjMX) but it uses a lot of jQuery in comparison. So I was wondering if I can amend the example in the original post to achieve the same effect. Which would mean...
Updating so that if there was an 'active' item, the line is already visible and moves from that location.
Is it possible to apply to a class rather than id?
With the above in mind, could this be applied in two separate places or would I need to duplicate the code?
Finally I wonder if we could use a :before or :after class so I don't have a div floating in the ul?
const navBar = document.getElementById("nav");
const navCursor = navBar.querySelector('.cursor');
const navItems = navBar.querySelectorAll('li');
function handleMouseEnterNavItem(event) {
// executed when mouse enter a navigation item
// update cursor to match position and size of target
const { offsetLeft, clientWidth } = event.target;
navCursor.style.left = offsetLeft + 'px';
navCursor.style.width = clientWidth + 'px';
}
navItems.forEach((navItem) => {
navItem.addEventListener('mouseenter', handleMouseEnterNavItem);
});
ul {
position: relative;
}
ul li {
font-family: sans-serif;
text-decoration: none;
color: gray;
margin: 22px 10px 10px;
display: inline-block;
padding: 0; /* note: padding will be underlined */
}
ul .cursor {
background: blue;
height: 1px;
position: absolute;
bottom: 0;
z-index: 10;
transition: .16s all 0.025s;
}
ul a {
text-decoration: none;
}
<ul id="nav" class="tabs-nav">
<li class="active">News</li>
<li>Activities</li>
<li>Search</li>
<li>Time</li>
<div class="cursor"></div>
</ul>

Related

Changing color of Font Awesome icon on click: CSS / JavaScript

Forgive me in advance if I'm being stupid here but I'm trying to change the color of 3 Font Awesome icons from white to black when a menu is clicked on my site using JavaScript to add a class of "active" on top of the current class of "social-icon" so that the CSS is activated.
I'm using a div called 'toggle' as a navbar and currently only the first icon is changed to black when this is clicked. I've tried using querySelectorAll instead but that doesn't work and I've also tried moving the social-icon class to within the font awesome icon class but again nothign. I'm just curious at to where I'm going wrong.
Thanks
JS
const menuToggle = document.querySelector('.toggle')
const showcase = document.querySelector('.showcase')
const socialToggle = document.querySelector('.social-icon')
menuToggle.addEventListener('click', function() {
menuToggle.classList.toggle('active')
showcase.classList.toggle('active')
socialToggle.classList.toggle('active')
})
CSS
.social {
position: fixed;
bottom: 18px;
right: 40px;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
}
.social li {
list-style: none;
}
.social-icon {
display: inline-block;
transform: scale(0.5);
margin-right: 25px;
transition: 0.5s;
font-size: 40px;
cursor: pointer;
}
.social-icon.active {
color: black;
}
HTML
<div class="toggle"></div>
<ul class="social">
<li class="social-icon"><i class="fab fa-facebook-f"></i></li>
<li class="social-icon"><i class="fab fa-instagram"></i></li>
<li class="social-icon"><i class="fab fa-tiktok"></i></li>
</ul>
You can use querySelectorAll to get a node list with all the icons and then iterate them:
const menuToggle = document.querySelector('.toggle');
const showcase = document.querySelector('.showcase');
const socialToggle = document.querySelectorAll('.social-icon');
menuToggle.addEventListener('click', function() {
menuToggle.classList.toggle('active');
showcase.classList.toggle('active');
socialToggle.forEach(function(el) {
el.classList.toggle('active');
});
})

hover on dynamically created list

I have a menu with a list of items created dynamically using javascript.
They have different colour and country attributes created using setAttribute.
$("#menuList a").hover(
function() {
var countryName = $(this).attr('country');
var fruitColour = $(this).attr('colour');
$('#toshow').append($("countryName \n fruitColour"));
},
function() {}
);
.toshow {
display: none;
}
#menuList a:hover div.toshow {
top: 0;
right: 0;
display: block;
position: absolute;
z-index: 99999;
background: red;
width: 200px;
height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menubar" id="menuList">
<li>Watermelon</li>
<li>Grapes</li>
<li>Strawberry</li>
<li>Blueberry</li>
</ul>
<div class="toshow" id="toshow"></div>
Here, I want to have a separated hidden div (display at top right of the page or next to the menuList) that does not have any content until any of the <a> tag being hovered, and show its responding two attributes until no more mouse hovered.
The code does not have errors. But I don't see anything in red when the mouse hovered through the list. Is it possible to achieve what I am looking for?
You can use the mouseout event to hide the toshow div with hide as you leave a list element. And at each hover event, you can change the html of toshow to the values of the li element which the user is hovering over and use show to display it.
Also make sure you attach the event handlers after you've inserted the html of the dynamically generated list.:
function displayGeneratedList() {
$('#menuList').html(`
<li>Watermelon</li>
<li>Grapes</li>
<li>Strawberry</li>
<li>Blueberry</li>
`);
$("#menuList a").hover(function() {
var countryName = $(this).attr('country');
var fruitColour = $(this).attr('colour');
$('#toshow').html(`${countryName}<br>${fruitColour}`).show();
});
$('#menuList a').mouseout(function() {
$('#toshow').hide();
});
}
$(document).ready(function() {
displayGeneratedList();
});
#menuList {
display: inline-block;
}
.toshow {
display: none;
float: right;
background: maroon;
width: 200px;
height: 100px;
padding: 5px;
color: white
}
<ul class="menubar" id="menuList">
</ul>
<div class="toshow" id="toshow"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Dropdown on hover is moving towards left of dropdown image in jQuery

I'm using jQuery for dropdown on hover in Liferay. The dropdown works absolutely fine when I run this jQuery as a separate HTML file, but if I use the same Jquery using the Liferay theme and add HTML in the web content section, the dropdown moves slightly to the left. Below is my CSS, HTML and jQuery code:
/* Flex Level Drop Down Menu
* Created: Jan 5th, 2010 by DynamicDrive.com. This notice must stay intact for usage
* Author: Dynamic Drive at http://www.dynamicdrive.com/
* Visit http://www.dynamicdrive.com/ for full source code
*/
//Version 1.1 (Feb 19th, 2010): Each flex menu (UL) can now be associated with a link dynamically, and/or defined using JavaScript instead of as markup.
//Version 1.2 (July 2nd, 2011): Menu updated to work properly in popular mobile devices such as iPad/iPhone and Android tablets.
//Version 1.3 (Nov 28th, 2011): Script now dynamically adds a class of "selected" to the anchor link while its drop down menu is expanded, for easy styling of the anchor link during its "open" state.
//Version 2.0 (April 16th, 2015): Adds mobile friendly, overlay version of the menu that's activated in mobile and small screen browsers. Refines drop down menu behavior when there's neither space to the right nor left to accommodate sub menu; in that case, sub menu overlaps parent menu. Requires jquery 1.8+
//Usage: $(elementselector).addflexmenu('menuid', options)
//ie:
//jQuery(document).ready(function($){
//$('a.mylinks').addflexmenu('flexmenu1') //apply flex menu with ID "flexmenu1" to links with class="mylinks"
//})
jQuery.noConflict()
var flexdropdownmenu={
arrowpath: 'arrow.gif', //full URL or path to right arrow image
backarrowpath: 'left.gif', //full URL or path to back arrow image
animspeed: 200, //reveal animation speed (in milliseconds)
showhidedelay: [150, 150], //delay before menu appears and disappears when mouse rolls over it, in milliseconds
mobilemediaquery: "screen and (max-width: 600px)", // CSS media query string that when matched activates mobile menu (while hiding default)
//***** NO NEED TO EDIT BEYOND HERE
mobilemql: null,
startzindex:1000,
mobilezindex: 1001,
ismobile:navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i) != null, //boolean check for popular mobile browsers
builtflexmenuids: [], //ids of flex menus already built (to prevent repeated building of same flex menu)
ulclones: {}, // object holding clone of each drop down menu UL
hidemenuevent: navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)/i)? 'touchstart' : 'click', // Mac doesn't seem to support click on body
css3animation: (function(){ // check for CSS3 animation support
var elstyle = document.createElement('p').style
return 'animation' in elstyle || 'WebkitAnimation' in elstyle || 'MozAnimation' in elstyle
})(),
positionul:function($, $ul, e, $anchor){
var istoplevel=$ul.hasClass('jqflexmenu') || $ul.hasClass('flexmenumobile') //Bool indicating whether $ul is top level flex menu or main mobile container
var docrightedge=$(document).scrollLeft()+$(window).width()-40 //40 is to account for shadows in FF
var docbottomedge=$(document).scrollTop()+$(window).height()-40
if (istoplevel){ //if main flex menu DIV
var offsets=$anchor.offset()
var anchorsetting=this.mobilemql.matches? $anchor.data('mobilesetting') : $anchor.data('setting')
var x=offsets.left+anchorsetting.useroffsets[0]+(anchorsetting.dir=="h"? $anchor.outerWidth() : 0) //x pos of main flex menu UL
var y=offsets.top+anchorsetting.useroffsets[1]+(anchorsetting.dir=="h"? 0 : $anchor.outerHeight())
x=(x+$ul.data('dimensions').w > docrightedge)? x-(anchorsetting.useroffsets[0]*2)-$ul.data('dimensions').w+$anchor.outerWidth()+(anchorsetting.dir=="h"? -($anchor.outerWidth()*2) : 0) : x //if not enough horizontal room to the ridge of the cursor
y=(y+$ul.data('dimensions').h > docbottomedge)? y-(anchorsetting.useroffsets[1]*2)-$ul.data('dimensions').h-$anchor.outerHeight()+(anchorsetting.dir=="h"? ($anchor.outerHeight()*2) : 0) : y
}
else{ //if sub level flex menu UL
var $parentli=$ul.data('$parentliref')
var parentlioffset=$parentli.offset()
var x=$ul.data('dimensions').parentliw //x pos of sub UL
var y=0
if ( (parentlioffset.left+x+$ul.data('dimensions').w) > docrightedge ){ //if not enough horizontal room to the ridge parent LI
if ($ul.data('dimensions').w > (parentlioffset.left - $(document).scrollLeft())) // no room to left either?
x = 0
else
x = x-$ul.data('dimensions').parentliw-$ul.data('dimensions').w
}
if ( parentlioffset.top+$ul.data('dimensions').h > docbottomedge ){ //if not enough vertical room to the bottom of parent LI
if ($ul.data('dimensions').h > (parentlioffset.top - $(document).scrollTop())) // no room upwards either?
y = $(document).scrollTop() - parentlioffset.top
else
y = y-$ul.data('dimensions').h+$ul.data('dimensions').parentlih
}
}
$ul.css({left:x, top:y})
},
showbox:function($, $target, $flexmenu, e){
clearTimeout($flexmenu.data('timers').hidetimer)
$flexmenu.data('timers').showtimer=setTimeout(function(){$target.addClass('selected'); $flexmenu.show(flexdropdownmenu.animspeed)}, this.showhidedelay[0])
},
hidebox:function($, $target, $flexmenu){
clearTimeout($flexmenu.data('timers').showtimer)
$flexmenu.data('timers').hidetimer=setTimeout(function(){$target.removeClass('selected'); $flexmenu.hide(100)}, this.showhidedelay[1]) //hide flex menu plus all of its sub ULs
},
buildmobilemenu:function($, mainulid, $target){
var $menu = this.ulclones[mainulid]
function flattenuls($mainul, cloneulBol, callback, finalcall){
var callback = callback || function(){}
var finalcall = finalcall || function(){}
var $headers = $mainul.find('ul').parent()
var $mainulcopy = cloneulBol? $mainul.clone() : $mainul
var $flattened = jQuery(document.createDocumentFragment())
var $headers = $mainulcopy.find('ul').parent()
for (var i=$headers.length-1; i>=0; i--){ // loop through headers backwards, so we end up with topmost UL last
var $header = $headers.eq(i)
var $subul = $header.find('>ul').prependTo($flattened)
callback(i, $header, $subul)
}
$mainulcopy.prependTo($flattened) // Add top most UL to collection
finalcall($mainulcopy)
return $flattened
}
var $flattened = flattenuls($menu, false,
function(i, $header, $subul){
var $breadcrumb = $('<li class="breadcrumb" />')
.html('<img src="' + flexdropdownmenu.backarrowpath + '" class="backarrow" />' + $header.text())
.prependTo($subul)
$subul.css({display:'block', left:0, top:0})
$header.find('a:eq(0)').append('<img src="' + flexdropdownmenu.arrowpath +'" class="rightarrow" />')
$header.bind('click', function(e){
$mobilecontainer.data('h', $subul.outerHeight())
var $headermenu = $(this).parent('ul')
$headermenu.css({zIndex: flexdropdownmenu.mobilezindex++}).animate({left:'-100%', opacity: 0}, function(){this.style.visibility='hidden'})
$subul.css({zIndex: flexdropdownmenu.mobilezindex++, left: '100%', visibility:'visible'}).animate({left:0, opacity: 1})
e.stopPropagation()
e.preventDefault()
})
$breadcrumb.bind('click', function(e){
var $headermenu = $header.parent('ul')
$mobilecontainer.data('h', $headermenu.outerHeight())
$subul.css({zIndex: flexdropdownmenu.mobilezindex++}).animate({left:'100%', opacity: 0}, function(){this.style.visibility='hidden'})
$headermenu.css({zIndex: flexdropdownmenu.mobilezindex++, left: '-100%', visibility:'visible'}).animate({left:0, opacity: 1})
e.stopPropagation()
e.preventDefault()
})
},
function($topul){
$topul.removeAttr("id class").css({zIndex: flexdropdownmenu.mobilezindex++, visibility:'visible', opacity:1, left:0, top:0, display:'block'})
}
)
var $mobilecontainer = $('<div class="flexmenumobile" id="' + mainulid + '-mobile"/>').append($flattened).appendTo(document.body)
$mobilecontainer.css('display', 'block')
$mobilecontainer.data('dimensions', {w:$mobilecontainer.outerWidth(), h:$mobilecontainer.find('ul:eq(0)').outerHeight()}) //remember mobile menu's dimensions
$mobilecontainer.css('display', 'none')
$mobilecontainer.bind('touchstart', function(e){
e.stopPropagation()
})
this.builtflexmenuids.push(mainulid + '-mobile') //remember id of mobile flex menu that was just built
},
buildflexmenu:function($, $menu, $target){
$menu.css({display:'block', visibility:'hidden', zIndex:this.startzindex}).addClass('jqflexmenu').appendTo(document.body)
$menu.bind('mouseenter', function(){
clearTimeout($menu.data('timers').hidetimer)
})
$menu.bind('mouseleave', function(){ //hide menu when mouse moves out of it
flexdropdownmenu.hidebox($, $target, $menu)
})
$menu.bind(this.hidemenuevent, function(e){ //hide menu when mouse moves out of it
e.stopPropagation()
})
$menu.data('dimensions', {w:$menu.outerWidth(), h:$menu.outerHeight()}) //remember main menu's dimensions
$menu.data('timers', {})
var $lis=$menu.find("ul").parent() //find all LIs within menu with a sub UL
$lis.each(function(i){
var $li=$(this).css({zIndex: 1000+i})
var $subul=$li.find('ul:eq(0)').css({display:'block'}) //set sub UL to "block" so we can get dimensions
$subul.data('dimensions', {w:$subul.outerWidth(), h:$subul.outerHeight(), parentliw:this.offsetWidth, parentlih:this.offsetHeight})
$subul.data('$parentliref', $li) //cache parent LI of each sub UL
$subul.data('timers', {})
$li.data('$subulref', $subul) //cache sub UL of each parent LI
$li.children("a:eq(0)").append( //add arrow images
'<img src="'+flexdropdownmenu.arrowpath+'" class="rightarrowclass" style="border:0;" />'
)
$li.bind(flexdropdownmenu.triggerevt, function(e){ //show sub UL when mouse moves over parent LI
var $targetul=$(this).css('zIndex', ++flexdropdownmenu.startzindex).addClass("selected").data('$subulref')
if ($targetul.queue().length<=1){ //if 1 or less queued animations
clearTimeout($targetul.data('timers').hidetimer)
$targetul.data('timers').showtimer=setTimeout(function(){
flexdropdownmenu.positionul($, $targetul, e)
$targetul.show(flexdropdownmenu.animspeed)
}, flexdropdownmenu.showhidedelay[0])
if (flexdropdownmenu.triggerevt=="click" && $(e.target).next('ul').length==1) //if LI being clicked on is a menu header
return false
}
})
$li.bind('mouseleave', function(e){ //hide sub UL when mouse moves out of parent LI
var $targetul=$(this).data('$subulref')
clearTimeout($targetul.data('timers').showtimer)
$targetul.data('timers').hidetimer=setTimeout(function(){$targetul.hide(100).data('$parentliref').removeClass('selected')}, flexdropdownmenu.showhidedelay[1])
})
})
$menu.find('ul').andSelf().css({display:'none', visibility:'visible'}) //collapse all ULs again
this.builtflexmenuids.push($menu.get(0).id) //remember id of flex menu that was just built
},
init:function($, $target, $flexmenu){
var mobilemenucheck = this.mobilemql.matches
this.triggerevt=(this.ismobile)? "click" : "mouseenter"
this.showhidedelay[0]=(this.ismobile)? 0 : this.showhidedelay[0]
if (this.builtflexmenuids.length==0){ //only bind click event to document, create overlay div once
$(document.body).bind(this.hidemenuevent, function(e){
$('.jqflexmenu').find('ul').andSelf().hide()
})
$('<div class="flexoverlay" />')
.bind('click', function(e){
$('div.flexmenumobile').hide()
$('div.flexoverlay').css('display', 'none')
})
.appendTo(document.body)
}
if ($target.parents().filter('ul.jqflexmenu').length>0) //if $target matches an element within the flex menu markup, don't bind onflexmenu to that element
return
if (!mobilemenucheck){ // if REGULAR MENU MODE (non mobile)
if (!this.ulclones[$flexmenu.get(0).id]) // if drop down menu hasn't been cloned yet (for mobile menu usage)
this.ulclones[$flexmenu.get(0).id] = $flexmenu.clone()
$('div.flexmenumobile').css('display', 'none')
$('div.flexoverlay').css('display', 'none')
if (jQuery.inArray($flexmenu.get(0).id, this.builtflexmenuids)==-1){ //if this flex menu hasn't been built yet
this.buildflexmenu($, $flexmenu, $target)
}
if (!$target.data('setting')){ // if this $target doesn't have a regular flex menu associated with it yet
var useroffsets=$target.attr('data-offsets')? $target.attr('data-offsets').split(',') : [0,0] //get additional user offsets of menu
useroffsets=[parseInt(useroffsets[0]), parseInt(useroffsets[1])]
$target.data('setting', {dir: $target.attr('data-dir'), useroffsets: useroffsets}) //store direction (drop right or down) of menu plus user offsets
$target.bind(flexdropdownmenu.triggerevt, function(e){
if (!flexdropdownmenu.mobilemql.matches){ // if not in mobile menu mode
$flexmenu.css('zIndex', ++flexdropdownmenu.startzindex)
flexdropdownmenu.positionul($, $flexmenu, e, $target)
flexdropdownmenu.showbox($, $target, $flexmenu, e)
if (flexdropdownmenu.triggerevt=="click")
e.preventDefault()
}
})
$target.bind("mouseleave", function(e){
if (!flexdropdownmenu.mobilemql.matches){ // if not in mobile menu mode
flexdropdownmenu.hidebox($, $target, $flexmenu)
e.preventDefault()
}
})
}
}
else{ // if MOBILE MENU MODE
if (!this.ulclones[$flexmenu.get(0).id]) // if drop down menu hasn't been cloned yet (for mobile menu usage)
this.ulclones[$flexmenu.get(0).id] = $flexmenu.clone()
$('.jqflexmenu').find('ul').andSelf().hide()
if (jQuery.inArray($flexmenu.get(0).id + '-mobile', this.builtflexmenuids)==-1){ //if this mobile flex menu hasn't been built yet
this.buildmobilemenu($, $flexmenu.get(0).id, $target)
}
var $mobilemenu = $('div#' + $flexmenu.get(0).id + '-mobile')
if (!$target.data('mobilesetting')){ // if this $target doesn't have a regular flex menu associated with it yet
$target.data('mobilesetting', {dir: $target.attr('data-dir'), useroffsets: [0,0]})
$target.bind('click', function(e){
if (flexdropdownmenu.mobilemql.matches){ // if in mobile menu mode
$('div.flexoverlay').css('display', 'block')
var winwidth = $(window).width()
var winheight = $(window).height()
var marginLeft = (winwidth/2 - $mobilemenu.data('dimensions').w/2 < 0)? -winwidth/2 : -$mobilemenu.data('dimensions').w/2
var marginTop = (winheight/2 - $mobilemenu.data('dimensions').h/2 < 0)? -winheight/2 : -$mobilemenu.data('dimensions').h/2
$mobilemenu.css({left:'50%', top:'50%', marginLeft: marginLeft, marginTop: marginTop})
$mobilemenu.css({zIndex: flexdropdownmenu.mobilezindex++, display:'block'})
return false
}
})
}
}
}
}
jQuery.fn.addflexmenu=function(flexmenuid, options){
var $=jQuery
flexdropdownmenu.mobilemql = (window.matchMedia)? window.matchMedia(flexdropdownmenu.mobilemediaquery) : {matches: false, addListener: function(){}}
return this.each(function(){ //return jQuery obj
var $target=$(this)
if (typeof options=="object"){ //if options parameter defined
if (options.dir)
$target.attr('data-dir', options.dir) //set/overwrite data-dir attr with defined value
if (options.offsets)
$target.attr('data-offsets', options.offsets) //set/overwrite data-offsets attr with defined value
}
if ($('#'+flexmenuid).length==1){ //check flex menu is defined
flexdropdownmenu.init($, $target, $('#'+flexmenuid))
if (window.matchMedia){
window.matchMedia(flexdropdownmenu.mobilemediaquery).addListener(function(){
flexdropdownmenu.init($, $target, $('#'+flexmenuid))
})
}
}
})
};
//By default, add flex menu to anchor links with attribute "data-flexmenu"
jQuery(document).ready(function($){
var $anchors=$('*[data-flexmenu]')
$anchors.each(function(){
$(this).addflexmenu(this.getAttribute('data-flexmenu'))
})
})
//ddlistmenu: Function to define a UL list menu dynamically
function ddlistmenu(id, className){
var menu=document.createElement('ul')
if (id)
menu.id=id
if (className)
menu.className=className
this.menu=menu
}
ddlistmenu.prototype={
addItem:function(url, text, target){
var li=document.createElement('li')
li.innerHTML=''+text+''
this.menu.appendChild(li)
this.li=li
return this
},
addSubMenu:function(){
var s=new ddlistmenu(null, null)
this.li.appendChild(s.menu)
return s
}
}
.flexdropdownmenu, .flexdropdownmenu ul{ /*topmost and sub ULs, respectively*/
font: normal 13px Verdana;
margin: 0;
padding: 0;
position: absolute;
left: 0px;
top: 0;
list-style-type: none;
background: white;
border: 1px solid black;
border-bottom-width: 0;
visibility: hidden;
display: none; /*collapse all sub menus to begin with*/
box-shadow: 3px 3px 8px #818181; /*shadow for CSS3 capable browsers.*/
-webkit-box-shadow: 3px 3px 8px #818181;
-moz-box-shadow: 3px 3px 8px #818181;
}
.flexdropdownmenu li{
position: relative;
}
.flexdropdownmenu li a{
display: block;
width: 160px; /*width of menu (not including side paddings)*/
color: black;
background: #dddddd;
border-bottom: 1px solid black;
text-decoration: none;
padding: 4px 5px;
}
* html .flexdropdownmenu li{ /*IE6 CSS hack*/
display: inline-block;
width: 170px; /*width of menu (include side paddings of LI A*/
}
.flexdropdownmenu li a:hover, .flexdropdownmenu li.selected>a{
background: #cecfce;
}
.rightarrowclass{
position: absolute;
top: 6px;
right: 5px;
}
/* ######### CSS for shadow added to sub menus ######### */
.ddshadow{
position: absolute;
left: 0;
top: 0;
width: 0;
height: 0;
background-color: #ccc; /* generally should be just a little lighter than the box-shadow color for CSS3 capable browsers */
}
.toplevelshadow{
margin: 5px 0 0 5px; /* in NON CSS3 capable browsers gives the offset of the shadow */
opacity: 0.8; /* shadow opacity mostly for NON CSS3 capable browsers. Doesn't work in IE */
}
.ddcss3support .ddshadow.toplevelshadow {
margin: 0; /* in CSS3 capable browsers overrides offset from NON CSS3 capable browsers, allowing the box-shadow values in the next selector to govern that */
/* opacity: 1; */ /* optionally uncomment this to remove partial opacity for browsers supporting a box-shadow property which has its own slight gradient opacity */
}
.ddcss3support .ddshadow {
background-color: transparent;
box-shadow: 5px 5px 5px #aaa; /* box-shadow color generally should be a little darker than that for the NON CSS3 capable browsers background-color */
-moz-box-shadow: 5px 5px 5px #aaa;
-webkit-box-shadow: 5px 5px 5px #aaa;
}
/* ######### Mobile menu container CSS ######### */
div.flexoverlay{ /* overlay that covers page when mobile menu is shown */
width: 100%;
height: 100%;
left: 0;
top: 0;
position: fixed;
background: black;
-webkit-transform-style: preserve-3d;
opacity: 0.7;
z-index: 1000; /* z-index value should be smaller than mobilezindex: 1001 variable inside flexdropdown.js */
display: none;
}
div.flexmenumobile{ /* main mobile menu container */
position: fixed;
color: white;
width: 250px; /* width of mobile menu */
display: none;
}
div.flexmenumobile a{
color: white;
text-decoration: none;
}
div.flexmenumobile ul{ /* style for all ULs in general inside mobile menu */
list-style: none;
width: 100%;
top: 0;
left: 0;
background: white;
border: 1px solid black;
margin: 0;
padding: 0;
position: absolute;
opacity: 0;
visibility: hidden;
}
div.flexmenumobile ul li{
border-bottom: 1px solid gray;
position: relative;
font-weight: bold;
}
div.flexmenumobile ul li.breadcrumb{ /* breadcrumb LI that's added to the top of every sub level UL */
cursor: pointer;
padding: 8px;
padding-left: 5px;
background: gray;
font-size: 1.1em;
}
div.flexmenumobile ul li a{
display: block;
color: black;
background: #fae7a9;
border-bottom: 1px solid black;
padding: 6px;
font-size: 1.1em;
}
div.flexmenumobile ul li a:hover{
background: #F0CE7D;
}
div.flexmenumobile ul img.backarrow{
margin-right: 5px;
}
div.flexmenumobile ul img.rightarrow{
position: absolute;
right: 5px;
top: 10px;
}
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="flexdropdown.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="flexdropdown.js">
/***********************************************
* Flex Level Drop Down Menu- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
* Please keep this notice intact
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for this script and 100s more
***********************************************/
</script>
</head>
<body>
<h3>Drop Down Menu:</h3>
<p style="text-align:left"><img src="Teams_Bar_New.jpg" alt="Mountain View" style="width:175px;height:29px;"/></p>
<h3>Drop to the right, with custom offset of 8px horizontally, 0px vertically, added:</h3>
<p style="text-align:left">Webmaster Resources</p>
<!--HTML for Flex Drop Down Menu 1-->
<ul id="flexmenu1" class="flexdropdownmenu">
<li>Home</li>
<li>CIS</li>
<li>Finance
<ul>
<li>Sub Item 3.1a</li>
<li>Sub Item 3.2a</li>
<li>Sub Item 3.3a</li>
<li>Sub Item 3.4a</li>
</ul>
</li>
<li>Human Resources</li>
<li>Legal
<ul>
<li>Sub Item 5.1a</li>
<li>Item Folder 5.2a
<ul>
<li>Sub Item 5.2.1a</li>
<li>Sub Item 5.2.2a</li>
<li>Sub Item 5.2.3a</li>
<li>Sub Item 5.2.4a</li>
</ul>
</li>
</ul>
</li>
<li>Marketing</li>
<li>Support Services</li>
</ul>
<!--HTML for Flex Drop Down Menu 2-->
<ul id="flexmenu2" class="flexdropdownmenu">
<li>Dynamic Drive</li>
<li>CSS Drive</li>
<li>JavaScript Kit</li>
<li>Coding Forums</li>
<li>DOM Reference</li>
</ul>
</body>
</html>
Can anybody please suggest how to fix this issue. I need my dropdown just below the hover image, not left of that image.
The above HTML, CSS, and jQuery code can also be found in the below link:
http://dynamicdrive.com/dynamicindex1/flexdropdown_suppliment.htm

Change CSS After Scrolling

I have a navbar that uses some CSS to change the opacity:
.navbar {
background-color: #4B5253;
opacity: 0.8;
filter: alpha(opacity = 80);
}
I need the opacity to change to 1.0 after the user scrolls down a certain number of pixels, for example, 500px.
I'm using jQuery, but I didn't find a solution.
Also, I'm not good with JavaScript, and sometimes I don't know where should I put my code. So if is there any way to do it all with CSS, it will be great!
Here is an example of what I want—pay close attention to the header as you scroll down.
If you want a native solution then use this:
function changeCss () {
var bodyElement = document.querySelector("body");
var navElement = document.querySelector("nav");
this.scrollY > 500 ? navElement.style.opacity = .8 : navElement.style.opacity = 1;
}
window.addEventListener("scroll", changeCss , false);
here is a live demo
function changeCss () {
var bodyElement = document.querySelector("body");
var navElement = document.querySelector("nav");
this.scrollY > 500 ? navElement.style.opacity = .8 : navElement.style.opacity = 1;
}
window.addEventListener("scroll", changeCss , false);
body{
background-color: white;
height: 1000vh
}
nav{
position:fixed;
top:0;
left:0;
width:100%;
text-align: center;
background: blueviolet
}
nav li{display: inline-block}
nav a{
padding: 10px 12px;
color: white;
text-transform:uppercase;
text-decoration: none
}
<nav class="menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
I wrote CSS for class a, then class b.
In .a, opacity was 0.8 and in .b the opacity was 1.0. With jQuery, I just changed the element's class:
.a {
opacity: 0.8;
}
.b {
opacity: 1.0;
}
$(window).scroll(function () {
var $heightScrolled = $(window).scrollTop();
var $defaultHeight = 500;
if ($heightScrolled < $defaultHeight) {
$('#mynav').removeClass("b")
$('#mynav').addClass("a")
}
else {
$('#mynav').addClass("b")
}
});
The easiest way to accomplish what you're trying to do is a combination of some simple jQuery and CSS transitions.
We will use JavaScript to check for the windows scroll position on every scroll event and compare it to the distance of the bottom of the #main element; if the scroll position is greater, then we'll apply a class to the body to indicate we have scrolled past #main, and then we will use CSS to define the nav styling for that state.
Change the CSS code so it changes opacity when it's past #main.
// get the value of the bottom of the #main element by adding the offset of that element plus its height, set it as a variable
var mainbottom = $('#main').offset().top + $('#main').height();
// on scroll,
$(window).on('scroll', function() {
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.nav').addClass('past-main');
} else {
$('.nav').removeClass('past-main');
}
});
.nav {
background-color: transparent;
color: #fff;
transition: all 0.25s ease;
position: fixed;
top: 0;
width: 100%;
background-color: #ccc;
padding: 1em 0;
/* make sure to add vendor prefixes here */
}
.nav.past-main {
background-color: #fff;
color: #444;
}
#main {
height: 500px;
background-color: red;
}
#below-main {
height: 1000px;
background-color: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="nav">
[logo]
</nav>
<div id="main">#main</div>
<div id="below-main">#below-main</div>

100% width (of page) drop down/drawer menu with JQuery?

I've been stuck trying to figure out how to code a menu much like what you see on the Playstation website: http://us.playstation.com/
EDIT: Fiddle: http://jsfiddle.net/jjcarlson/7q64A/
So far I have a number of issues. The first is that I have been unable to create the 100% width, because, I am assuming, of the parent/child relationship.
The second issue I have is that my Timeout works on all class elements rather than only the currently hovered element. In other words, if all elements have slid down and one is hovered over, they all will remain open until none of them have been hovered for 1.5 seconds. I admit that my inability to come up with a solution may be due to my limited experience with the language. Below is the CSS:
.accordion-container {
width: 90%;
padding-bottom: 5px;
margin: 20px 0 0 20px;
}
.accordion {
width: 40%;
padding: 20px;
margin: 0 15px 35px;
position: relative;
float: left;
display: inline-block;
}
.accordion-question {
margin: 0;
padding: 0 0 5px 20px;
display: inline-block;
color: #06F;
background-color: #9F0;
cursor: pointer;
}
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
}
.accordion-answer {
margin: 0;
padding: 0;
color: #0C0;
}
Then, the JQuery:
$(document).ready(function () {
var menu = $('.accordion-answer')
var timeout = 0;
var hovering = false;
menu.hide();
$('.accordion-question').hover(function () {
hovering = true;
// Open the menu
$(this).closest('.accordion').find('.accordion-answer')
.stop(true, true)
.delay(400).slideDown(600);
if (timeout > 0) {
clearTimeout(timeout);
}
})
.on("mouseleave", function () {
resetHover();
});
$('.accordion-answer').hover(function () {
hovering = true;
startTimeout();
})
.on("mouseleave", function () {
resetHover();
});
function startTimeout() {
timeout = setTimeout(function () {
closeMenu();
}, 1500);
};
function closeMenu() {
if (!hovering) {
$('.accordion-answer').stop(true, true).slideUp(400);
}
};
function resetHover() {
hovering = false;
startTimeout();
};
});
And finally, the HTML:
<div class="accordion-container">
<div class="accordion">
<div class="accordion-question">
<h2>Is this a question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>To be honest, I am not sure</p>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
<div class="accordion" id="testanchor">
<div class="accordion-question">
<h2>What would be a good second question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>I don’t know, man!</p>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
</div>
Styling is minimal right now (sorry) as I'm just trying to get this figured out. Thank you for any help you can provide.
To get a width of 100% you should not display them as inline-block and set the width of .accordion to 100%.
In the hover-event you set hovering to true. If the next hover-event occurs prior to the call of closeMenu, then the if clause will already be false.
You should be able to accomplish the 100% width of your dropdown by altering the css of your .according-answer-container to a fixed position along with setting left and right to 0:
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
position: fixed;
left: 0;
right: 0;
}
An update to your fiddle shows this working

Categories