I'm building a dropdown menu for a project I'm working on, and I've come across some trouble. It is built so that the width and the style.left of each submenu is set by a JavaScript function that is called when the root-level menu items are hovered. When I hover these menu items it looks like this:
The submenu is clearly off by quite some pixels to the left. If I don't alter the style.left of the submenu I get the following instead:
Here the alignment is correct. The fault has occured in both Mozilla Firefox and Google Chrome for both Windows 7 and Linux, so it's not a platform related fault.
Here is the code that produces the error:
menu.js
function show_sub_menu(cath){
var menu_item = document.getElementById(cath) //cath is an integer passed to the function
var m_width = Math.floor(window.innerWidth*0.7*0.2); //Menu is 70% of window, each item is 20% of menu
menu_item.style.left = cath*m_width; //Set the style.left dynamically depending on what menu item is to be displayed
//This last line of code produces the error
}
menu.css
#m_wrapper{
position:relative;
width:100%;
}
#menu{
position:relative;
width:70%;
}
#menu li{
width:20%;
float:left;
}
#menu div{
position:absolute;
width:20%;
top:30px;
}
#menu div a{
position:relative;
display:block;
padding:5px;
}
menu.htm
<div id=m_wrapper>
<ul id=menu>
<li onMouseOver=show_sub_menu('0')>Item 1</li>
<div id=0 onMouseOver=show_sub_menu('0')>
<a href=#>Item 1.1</a>
<a href=#>Item 1.2</a>
</div>
</li>
</ul>
</div>
I this seems very illogical, since m_width in the .js is, for my screen settings, 235px and m_width*cath is 0. I am fairly new with JavaScript, so help would be very appreciated!
First, you have your list-item closing early, and an ID that shouldn't start with a digit. So let's clean that up:
<div id="m_wrapper">
<ul id="menu">
<li onMouseOver="show_sub_menu('0');">
Item 1
<div id="s0" onMouseOver="show_sub_menu('0');">
Item 1.1
Item 1.2
</div>
</li>
</ul>
</div>
Next let's check out your CSS. Since we want to position your submenus relative to the main menu items, let's put position:relative; on the list-item itself to create a space from which we can position other stuff.
Now that we have a context where the submenu is aligned based on the top-left corner of your list-item, what we really need is for that menu to appear 30 pixels down from that corner - no left or right adjustment needed.
#m_wrapper{
position:relative;
width:100%;
}
#menu{
position:relative;
width:70%;
}
#menu li{
position:relative;
width:20%;
float:left;
}
#menu div{
position:absolute;
width:100%;
top:30px;
left:0;
}
#menu div a{
display:block;
padding:5px;
}
From here, your sub-menu should be positioned where you need it, but it's shown all the time. We'll take care of that by adding display:none; to #menu div and modifying the JavaScript to change display instead:
function show_sub_menu(cath){
var menu_item = document.getElementById("s"+cath);
menu_item.style.display = "block";
}
That should make your menu appear where and when you need it. I'll leave the disappearing act to you.
Related
I have a collapsible menu that has the following class when closed:
<div class="menu one collapse">
And the following class when opened:
<div class="menu one in collapse">
I want to use the MutationObserver or jQuery to monitor the collapsible menu class and change the following from
<div class="monitored-class three" style="display: block;">
to
<div class="monitored-class three" style="display: none!important;">
When the menu is open, and to revert the changes when the menu is closed.
I have been searching for the past hour for this and the closest I have come is JQuery Detect class changes but the suggested answer right at the bottom:
var mut = new MutationObserver(function(mutations, mut){
// if attribute changed === 'class' && 'open' has been added, add css to 'otherDiv'
});
mut.observer(document.querySelector(".slide-out-div"),{
'attributes': true
});
Does not have enough details and code for me to proceed. There is also a more comprehensive answer here:
https://stackoverflow.com/a/14570614/5619682
But it does not directly address what I need to do.
I'm thankful for any help! :)
There is acctually one way to handle this with CSS only, but it will work only if the DOM Elements are listed in a hirarchie.
You can trigger specific CSS Styles by setting up the wrapper CSS classes which will modify the Style in the Child Elements you want.
As an easy Example I will show you this Example.
It triggers the Menu Navigations though the Menu Class body.menu-open.
The Menu appears only if the class "menu-open" has been added to the body.
As the Body is the Major Element of all your Elements you can go in your CSS now and trigger your prefed "menu-open Style" with body.menu-open { .... }
I hope this will give you an Idea of CSS Animation and Triggering (or how is this called correctly?). I think something equivalent to this is your solution.
// Trigger Menus Toggle though CSS
$(document).on('click', '.magic_button', function(){
$('body').toggleClass('menu-open');
});
/* Global Hardreset */
* { padding:0px; margin:0px; }
/* Menu Wrapper */
.menu_wrapper {
display:block; height:50px; background:rgba(0,0,0,.3); position:relative; overflow:hidden;
}
/* Magic Button */
.magic_button {
display:block; width:40px; height:40px;
border-radius:50%; background: maroon;
position: absolute; top:5px; left:10px;
overflow:hidden; cursor:pointer;
}
/* Basic Setup and Styling */
.main_menu {
list-style:none; padding:0p; margin:0px;
display:block; text-align:center;
position:absolute; left:100%; top:0px; right:0px;
transition:all .3s; -moz-transition:all .3s; -webkit-transition:all .3s;
}
.main_menu li {
display:inline-block;margin:0px auto;
}
.main_menu li a {
background:darkseagreen; padding:18px 20px; color: #fff; line-height:50px;
text-decoration:none; font-family:Verdana; font-size:12px;
}
/*
* The CSS Statements for doing the Magic to Open / Close Menu.
* Notice: Acctually it would be generally better if you add thoose "check classes"
* into the Body, as the body is the major Element you can trigger from.
*/
body.menu-open .main_menu { left:0px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<nav class='menu_wrapper'>
<ul class='main_menu'>
<li><a href=#> First Link </a></li>
<li><a href=#> Second Link </a></li>
<li><a href=#> Magic Link </a></li>
<li><a href=#> Dungeon Entry Link </a></li>
</ul>
<div class="magic_button"></div>
</nav>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Could somebody help me,take a look at this website,and tell me please,what function is used for the nice transition when you click on some of the menu bars,it goes smoothly to another page without loading whitescreen.
If you know,tell me, what it is or how can i do that,or even both :D please give me answer below.Thanks a lot.
If you give a look to the Sourcecode of the Page, you'll see that all the needen Pages are already loaded in the DOM. (One Page structure I guess, or maybe as Asychronoumus loading).
However all the Pages have their own DIV container, which are linked to the Navigation Bar.
On click on each Navigation Element, make a transition of the prefered DIV's.
You can either choose the fade effect (which is using on the Page you show us), or even some other cool effects with bouncing, or even if you know how to manupulate CSS with jQuery, then your own Animation / Transition too. Here's a link to the jQuery API fadeIn and fadeOut
.
I would do it like this:
$(function(){
// Setup your Variables first
var nav = $('.navigation ul li');
var all_pages = $('.pages .page');
var active = 'active';
var target, page;
// On Click do the stuff to get some transition
nav.on('click', function(){
// Get the Target
target = $(this).attr('data-target');
page = $('.page[data-page='+target+']');
// Hide all pages here (maybe it would be a better idea to target .page.active)
all_pages.fadeOut('slow').removeClass(active);
// FadeIn the target Page
page.fadeIn('slow').addClass(active);
});
// fallback to first page when the target is not set on page load
if(!target) nav.first().trigger('click');
});
.main { position:relative; width:100%; height:100%; font-family:'Verdana'; font-size:13px; }
.navigation { border:0px solid red; width:150px; position:absolute; left:0px; top:0px; bottom:0px; }
.navigation ul { list-style:none; width:auto; margin:0px; padding:0px; }
.navigation ul li { display:block; height:30px; border:0px solid green; line-height:30px; white-space:nowrap; cursor:pointer; padding:0px 20px; }
.pages { position:absolute; left:150px; right:0px; top:0px; bottom:0px; border:0px solid blue; }
.page { position:absolute; top:0px; left:0px; right:0px; bottom:0px; display:none; min-height:500px; }
.page.active { }
.page:nth-child(1),
.navigation ul li:nth-child(1) { background:lightgreen; }
.page:nth-child(2),
.navigation ul li:nth-child(2) { background:maroon; }
.page:nth-child(3),
.navigation ul li:nth-child(3) { background:wheat; }
.page:nth-child(4),
.navigation ul li:nth-child(4) { background:cyan; }
.page:nth-child(5),
.navigation ul li:nth-child(5) { background:salmon; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class='main'>
<div class='navigation'>
<ul>
<li data-target='1'>First Link</li>
<li data-target='2'>Second Page</li>
<li data-target='who'>Who I am</li>
<li data-target='location'>Location</li>
<li data-target='5'>Oter Stuff</li>
</ul>
</div>
<div class='pages'>
<div class='page' data-page='1'> Here is the first page ... </div>
<div class='page' data-page='2'> here is the seocnd one</div>
<div class='page' data-page='who'> Who I am?</div>
<div class='page' data-page='location'> Location </div>
<div class='page' data-page='5'> Oter Stuff </div>
</div>
</div>
I hope you get the Idea behind the Code to get the result you want :)
Btw, I made this quickly HTML Markup to get a Similar effect for the transitions.
You'll need to add some more Animation Stuff for the Navigation to get the "on mouse over slide the names up etc" stuff - propably easy done with :hover syntax of CSS.
Hope this helps, ps. this is my first Post, I may have some mistakes in there.
And yes, there should be a better HTML Buildup as my Snippet does for now.
regards
Gkiokan
I'm having some trouble when designing a responsive layout as follows below:
If you browse to http://www.wickersleysixthform.net you can see this in action.
Basically I'm trying to create a responsive menu so in browsers of 768px and above you will see a normal horizontal navigation. Then for anything under 481px you will see the "three line" menu with a .slideToggle() effect on that once pressed drops down the menu.
I can sort of get this to work, but the .slideToggle() isn't pushing the rest of the content down which I need it to do. Also the three lines won't appear if I re-size my browser screen manually however if I resize then refresh the page it will do, but if I do that then the normal links in the larger screen size don't show. I hope that makes sense.
This is the jQuery I'm using for the toggle inside a jQuery(document).ready(function($) {});
/* getting viewport width */
var responsive_viewport = $(window).width();
/* if is below 481px */
if (responsive_viewport < 481) {
$(".top-nav").before('<div id="menu">☰</div>');
$("#menu").click(function(){
$(".top-nav").slideToggle();
});
}
/* if is above or equal to 768px */
if (responsive_viewport >= 768) {
$(".top-nav").show();
}
Can anyone help? No doubt it's something simple but it's driving me insane. Possibly CSS based rather than the jQuery?
The CSS I'm using is as follows (in my base/mobile stylesheet).
.header {
background-color:#blue;
padding-top:10px;
height:50px;
}
#menu {
display:block;
font-size:1.75em;
position: absolute;
right: 10px;
top: 2px;
}
.top-nav {
display:none;
}
.top-nav.open {
display:block;
background:#blue;
}
In my 768 and up stylesheet:
.header {
padding-top:0;
height:70px;
position:fixed;
width:100%;
z-index:10;
}
#menu {
display:none;
}
.top-nav {
display:block;
}
My HTML structure:
<header class="header" role="banner">
<div id="inner-header" class="wrap clearfix">
<a rel="nofollow" href="http://www.wickersleysixthform.net">
<img id="logo" width="50px" height="36px" src="http://www.wickersleysixthform.net/wp-content/themes/sixthform/library/images/white.png">
</a>
<nav role="navigation">
<div id="menu">☰</div>
<ul id="menu-main-menu" class="nav top-nav clearfix">
<li>About</li>
<li>
Current Students
<ul class="sub-menu"></ul>
</li>
<li>Courses</li>
<li>Student Life</li>
<li>Prospectus</li>
<li>Apply</li>
<li>Contact</li>
</ul>
</nav>
</div>
</header>
The problem is that your header element has a fixed height of 50px. So when the menu expands the header stays the same height.
Removing the height or replacing it with min-height solves your problem
this is what I'm working on right now
http://www.dsi-usa.com/yazaki_port/hair-by-steph/
as you can see when you click the tabs the fade in and fade outs look extremely funny. I'm wondering if anyone can take a look at the code and tell me what I'm doing wrong. I'm extremely new to Jquery and Javascript (like yesterday new) so I apologize if the code is messy. I'm wondering if 1. there was an easier way to write this and 2. if there's a way to just have the sections fade into each other/any other cool ideas anyone has.
the html structure (pulled out all of the content for space purposes)
<div id="main">
<div id="display_canvas">
</div>
<div id="nav">
<ul>
<li><a class="btn" title="contact">CONTACT</a></li>
<li><a class="btn" title="resume">RESUME</a></li>
<li><a class="btn" title="portfolio">PORTFOLIO</a></li>
<div class="clear"></div>
</ul>
<div class="clear"></div>
</div>
<div id="resume">
//contents here
</div>
<div id="contact">
//contents here
</div>
</div>
the css
*
{
margin:0;
padding:0;
font-family:verdana, helvetica, sans-serif;
}
#main
{
width:1200px;
margin:0 auto;
}
#display_canvas
{
height:700px;
background-color:#fefea8;
box-shadow:5px 5px 5px #888888;
-moz-box-shadow:5px 5px 5px #888888;
-webkit-box-shadow:5px 5px 5px #888888;
display:none;
}
.clear
{
clear:both;
}
#resume
{
clear:both;
float:right;
width:100%;
background-color:#000000;
background-image:url("../imgs/resume_back.png");
background-position:300px 0px;
background-repeat:no-repeat;
height:200px;
text-align:left;
display:none;
}
#contact
{
clear:both;
float:right;
width:100%;
background-color:#000000;
background-image:url("../imgs/contact_back.png");
background-position:left;
background-repeat:no-repeat;
height:200px;
text-align:left;
display:none;
}
#nav
{
margin:1em 0 0 0;
text-align:right;
}
#nav ul
{
list-style-type:none;
}
#nav li
{
display:inline;
}
.btn
{
margin-right:20px;
display:block;
text-align:center;
float:right;
color:#000000;
font-size:15px;
font-weight:bold;
line-height:30px;
text-decoration:none;
cursor:pointer;
width:150px;
height:30px;
}
.over
{
background-color:#888888;
color:#ffffff;
}
.active_contact
{
background-color:#000000;
color:#00a8ff;
}
.active_resume
{
background-color:#000000;
color:#9848c2;
}
.active_portfolio
{
background-color:#000000;
color:#ffffff;
}
and finally a whole mess of javascript
$(document).ready(function(){
//handles general navigation
$(".btn").hover(
function(){
$(this).addClass("over");
},
function(){
$(this).removeClass("over");
}
)
$(".btn").click(function(){
var btn = $(this);
var newClass = "active_" + btn.attr("title"); //set the new class
var section = $("#" + btn.attr("title"));
if ($("#curSection").length)
{
alert('there is a section');
var curClass = "active_" + $("#curSection").attr("title"); //get the current class active_section name
var curSection = "active"
$("#curSection").removeClass(curClass).removeAttr("id"); //remove the current class and current section attributes
btn.addClass(newClass).attr("id", "curSection"); //designate new selection
$(".currentSection").fadeOut("slow", function(){ //fade out old section
$(".currentSection").removeClass("currentSection");
section.fadeIn("slow", function(){ //fade in new section
alert('faded in');
section.addClass("currentSection"); //designate new section
});
});
}
else
{
alert('first time');
btn.addClass(newClass).attr("id", "curSection"); //designate new selection
section.fadeIn("slow", function(){
alert('faded in');
section.addClass("currentSection");
});
}
});
//handles resume navigation
$(".res-btn").hover(
function(){
$(this).addClass("res-over")
},
function(){
$(this).removeClass("res-over")
}
)
$(".res-btn[title=experience]").click(function(){
$("#scroller").stop().animate({top: "0px"}, 1000);
});
$(".res-btn[title=expertise]").click(function(){
$("#scroller").stop().animate({top: "-180px"}, 1000);
});
$(".res-btn[title=affiliates]").click(function(){
$("#scroller").stop().animate({top: "-360px"}, 1000);
});
});
if anyone has any ideas as to why this doesn't work let me know. I thought maybe it was having problems loading the content, but the content should be loaded already as they are on the screen already, just no display. I'm stumped, I saw a few posts similar to mine, so I followed some of their thinking. When I set the fadeIn() to like 5000 instead of "slow" The first 60% or so of the fadeIn is skipped and the section appears at say 60% opacity and then fades in the rest of the way. Not sure what I'm doing so thank you in advance.
Off the top of my head, I think the problem might be that you are initiating an alert dialogue box rather than a jquery Fancybox / Thickbox type of overlay lightbox which accommodates the speed at which the it animates to open or close. And in any case, I am unable to replicate the issue you are facing despite going directly to your link.
So rather than to try and resolve that chunk of codes you have picked out from different sources and since the content that you wish to display is an inline one, you might as well consider using Thickbox or Fancybox instead.
Alternatively, you could also kinda script your own lightbox without using the alert dialogue boxes if you like. It could look something like this:
HTML:
<!--wrapper-->
<div id="wrapper">
Box 1</li>
Box 2</li>
<!--hidden-content-->
<div class="box-1">
This is box 1. close
</div>
<div class="box-2">
This is box 2. close
</div>
</div>
<!--wrapper-->
CSS:
#wrapper{
background:#ffffff;
width:100%;
height:100%;
padding:0;
}
.box-1, .box-2{
display:none;
width:300px;
height:300px;
position:fixed;
z-index:3000;
top:30%;
left:30%;
background:#aaaaaa;
color:#ffffff;
opacity:0;
}
JQUERY:
$(document).ready(function(){
$(".toggle-1").click(function(){
$(".box-1").show(900);
$(".box-1").fadeTo(900,1);
});
$(".close-1").click(function(){
$(".box-1").hide(900);
$(".box-1").fadeTo(900,0);
});
$(".toggle-2").click(function(){
$(".box-2").show(900);
$(".box-2").fadeTo(900,1);
});
$(".close-2").click(function(){
$(".box-2").hide(900);
$(".box-2").fadeTo(900,0);
});
});
Well, of course there's still quite a bit of styling to be done in order for the content to appear nicely in the center of the screen, but I'm gonna be leaving that out as this is more of a question of how to control the speed of which the overlay appears.
In any case, if you wanna change the speed of which it appears or close, simply alter the "900" value to something else - a lower number means a faster animation speed and vice versa. If you have noticed, I'm applying the .hide() and .fadeTo() functions together. This is partly because I will try and enforce for the shown divs to be hidden after the Close button is clicked. This will prevent it from stacking on top of other content and thereby disabling any buttons, links or functions. You can try to play around with their "900" values as well. For e.g. when you press the close button, you can actually make .hide() execute slower in relation to the fadeTo() simply by assigning maybe 3000 to the former and 700 to the latter. This will give the illusion that it is fading only rather than fading and swinging, the latter of which is prominent when you utilize the .hide() or .show() function.
Hope this helps some how. =)
I've got this CSS Horizontal menu which number of tabs is dependant to a mysql query made by php. Recently, I got so many tabs, that it overflow under the first line of tab, and hide the top part of the content box.
I would like the tabs to overflow right of the window, with overflow hidden, but that an arrow would appear if the tabs are overflowing.
Here is an example of the html code of a menu:
<ul id="tabs">
<li class="active" id="tabFirstCategory"><a href="#" onclick='showHideTabs("FirstCategory");'>FirstCategory</a>
<li class="active" id="tabSecondCategory"><a href="#" onclick='showHideTabs("SecondCategory");'>SecondCategory</a>
</ul>
<div id="tabcontent" class="clear">Some Content</div>
And here is the CSS which style the menu and content box
body
{
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
}
ul#tabs
{
position:fixed;
width:100%;
background-color:#ffffff;
border-bottom-style: solid;
border-color: #d3d3d3;
border-width: 1px;
z-index:2;
}
ul#tabs, ul#tabs li
{
float:left;
margin:0;
padding:0;
list-style:none;
}
ul#tabs .active
{
font-weight:bold;
}
ul#tabs li a
{
float:left;
padding:4px 10px 4px;
border:1px solid #d3d3d3;
border-bottom:none;
margin-right:4px;
}
ul#tabs .active a
{
background-color:#edf4f9;
}
.clear
{
clear:both;
/*for IE6 pos*/
width:100%;
overflow:hidden;
}
#tabcontent
{
position:relative;
top:25px;
margin-bottom:25px;
}
If possible I would like to have a CSS Solution to it, but I'm not against using javascript too. (No jquery, due to managerial policy.)
You need to make your html this way
<div class="menu-outer">
<img src="left-arrow.png" onclick="moveMenu( -10 )" />
<ul>
...
</ul>
<img src="right-arrow.png" onclick="moveMenu( 10 )" />
</div>
By default set image display to none ( using css class menu-outer ). Add class ( for ex. 'large' ) which make this images visible ( will be used for div )
Now for javascript - check on load if menu fits width ( offsetWidth of ul vs. offsetWidth of div ) - if no, add 'large' class to div ( 'menu-outer large' ) - so buttons will appear
move ul using position: relative and setting its left.