The following nav I'm building works just fine, however I noticed that when click outside the nav buttons but still inside <nav> container the open dropdown doesn't close as it should however it does close when click outside <nav>.
How can that be? Thank you for your help.
See Demo here
JQuery
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if (menu.hasClass('active')) {
menu.removeClass('active');
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
}
You have to change your container, something like:
var container = $("nav .top-bar-section ul");
I want to enable and disable or better to add and remove jQuery accordion on my menu conditionally, is it possible to add or remove this on screen rotate or screen-size change ? I tried it but It does not seems to be working, The accordion is remaining for change in screen-size .
jQuery( document ).ready( function(){
apply_accordion();
jQuery(window).on("orientationchange",function(){
apply_accordion();
});
} );
function apply_accordion(){
if (jQuery(window).width() < 540) {
jQuery('.footer-area').accordion({
icons: { "header": "icon-large ui-icon-carat-1-s", "activeHeader": "icon-large ui-icon-caret-1-n" },
active: false,
autoHeight: false,
navigation: true,
collapsible: true,
});
} else {
//jQuery( '.footer-area' ).accordion( "disable" );
//jQuery( '.footer-area' ).accordion( "destroy" );
// jQuery( '.footer-area' ).accordion( "refresh" );
jQuery( '.footer-area' ).accordion( "destroy" ).accordion();
}
}
update
if else part will be,
} else {
jQuery( '.footer-area' ).accordion( "destroy" );
jQuery('.footer-area').accordion('option', 'active', 0);
}
when I starts with moving from portrait to landscape, it is working, but the reverse is not working , means when I am moving from landscape to portrait it is not working . And also gives error in console cannot call methods on accordion prior to initialization; attempted to call method 'destroy'
New jsfield
I would like to remove and add accordion with screen size.
Note:
jQuery version 1.11.4
check Techbreak's answer https://jsfiddle.net/voytfj2q/20/ it seems to be working but if you will check console it will generate " Uncaught Error: cannot call methods on accordion prior to initialization; attempted to call method 'destroy'" . and in actual implementation it does not work when I am moving from landscape to portrait.
And I have also posted an workaround, for now in my implementation it is working for me, but I know this is only a workaround.
Here is another fiddle if you will increase and decrease the screen-size slowly you can notice the issue.
Screenshot of issue, you can notice for few of them the accordion is disabled for increase in size and for some it is not disabled.
You need to activate the accordian to expand when the size is big enough to expand the content or screen rotated completely as follows,
jQuery(document).ready(function() {
jQuery(window).on("resize", function() {
if (jQuery(window).width() < 540) {
jQuery('.footer-area').accordion({
active: false, collapsible:true, active:true
});
} else {
//reactivate the accordian so that it can be expanded again
jQuery('.footer-area').accordion('option', 'active', 0);
}
});
Working fiddle for your example : https://jsfiddle.net/voytfj2q/18/
});
OK. Actually, you have solved the issue with many different instances of the accordion, which wasn't in evidence from your original post, so the wrong selector .footer-area used here:
jQuery('.footer-area').accordion({
active: false, collapsible:true, active:true
});
has been adjusted.
Issue #1:
As you need to create and destroy the widget based on the page size, we need to check for the existence of every widget instance before calling any method of the accordion, otherwise we will raise the infamous error: ...cannot call methods on *some-widget* prior to initialization.
This issue is solved by checking for the existence of the data which has been appended to the element at widget instance creation:
var isInstance1 = (typeof jQuery('#footer-widget-area-1 .footer-area').data("ui-accordion") != "undefined");
Issue #2:
When you are switching back to the unstyled menu, the page height will increase and the page will show the vertical scrollbar, which is resulting in a different page width. The page is resized again and your check for window.width will behave unstable.
This is the reason why you need to check for jQuery('body').width() + scrollbar_width(). Simply take the provided function to get the scrollbar width as-is, and include it in your snippet lbrary.
Fiddle: https://jsfiddle.net/Lgx4es86/6/
/* Calculates scrollbar width in pixels */
function scrollbar_width() {
if( jQuery('body').height() > jQuery(window).height()) {
/* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append( calculation_content );
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return ( width_one - width_two );
}
return 0;
}
jQuery( document ).ready( function(){
apply_accordion();
jQuery(window).resize(function() {
apply_accordion();
});
} );
function apply_accordion(){
var ww = jQuery('body').width() + scrollbar_width();
if (ww < 540) {
jQuery('#footer-widget-area-1 .footer-area').accordion({
active: false, collapsible:true
});
jQuery('#footer-widget-area-2 .footer-area').accordion({
active: false, collapsible:true
});
jQuery('#footer-widget-area-3 .footer-area').accordion({
active: false, collapsible:true
});
jQuery('#footer-widget-area-5 .footer-area').accordion({
active: false, collapsible:true
});
jQuery('#footer-widget-area-6 .footer-area').accordion({
active: false, collapsible:true
});
} else {
var isInstance1 = (typeof jQuery('#footer-widget-area-1 .footer-area').data("ui-accordion") != "undefined");
if (isInstance1) {
jQuery('#footer-widget-area-1 .footer-area').accordion('option', 'active', 0);
jQuery('#footer-widget-area-1 .footer-area').accordion("destroy");
}
var isInstance2 = (typeof jQuery('#footer-widget-area-2 .footer-area').data("ui-accordion") != "undefined");
if (isInstance2) {
jQuery('#footer-widget-area-2 .footer-area').accordion('option', 'active', 0);
jQuery('#footer-widget-area-2 .footer-area').accordion("destroy");
}
var isInstance3 = (typeof jQuery('#footer-widget-area-3 .footer-area').data("ui-accordion") != "undefined");
if (isInstance3) {
jQuery('#footer-widget-area-3 .footer-area').accordion('option', 'active', 0);
jQuery('#footer-widget-area-3 .footer-area').accordion("destroy");
}
var isInstance5 = (typeof jQuery('#footer-widget-area-5 .footer-area').data("ui-accordion") != "undefined");
if (isInstance5) {
jQuery('#footer-widget-area-5 .footer-area').accordion('option', 'active', 0);
jQuery('#footer-widget-area-5 .footer-area').accordion("destroy");
}
var isInstance6 = (typeof jQuery('#footer-widget-area-6 .footer-area').data("ui-accordion") != "undefined");
if (isInstance6) {
jQuery('#footer-widget-area-6 .footer-area').accordion('option', 'active', 0);
jQuery('#footer-widget-area-6 .footer-area').accordion("destroy");
}
// var isInstance = (typeof jQuery('.footer-area').data("ui-accordion") != "undefined");
// if (isInstance){
// jQuery('.footer-area').accordion('option', 'active', 0);
// jQuery('.footer-area').accordion( "destroy" );
// }
}
}
Your workaround:
You are applying and removing the accordion styles, but not destroying the widget instances, so data event handlers are still there. You would need at least to move the jQuery('.footer-area').accordion part in another place to execute it just only one time. Moreover, beside this, the page width issue isn't solved by your workaround.
Scrollbar width function: credit Alex Mansfield (http://alexmansfield.com/javascript/css-jquery-screen-widths-scrollbars)
A work around will be removing and adding the classes and attributes when ever the screen size is changing. I am posting this workaround but would like to have an correct solution to it.
jQuery(document).ready(function() {
jQuery(window).on("resize", function() {
if (jQuery(window).width() < 540) {
jQuery('.footer-area').accordion({
active: false, collapsible:true, active:true
});
jQuery('.footer-area h2').append('<span class="ui-accordion-header-icon ui-icon ui-icon-carat-1-s"></span>');
jQuery('.footer-area div').css('display', 'none');
jQuery('.footer-area div').addClass('ui-widget-content');
jQuery('.footer-area div').addClass('ui-accordion-content');
jQuery('.footer-area h2').addClass('ui-accordion-header');
jQuery('.footer-area h2').addClass('ui-accordion-icons');
} else {
jQuery('.footer-area h2 .ui-accordion-header-icon').remove();
jQuery('.footer-area div').removeAttr('style');
jQuery('.footer-area div').removeClass('ui-widget-content');
jQuery('.footer-area div').removeClass('ui-accordion-content');
jQuery('.footer-area h2').removeClass('ui-accordion-header');
jQuery('.footer-area h2').removeClass('ui-accordion-icons');
}
});
There an option using pure css in which you can use media quires to show or hide them accordingly based on screen size:
Let's say you have ui-accordion-header class on your accordion headers when it's rendered.
Now you can put this in your style sheet:
#media screen and (min-width: 0) and (max-width: 1024px) {
.ui-accordion-header { display: block; } /* show it on small screens */
}
#media screen and (min-width: 0) and (max-width: 400px) {
.ui-accordion-header { display: none; } /* hide it elsewhere */
}
Or:
#media all and (orientation:portrait) {
.ui-accordion-header { display: none; }
}
#media all and (orientation:landscape) {
.ui-accordion-header { display: block; }
}
And you don't need to write any js code. Check the code here.
var myAccordion = null;
jQuery(document).ready(function () {
createAccordion(true);
jQuery(window).bind("resize", function (event) {
updateAccordion();
});
});
function createAccordion(value){
try{
$(".footer-area").accordion({
icons: {"header": "icon-large ui-icon-carat-1-s", "activeHeader": "icon-large ui-icon-caret-1-n"},
active: 0,
// heightStyle: "fill",
collapsible: value
});
}catch(e){
alert(e);
}
}
function updateAccordion() {
try{
var w = jQuery(window).width();
if (w < 540){
$(".footer-area").accordion("option", "collapsible", false);
}else{
$(".footer-area").accordion("option", "collapsible", true);
}
}catch(e){
alert(e);
}
}
see http://liveweave.com/Pieivc
what i want that in start there show be no icon for arrow up as not needed but when user click arrow down it appears should appears and when user reaches last itme in ul li list bottom arrow should vanish
how can i do to check it ?..
(function () {
$('#scrollup').on({
'mousedown touchstart': function() {
$(".sidebar-menu").animate({scrollTop: 0}, 2000);
},
'mouseup touchend': function() {
$(".sidebar-menu").stop(true);
}
});
$('#scrolldown').on({
'mousedown touchstart': function() {
$(".sidebar-menu").animate({
scrollTop: $(".sidebar-menu")[0].scrollHeight
}, 2000);
},
'mouseup touchend': function() {
$(".sidebar-menu").stop(true);
}
});
})();
You can check this using $('.sidebar-menu').scrollTop() value.
So for example, I wrote a function called check(), which checks the location of the scroll and display/hide the appropriate arrows. This function is called on mouse touchend event of each arrow.
function check() {
if ($('.sidebar-menu').scrollTop() == 0) {
$('#scrollup').hide();
$('#scrolldown').show();
} else if ($('.sidebar-menu').scrollTop() == height - 100) {
$('#scrolldown').hide();
$('#scrollup').show();
}
}
See it in action: http://jsfiddle.net/ry2zwho1/1/
Try to use this jsfiddle
$(function(){
var carousel = $('.carousel ul');
var carouselChild = carousel.find('li');
var clickCount = 0;
var canClick = true;
$(".btnPrevious").css('color', 'red').show();
itemWidth =......
Please see my FIDDLE
I've got a 1 page website with a "responsive" navigation menu (with anchor links to elements on the page) that prepends to a menu icon when the browser viewport is smaller than a specific width (in my case 767px) using this javascript:
jQuery(document).ready(function($){
$('#menu_wrapper').prepend('<div id="menu-icon">Menu</div>');
$("#menu-icon").on("click", function(){
$("#menu").slideToggle();
$(this).toggleClass("active");
});
});
As you can see in the fiddle I'm also using javascript to make the navigation sticky when scrolling down past navigation element regardless of the viewport size.
Now the problem I have is that when I am below the viewport of 767px, I click on the toggle 'MENU' button to open / show the navigation and when I click an option in the menu, the page scrolls to the correct part of the page BUT the menu stays open.
What I want is the menu to close (slide back up) when an option is clicked in the menu (obviously this must only apply when I am below below the viewport of 767px).
How can I do this?
$('#menu li a').on("click", function(){
$('#menu').slideUp();
});
just slideUp() if #menu li a is clicked
updated jsFiddle: http://jsfiddle.net/ayhpp8ax/1/
Just add this in $(document).ready function
$('#menu li').on('click', function(){
$("#menu").hide();
$("#menu-icon").removeClass("active");
});
(function($) {
$.fn.menumaker = function(options) {
var cssmenu = $(this), settings = $.extend({
title: "Menu",
format: "dropdown",
sticky: false
}, options);
return this.each(function() {
cssmenu.prepend('<div id="menu-button">' + settings.title + '</div>');
$(this).find("#menu-button").on('click', function(){
$(this).toggleClass('menu-opened');
var mainmenu = $(this).next('ul');
if (mainmenu.hasClass('open')) {
mainmenu.hide().removeClass('open');
}
else {
mainmenu.show().addClass('open');
if (settings.format === "dropdown") {
mainmenu.find('ul').show();
}
}
});
cssmenu.find('li ul').parent().addClass('has-sub');
multiTg = function() {
cssmenu.find(".has-sub").prepend('<span class="submenu-button"></span>');
cssmenu.find('.submenu-button').on('click', function() {
$(this).toggleClass('submenu-opened');
if ($(this).siblings('ul').hasClass('open')) {
$(this).siblings('ul').removeClass('open').hide();
}
else {
$(this).siblings('ul').addClass('open').show();
}
});
};
if (settings.format === 'multitoggle') multiTg();
else cssmenu.addClass('dropdown');
if (settings.sticky === true) cssmenu.css('position', 'fixed');
resizeFix = function() {
if ($( window ).width() > 1500) {
cssmenu.find('ul').show();
}
if ($(window).width() <= 900) {
cssmenu.find('ul').hide().removeClass('open');
}
};
resizeFix();
return $(window).on('resize', resizeFix);
});
};
})(jQuery);
(function($){
$(document).ready(function(){
$("#cssmenu").menumaker({
title: "Menu",
format: "multitoggle"
});
});
})(jQuery);
I am using a template and it come with a jQuery function to detect the window width, but it only works if you open the window up or refresh the page, not when you adjust the window width.. From what IU have read I need to integrate the resize function into my codebase
$(window).resize(function()
but as my jQuery is limited I'm not sure how to put it in this script
var ww = $(window).width();
/* Menu */
$(document).ready(function() {
"use strict";
$('body').find("#mainmenu li a").each(function() {
if ($(this).next().length > 0) {
$(this).addClass("parent");
}
});
$('body').find(".toggleMenu").click(function(e) {
e.preventDefault();
$(this).toggleClass("active");
$('body').find("#mainmenu").toggle();
});
adjustMenu();
});
$(window).load(function () {
$('body').find("#mainmenu").css('pointer-events', 'auto');
});
var adjustMenu = function() {
"use strict";
if (ww < 900) {
$('body').find(".toggleMenu").css("display", "inline-block");
if (!$('body').find(".toggleMenu").hasClass("active")) {
$('body').find("#mainmenu").hide();
} else {
$('body').find("#mainmenu").show();
}
$('body').find("#mainmenu li").unbind('mouseenter mouseleave');
$('body').find("#mainmenu li a.parent").unbind('click').bind('click', function(e) {
e.preventDefault();
$(this).parent("li").toggleClass("hover");
});
}
else if (ww >= 900) {
$('body').find(".toggleMenu").css("display", "none");
$('body').find("#mainmenu").show();
$('body').find("#mainmenu li").removeClass("hover");
$('body').find("#mainmenu li a").unbind('click');
$('body').find("#mainmenu li").unbind('mouseenter mouseleave').bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
$(this).toggleClass('activelink');
$(this).find("ul").toggleClass('animatedfast');
$(this).find("ul").toggleClass('fadeInUp');
});
$('body').find("#mainmenu ul li").unbind('mouseenter mouseleave').bind('mouseenter mouseleave', function() {
$(this).toggleClass('hover');
$(this).find("ul li").toggleClass('animatedfast');
$(this).find("ul li").toggleClass('fadeInLeft');
});
}
};
I can see that the logic is taking place in the adjustMenu function, so would I wrap that in the resize function?
Maybe I'm missing something obvious, but why not pull the whole thing out of
$(document).ready ()
Place it in a function
Function doAllOfThis (
//do everything
);
And then call it on document ready?
$(document).ready(function ({
doAllOfThis();
});
$(widow).resize (function ({
doAllOfThis();
});
I don't see anything that would be an issue. But you could just extract the code with "if ww =" conditions and move that to a function, then do as above with the function.
BETTER SOLUTION
Just noticed the
adjustMenu();
Function is already set for you, so add
$(window).resize(function({
var ww = $(window).width();
adjustMenu();
});
Utilize the resize event.
$(window).resize(function() {
var ww = $(window).width(); // will contain width after resize
// your adjust logic here
});