Dropdown on hover is moving towards left of dropdown image in jQuery - javascript
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
Related
Navigation sliding line on hover (and active state)
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>
Trying to do a horizontal slide nav with endless loop
Trying to do a regular horizontal nav with arrow that has a endless loop. Tried figuring it out and some how I can't get it to loop back to "all" div. tried slick carousel but it has this glitch when the page loads HTML <div id="second-navigation"> <div id="slider"> <li>All</li> <li>slide1</li> <li>slide2</li> </div> </div> JS var W = $('#second-navigation').width(); var N = $('#slider li').length; var C = 0; $('#slider').width( W*N ); $('#left, #right').click(function(){ var myID = this.id=='right' ? C++ : C-- ; C= C===-1 ? N-1 : C%N ; $('#slider').stop().animate({left: -C*W }, 1000 ); }); CSS #second-navigation{ width:300px; height:150px; position:relative; overflow:hidden; } #slider{ position:absolute; height:150px; left:0; width:9999px; } #slider li{ float:left; }
One approach would be to as follows: When a direction button (ie left or right) is clicked, clone the list item that will be moved out of view by the animation (ie the first <li> for the <ul> when the "left" button is clicked) attach the cloned <li> to the opposite end of the <ul> list (ie append the cloned first to the end of <ul> when "left" is clicked animate the margin of the <ul> element to hide the original <li> that was cloned (ie for the "left" case, animate the <ul> left margin to "-150px", which is the width of your <li> items) On completion of the animation, ensure the <ul> margin is reset, and that the now hidden <li> element has been removed This can be written in code as shown below. There are a few extra things going on here: The <ul> needs to be the direct parent of <li> items (a <div> cannot parent <li> items) Flex box is used to achieve horizontal layout of <li> items, which simplifies CSS styling Compounded animations need to be prevented (ie the case where button click happens during an existing animation). Below, I'm just ignoring clicks if an animation is underway $("#left").click(function() { /* If currently animated, early exit */ if($("#second-navigation ul:animated").length) { return; } /* Clone the element that will be hidden */ var firstClone = $("li:first-child").clone(); $("#second-navigation ul") .animate({ /* Animate ul container left margin to left */ "marginLeft": "-150px" }, { done: function() { /* Reset ul container left margin */ $(this).css("marginLeft", "0px"); /* Remove element that is now hidden */ $("li:first-child", "#second-navigation ul").remove(); } }) /* Add cloned element to end of list */ .append(firstClone); }); $("#right").click(function() { if($("#second-navigation ul:animated").length) { return; } var lastClone = $("li:last-child").clone(); $("ul") .css({ "marginLeft": "-150px" }) .animate({ "marginLeft": "0" }, { done: function() { $("li:last-child", "#second-navigation ul").remove(); } }) .prepend(lastClone); }); #second-navigation { position: relative; overflow: hidden; width: 300px; height: 150px; } ul { display: flex; width: fit-content; flex-direction: row; padding: 0; margin: 0; } li { position: relative; height: 150px; width: 150px; top: 0; left: 0; transition: left ease-in-out 1s; background: linear-gradient(45deg, black, transparent); } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <div id="second-navigation"> <ul> <li>All</li> <li>slide1</li> <li>slide2</li> </ul> </div> <button id="left">Move left</button> <button id="right">Move right</button> Hope this helps!
hide drop down menu on scroll JS only
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
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>
ng-src not working correctly
Main issue I am having, is i am using ng-src="" to add in images dynamically via my JSON file. I ran into the issue where inside the img element (within the html) where the ng-src="" is located it is not sourcing in the images I have stored at all. And when I go to inspect the element I see both ng-src=location/some.png" and src="location/some.png" both inside the element within the DOM. But when I just use src="" with out the directive the images appear but when I refresh the browser, the images disappears sometimes and reappear other times, acting very buggy. Here I have a js fiddle of my situation and code below: http://jsfiddle.net/coder101/c3X7B/4/ HTML: <div ng-app="indieApp"> <div class="wrap"> <div class="space"></div> <div id="main" role="main" ng-controller="imageAddCrtl"> <ul id="tiles" class=""> <li ng-repeat="image in imageInfo"> <img ng-src="{{image.path}}" /> </li> </ul> </div> </div> </div> Css: .wrap .space { padding-bottom:10px; position:relative; width:100%; right:0; top:0; left:0; bottom:0; text-align:center; margin-top:80px; } .wrap #tiles { list-style-type: none; position: relative; /** Needed to ensure items are laid out relative to this container **/ margin: 0; padding: 0; } /** * Grid items */ .wrap #tiles li { width: 200px; background-color: #ffffff; border: 1px solid #dedede; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; display: none; /** Hide items initially to avoid a flicker effect **/ cursor: pointer; padding: 4px; } .wrap #tiles li.inactive { visibility: hidden; opacity: 0; } .wrap #tiles li img { display: block; } JS (this is for an infinite scroll using the wookmark Library I have, not apart of the problem to my knowledge) (function ($) { var $tiles = $('#tiles'), $handler = $('li', $tiles), $main = $('#main'), $window = $(window), $document = $(document), options = { autoResize: true, // This will auto-update the layout when the browser window is resized. container: $main, // Optional, used for some extra CSS styling offset: 20, // Optional, the distance between grid items itemWidth: 210 // Optional, the width of a grid item }; /** * Reinitializes the wookmark handler after all images have loaded */ function applyLayout() { $tiles.imagesLoaded(function () { // Destroy the old handler if ($handler.wookmarkInstance) { $handler.wookmarkInstance.clear(); } // Create a new layout handler. $handler = $('li', $tiles); $handler.wookmark(options); }); } /** * When scrolled all the way to the bottom, add more tiles */ function onScroll() { // Check if we're within 100 pixels of the bottom edge of the broser window. var winHeight = window.innerHeight ? window.innerHeight : $window.height(), // iphone fix closeToBottom = ($window.scrollTop() + winHeight > $document.height() - 100); if (closeToBottom) { // Get the first then items from the grid, clone them, and add them to the bottom of the grid var $items = $('li', $tiles), $firstTen = $items.slice(0, 10); $tiles.append($firstTen.clone()); applyLayout(); } }; // Call the layout function for the first time applyLayout(); // Capture scroll event. $window.bind('scroll.wookmark', onScroll); })(jQuery); In the important external libraries I have attached: imagesInfo.json -> is where the images are being sourced from my local server, as I have the images stored in a images directory controller.js -> is where I have the angularJS information angular.js -> well just the need angular lib The rest of the libraries I have are just for the image functionally of the infinite scroll and setting up a grid styled layout
You forgot to add ng-app="indieApp" plnkr here: http://plnkr.co/edit/LfMer1?p=preview