I am using the excellent accordion menu provided by Ian Flynn of RocketMill: http://www.rocketmill.co.uk/create-accordian-boxes-with-a-rotating-arrow-using-css-jquery
This has worked well for me in the past, but I have a new client that leans towards the verbose. This presents a problem when the user attempts to click on their next desired accordion link. The accordion works correctly, but the hyperbolic amount of content shoots off of the page, presenting an obvious usability issue.
What I want to do is to reconcile the top of the active (just clicked on) "menuTitle" div with the top of its parent, the "content" div.
<div id="content">
<div class="menuTitle">
<strong>Title 1…</strong>
</div>
<div class="menuContent"> <!-- Sliding content box -->
<h5>Sub-title 1</h5>
<p>Content</p>
</div> <!-- End of div class="menuContent" -->
<!-- THE ABOVE SEVEN LINES REPEAT FOR EACH FOLD OF THE ACCORDION -->
</div> <!-- End of div id="content" -->
I have been working on this for about three days and have consulted many, many sites, jQuery guides, and whisky. I am not a jQuery expert. Please help!
Oh… I made a jsFiddle. My first: http://jsfiddle.net/Parapluie/CRXX8/
well, if i understand what you want..
http://jsfiddle.net/CRXX8/4/
$(document).ready(function() {
$('#content .menuTitle').on('click',function() {
$('#content .menuTitle').removeClass('on'); // "closes" the closing menu arrow
$('#content .menuContent').slideUp('normal'); // slide-closes the closing div
if($(this).next().is(':hidden') == true) {
$(this).addClass('on'); // "opens" the opening menu arrow
$(this).next().slideDown('normal',function(){
$('html,body').animate({scrollTop:$(this).prev().offset().top}, {queue: false,duration:250, easing: 'swing'}); // on complete slidedown, scroll the clicked .menuTitle to top of page
});// slide-opens the opening div
}
}); // end of click event
}); // end of ready
UPDATE:
As your called elements are wraped in a div called '#focusWide', you dont have to scrollTop html,body, you have to scrollTop the wraper div '#focusWide' and use position().top istead of offset().top. And i add more '11px' (half of wraper div padding).
$('#focusWide').animate({scrollTop:$(this).prev().position().top + 11 + 'px'}, {queue: false,duration:250, easing: 'swing'});
http://jsfiddle.net/CUu7h/2/
I use the function shown below, which works great in most cases. Just make sure the container/wrapper is scrollable (using overflow-y:auto). See fiddle
function scrollIntoView(oElement, sContainer, fnCallback) {
var oContainer, nContainerTop, nContainerBottom, nElemHeight, nElemTop, nElemBottom;
if (!oElement || oElement.length <= 0) {
return;
}
oContainer = (typeof sContainer == "object" ? sContainer : $(sContainer));
nContainerTop = oContainer.scrollTop();
nContainerBottom = nContainerTop + oContainer.height();
nElemHeight = oElement.height() || 25;
nElemTop = oElement[0].offsetTop - 50;
nElemBottom = nElemTop + nElemHeight + 100;
if ((nElemTop < nContainerTop) || (nElemHeight >= $(sContainer).height())) {
oContainer.animate({ scrollTop: nElemTop }, { duration: "fast", complete: fnCallback });
}
else if (nElemBottom > nContainerBottom) {
oContainer.animate({ scrollTop: (nElemBottom - $(sContainer).height()) }, { duration: "fast", complete: fnCallback });
}
else if (fnCallback) {
fnCallback();
}
}
Related
I have an overlay menu (Wordpress betheme)
After I click on a menu item it doesn't close automatically.
Can anybody help to close the menu after the click?
/* ---------------------------------------------------------------------------
* Menu | Overlay
* --------------------------------------------------------------------------- */
$('.overlay-menu-toggle').click(function(e) {
e.preventDefault();
$(this).toggleClass('focus');
$('#Overlay').stop(true, true).fadeToggle(500);
var menuH = $('#Overlay nav').height() / 2;
$('#Overlay nav').css('margin-top', '-' + menuH + 'px');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Overlay">
<nav id="overlay-menu">
<ul id="menu-felso-menu" class="menu overlay-menu">
<li id="menu-item-112" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-112">Miért mi?</li>
</ul>
</nav>
</div><a class="overlay-menu-toggle" href="#"><i class="open icon-menu-fine"></i>TOGGLE</a>
this worked for me with the Side Slide menu. Just put the code in the JS window in the "Theme Options" and adapt the menu IDs to your code. Betheme does nothing else than slide in and out the mobile menu (e.g. right: -250px;), slide the whole body to the left (e.g. left: -125px;) and display a dark "body_overlay" when the menu is active. I have links with #anker and links for normal subpages so I addressed each #anker separately (#menu-item-155).
The class .icon-menu-fine is from the burger menu to get things working again after closing the menu through JS.
jQuery( document ).ready( function( $ ) {
$('#menu-item-155 a').click(function(e) {
e.preventDefault();
$(this).toggleClass('focus');
$('#Side_slide').stop(true, true).fadeToggle(500);
$('#Side_slide').css('right', '-250px');
$('body').css('left', '0px');
$('#body_overlay').css('display', 'none');
});
$('.icon-menu-fine').click(function(e) {
e.preventDefault();
$('#Side_slide').css('right', '0px');
$('body').css('left', '-125px');
$('#body_overlay').css('display', 'block');
$('#Side_slide').css('display', 'block');
});
});
I've just copied part of BeTheme code, that closes menu with a little modifications.
Just put this code in the JS window in the "Theme Options" > "Custom CSS & JS":
jQuery(document).ready(function($) {
/* Close Side Menu on item click */
$('#Side_slide .menu-item a').click(function(e) {
e.preventDefault()
/* globals jQuery, mfn */
var mobileInitW = (mfn.mobileInit) ? mfn.mobileInit : 1240
var slide = $('#Side_slide')
var overlay = $('#body_overlay')
var ssMobileInitW = mobileInitW
var pos = slide.hasClass('left') ? 'left' : 'right'
var shiftSlide = -slide.data('width')
var shiftBody = shiftSlide / 2
var duration = 300
if (pos === 'left') {
slide.animate({ 'left': shiftSlide }, duration)
$('body').animate({ 'right': 0 }, duration)
} else {
slide.animate({ 'right': shiftSlide }, duration)
$('body').animate({ 'left': 0 }, duration)
}
overlay.fadeOut(300)
// if page contains revolution slider, trigger resize
if ($('.rev_slider').length) {
setTimeout(function() {
$(window).trigger('resize')
}, 300)
}
})
})
This is what worked for me. It seems the action button that is used will go to the set anchor on the page but wouldn't close the slide menu. Really weird behavior. Not sure ever why you would like that effect, especially when a dark overlay is placed over the page.
It seemed for in my case I needed to remove all the dollar signs. Manuel had the solution just had to change things because of the $'s
Of course, you will see I had to adjust the initial tag that I wanted to be detected for the closing of the slider.
jQuery(document).ready(function()
{
jQuery('a.action_button.scroll').click(function(e) /* Change this line with the ones below for different menu behaviours*/
{
e.preventDefault();
jQuery(this).toggleClass('focus');
jQuery('#Side_slide').stop(true, true).fadeToggle(500);
jQuery('#Side_slide').css('right', '-250px');
jQuery('body').css('left', '0px');
jQuery('#body_overlay').css('display', 'none');
});
jQuery('.icon-menu-fine').click(function(e)
{
e.preventDefault();
jQuery('#Side_slide').css('right', '0px');
jQuery('body').css('left', '0px');
jQuery('#body_overlay').css('display', 'block');
jQuery('#Side_slide').css('display', 'block');
});
});
Really sweet stuff. It was super sweet seeing the menu close finally on click.
Of course, I have since adjusted it so that if any menu element is clicked/touched on then the slide menu will disappear with the below adjustment to the above code.
jQuery('ul#menu-main-menu-1').click(function(e)
I found the most pleasing behavior was to use this one though as it will trap any click on the menu and close it.
jQuery('div#Side_slide').click(function(e)
btw: this code is inserted into the "Theme Options --> Custom CSS & JS --> JS
In my project I want to fade in divs in html and I am using the following code
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll( function(){
/* Check the location of each desired element */
$('.hideme').each( function(i){
var bottom_of_object = $(this).offset().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* If the object is completely visible in the window, fade it it */
if( bottom_of_window > bottom_of_object ){
$(this).animate({'opacity':'1'},500);
}
});
});
});
#container {
height:2000px;
}
#container div {
margin:50px;
padding:50px;
background-color:lightgreen;
}
.hideme {
opacity:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/g/jquery.fullpage#2.5.9(jquery.fullPage.min.js+vendors/jquery.easings.min.js+vendors/jquery.slimscroll.min.js)"></script>
<link href="https://cdn.jsdelivr.net/jquery.fullpage/2.5.9/jquery.fullPage.min.css" rel="stylesheet" />
<div id="container">
<div>Hello</div>
<div>Hello</div>
<div>Hello</div>
<div>Hello</div>
<div>Hello</div>
<div>Hello</div>
<div class="hideme">Fade In</div>
<div class="hideme">Fade In</div>
<div class="hideme">Fade In</div>
<div class="hideme">Fade In</div>
<div class="hideme">Fade In</div>
</div>
which can be found at this JS Fiddle
In the project I also use the javascript code for
$(document).ready(function() {
$('#fullpage').fullpage();
});
which basically makes the scrolling better, details at https://github.com/alvarotrigo/fullPage.js/
The problem: Because of the full page code the fading in function does not enter the scroll if condition.
I think you're looking for something like this JS Fiddle 1
JS:
//initialize
var winHeight = $(window).height(),
sections = $('.sections'),
currentSlide = 0;
$('html, body').animate({scrollTop: 0}, 0);
//hide elements not in the view as the page load for the first time
sections.each(function() {
if ($(this).offset().top > winHeight - 5) {
$(this).fadeOut(0);
}
});
//show elements on scroll
$(window).scroll(function(event) {
// retrieve the window scroll position, and fade in the 2nd next section
// that its offset top value is less than the scroll
scrollPos = $(window).scrollTop();
if (scrollPos >= currentSlide * winHeight) {
nextSlide = currentSlide + 2;
$('#sec-' + nextSlide).fadeIn();
// as long as current slide is still in range of the number of sections
// we increase it by one.
if (currentSlide <= sections.length) {
currentSlide++;
}
}
});
----------
Update:
Upon a comment by the OP "I want the divs within sections to fade in on scroll not the section div but the ones inside it as there are multiple", all what we need to do is to change this line $(this).fadeOut(0); to this $(this).children().fadeOut(0); and then this line:
$('#sec-' + nextSlide).fadeIn(); to this $('#sec-' + nextSlide).children().fadeIn(1500);
and now, instead of the section itself, we're fading in and out all children of that section.
JS Fiddle 2
I'm surprised the previous answer got so many upvotes when the scroll event doesn't even get fired when using fullPage.js :D
The solution for your problem is detailed in the fullPage.js FAQs.
Which is basically using the fullPage.js option scrollbar:true or autoScrolling:false. This way the scroll event will get fired.
If you still want to use your fading effects when changing from one section to another, the proper solution is making use of fullPage.js callbacks or fullpage.js state classes to fire the animations. That can be done using javascript or plain css 3.
Check an example on how to use css3 animations in combination with the fullpage.js state classes on this video tutorial.
I have a 'sticky sidebar nav' that is positioned absolutely relative to the #sidebar div, so it follows the page down on the left hand side and is always available. To make this work I had to add a height to the sidebar, so I used some code to find the height of the container dynamically. This is the code i used:
<script type="text/javascript">
function matchColHeights(col1, col2) {
var col1Height = $(col1).height();
var col2Height = $(col2).height();
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
}
$(document).ready(function() {
matchColHeights('#sidebar', 'section#main-container');
})
</script>
Currently the #sidebar div sits inside the section called section#maincontainer. A very simplified version of the html is below.
<body>
<header>Header content</header>
<section id="main-container">
<div id="sidebar">
<ul>
This is the floated ul
<ul>
</div>
<div class="content">
This is where the content of the page sits
</div>
<div class="content2">
This is where the content of the page sits (because of the design there are often more than one divs floated right
<div>Within the content divs are potential expanding divs (accordions and tabs that change size)</div>
</div>
</section>
<footer>Footer content</footer>
</body>
So the problem I have is that there is expandable content (tabs and accordions) in the content area, and when the content expands, the jQuery does not update the height of the sidebar to the new height (this new height could be shorter or longer than the original height). I have tried adding the function to my .click() handler of the accordion (haven't yet tried with the tabs) but here is the code that is used to drop my accordion down:
<!--Content Accordion-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordion> div').hide();
$('div.content-accordion> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
});
} else {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
}
});
});
</script>
As you can see I can add the $matchColHeights('#sidebar', 'section#main-container'); function into the click function and it doesn't refresh to the new height still. I have tried a few other possibilities with no luck.
Just to let everyone know i found a solution...Took alot of messing about but code is below.
I essentially on the click had to set sidebar height back to 0, and create a function that finds the new height of the section#main-container, and then applys that as a css height to the sidebar. This changed the height of the sidebar just fine, but then the sticky sidebar wasnt readjusting to the new height, so i just pasted the code that works my sticky sidebar (the code that starts with $("aside") into the function and it refreshes just fine. Thanks to those that helped.
<!--Content Accordian-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordian> div').hide();
$('div.content-accordian> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
});
} else {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
}
});
});
</script>
I believe you could write
if (col1Height !== col2Height) {
$(col1).height(col2Height);
}
instead of
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
But that won't solve your problem.
You probably have to fire that matchColHeights() function from inside a callback like this:
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
});
} else {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
}
Let me know if it worked.
I have the following javascript that shows or hides a div when a link is clicked:
<script type="text/javascript">
$(document).ready(function(){
$('.show_hide').showHide({
speed: 500, // speed you want the toggle to happen
changeText: 0, // if you dont want the button text to change, set this to 0
showText: 'View',// the button text to show when a div is closed
hideText: 'Close' // the button text to show when a div is open
});
});
(function ($) {
$.fn.showHide = function (options) {
//default vars for the plugin
var defaults = {
speed: 1000,
easing: '',
changeText: 0,
showText: 'Show',
hideText: 'Hide',
};
var options = $.extend(defaults, options);
$(this).click(function () {
// this var stores which button you've clicked
var toggleClick = $(this);
// this reads the rel attribute of the button to determine which div id to toggle
var toggleDiv = $(this).attr('rel');
// here we toggle show/hide the correct div at the right speed and using which easing effect
$(toggleDiv).slideToggle(options.speed, options.easing, function() {
// this only fires once the animation is completed
if(options.changeText==1){
$(toggleDiv).is(":visible") ? toggleClick.text(options.hideText) : toggleClick.text(options.showText);
}
});
return false;
});
};
})(jQuery);
</script>
The problem is, I have two such divs, but I only want one to be displayed at a time. So, if someone clicks on the link to display div 2, and div 1 is already displayed, it should hide itself first before displaying div2.
Relevant HTML:
<div class="button">FAQs</div>
<div class="button">Contact</div>
<div id="faq" class="faq">FAQs here </div>
<div id="contact" class="faq">Contact form here </div>
I don't have any experience with JS/Jquery, but I tried adding this code, which didn't work:
var otherDiv;
if ($(this).attr('rel') == 'contact')
otherDiv = 'faq';
else
otherDiv = 'contact';
if ($(otherDiv).is(":visible"))
$(otherDiv).slideToggle(options.speed);
Most people use CSS classes as a place to store 'metadata'. When a div becomes visible, add a class to it like "toggledVisible" or whatever. When a new toggle is clicked, find all instances of "toggledVisible", hide them, and remove that class.
Alternatively, you always keep track of some sort of "currentlyVisible" object and toggle it.
Maybe jQuery ui accordion is an alternative?
HTML:
<div class="accordion">
<h3>FAQs</h3>
<div id="faq" class="faq">FAQs here</div>
<h3>Contact</h3>
<div id="contact" class="faq">Contact form here</div>
</div>
JS:
jQuery(document).ready(function() {
jQuery(".accordion").accordion();
});
Also see my jsfiddle.
=== UPDATE ===
JS:
jQuery(document).ready(function() {
jQuery(".accordion").accordion({
autoHeight: false
});
});
Also see my updated jsfiddle.
Try to add this row in your click() function
$('.faq').not(this).hide();
This will hide all shown divs except the one you clicked.
I want to only show the menu phrases "music, newsletter, contact" fixed at the bottom of the screen. On hover I want them to slide up and reveal hidden content. here's exactly what I mean:
http://sorendahljeppesen.dk/
See the bottom of the screen. Anyone know how this would be accomplished? Thank you.
P.S. also, would anyone know what type of MP3 player that is?
Put your hidden content into a div such as;
<div class="hiddenContent">...</div>
Then give your links at the bottom of the page a class such as;
Music
Then tell the Jquery to show the hidden content when you hover over the link;
$('.bottomLink').hover(
function () {
// Show hidden content IF it is not already showing
if($('.hiddenContent').css('display') == 'none') {
$('.hiddenContent').slideUp('slow');
}
},
function () {
// Do nothing when mouse leaves the link
$.noop(); // Do Nothing
}
);
// Close menu when mouse leaves Hidden Content
$('.hiddenContent').mouseleave(function () {
$('.hiddenContent').slideDown('slow');
});
Try this code:
ASPX section,
<div id="categories-menu" class="hover-menu">
<h2>Categories</h2>
<ul class="actions no-style" style="display: none">
<li>//Place your content here that should show up on mouse over</li>
</ul>
</div>
JQuery section,
<script type="text/javascript">
$(document).ready(function() {
function show() {
var menu = $(this);
menu.children(".actions").slideUp();
}
function hide() {
var menu = $(this);
menu.children(".actions").slideDown();
}
$(".hover-menu").hoverIntent({
sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)
interval: 50, // number = milliseconds for onMouseOver polling interval
over: show, // function = onMouseOver callback (required)
timeout: 300, // number = milliseconds delay before onMouseOut
out: hide // function = onMouseOut callback (required)
});
});
</script>
Hope this helps...
I have found this great article with live demo and source code to download, the article show how to make a slide out menu from bottom.