Responsive menu with resizing - javascript

I need to responsive button like this:
we have 15 buttons on a menu. When the browser is resizing, some buttons add to <select>
like this:
I have this jsFiddle to demonstrate the problem:

This is too much manipulation when the window is resized. I don't know if this can be done with CSS. You should prefer that..
But here is a working but dirty fiddle with Javascript/jQuery.
You should listen to the resize event.
$(document).ready(function (event) {
buildMenu();
$(window).resize(function (event) {
buildMenu();
});
});

You can use $(window).on('resize', function() { ... }); to detect ant change in width and act accordingly.
Here's a jQuery code that works
$(function() {
$("<select />").appendTo($("nav"));
var $select = $('nav select');
$select.hide();
$("<option />", {
"selected": "selected",
"value" : "",
"text" : "Go to..."
}).appendTo($select);
$("nav a").each(function() {
var el = $(this);
$("<option />", {
"value" : el.attr("href"),
"text" : el.text()
}).appendTo($select);
});
$(window).on('resize', function() {
console.log($(window).width());
if($(window).width() < 960) {
$($select).show();
$('nav ul').hide();
}
else if($(window).width() > 960) {
$($select).hide();
$('nav ul').show();
}
});
$select.change(function() {
window.location = $(this).find("option:selected").val();
});
});
Code. See demo here: Demo

You could give each button and duplicated option a class, and then use media queries to show and hide the ones that you wish to display, keeping the logic in the JS to a minimum:
#media (max-width: SIZE-1) {
li.about-us,
li.support-1,
li.support-2,
li.support-3,
li.etc {
display: none;
}
option.about-us,
option.support-1,
option.support-2,
option.support-3,
option.etc {
display: none;
}
}

Do it the other way around, it's more flexible, so, the default situation is a dropdown menu.
In javascript listen to the window resize event, on resize, measure width available, start putting options from the dropdown in the menu till it's wider than the screen, remove last item, done.

Related

Dreaded 100% Sidebar Height - jQuery Fix, but another issue arises

So I'm currently coding a UI and it's responsive so the sidebar has to be position: absolute to get 100% height.
I used jQuery to fix the height issue for pages extending further then the original 100% of the page.
Here is the jQuery:
<script>
if (document.documentElement.clientWidth > 959) {
$(document).ready(function () {
$(window).resize(function () {
var bodyheight = $(document).height();
$(".site-sidebar").height(bodyheight);
});
$(window).ready(function () {
var bodyheight = $(document).height();
$(".site-sidebar").height(bodyheight);
});
});
}
</script>
Now.. The issue is with a page that has tabs and the last tab is longer then the "active" tab so the height isn't be adjusted correctly.. So when you click the last tab theres a white space below the sidebar.
Heres a screenshot of what I mean: https://www.dropbox.com/s/i64vm9pf15kqlo1/Screenshot%202015-02-17%2016.20.46.png?dl=0
I think I need to adjust the code so that when a tab is clicked, it will "reload" that script. However, my jQuery is limited and don't know how to go about it. Please help :) I will love you forever.
<script>
function resizeSidebar() {
if (document.documentElement.clientWidth > 959) {
var bodyHeight = $(document).height();
$(".site-sidebar").height(bodyHeight);
}
}
$(document).ready(function() {
resizeSidebar();
}
</script>
If you're using jQuery UI's tabs, add this:
$( ".selector" ).on( "tabsactivate", function( event, ui ) { resizeSidebar(); } );
Replacing .selector with what's appropriate for your HTML. Otherwise, you'll need to bind resizeSidebar to the click event of your tabs.

Jquery drag n drop photo editor with clone on parent container

I am trying to implement a banner management system and was planning on using the jquery Photo Manager. The problem I am currently facing is that I cannot seem to get the parent image to clone on the primary container.
Here is the link to the fiddle for the codes (It is basically the same from the jQuery UI site)
What I am intending to create is to allow users to drag or add the image from the left to right and users can add the same image multiple times but as soon as the image is added to the right it disappears from the left.
I was looking at this piece of code for solution but do not see any removal of DOM elements specific to the item getting moved. only items removed from the DOM are the icons.
function deleteImage($item) {
$item.fadeOut(function () {
var $list = $("ul", $trash).length ? $("ul", $trash) : $("<ul class='gallery ui-helper-reset'/>").appendTo($trash);
$item.find("a.ui-icon-trash").remove();
$item.append(recycle_icon).appendTo($list).fadeIn(function () {
$item.animate({
width: "48px"
})
.find("img")
.animate({
height: "36px"
});
});
});
}
can someone help me out with an explanation.
Thanks in advance.
Actually using the jquery .clone() function did the trick. All I had to do was instead of passing the object of the element, I passed their clones with the events.
$trash.droppable({
accept: "#gallery > li",
activeClass: "ui-state-highlight",
drop: function (event, ui) {
deleteImage(ui.draggable.clone(true));
}
});
setting the parameter to true for the clone, makes a deep copy of the element including all the events.
$("ul.gallery > li").click(function (event) {
var $item = $(this),
$target = $(event.target);
if ($target.is("a.ui-icon-trash")) {
deleteImage($item.clone(true));
} else if ($target.is("a.ui-icon-zoomin")) {
viewLargerImage($target);
} else if ($target.is("a.ui-icon-refresh")) {
$item.remove();
}
return false;
});
Here is the link to the working fiddle for reference. Link

only want my function to take place on larger screens when it is no longer a mobile device

Im having trouble getting this to work, so obviously i'm doing something wrong... I created a fade-in hover state on the submenus of my menu, which works perfectly, but when I scale down to mobile view the effect is still relevant, which I do not want as mobile devices don't have hover state. so I rapped my function in a jquery(window).resize function but then it does not work at all.
jQuery(window).resize(function() {
var w = jQuery(window).width();
if (w <= 768 ) {
jQuery('nav.main-nav li').each(function() {
var submenu = jQuery(this).find('ul:first');
jQuery(this).hover(function() {
submenu.css({opacity: 1});
submenu.stop().css({overflow:'hidden', height:'auto', display:'none'}).fadeIn(300, function() {
jQuery(this).css({overflow:'visible', height:'auto', display: 'block'});
});
},
function() {
submenu.stop().css({overflow:'hidden', height:'auto', display:'none'}).fadeOut(300, function() {
jQuery(this).css({overflow:'hidden', display:'none'});
});
});
});
}
});
Instead of using jQuery(window).width();,
try using document.documentElement.clientWidth

Make last hovered menu item stay open

I have a menu that when hovered, shows the subnav of the current hovered item by adding .stick to the submenu and removing it on mouseleave. If not hovering on another menu item I want the last hovered menu item to stay open for another 2 seconds before hiding.
Here's what I have. I know that the mouseleave() called on the container won't work since it's within the handlerOut of the ul#main-nav > li hover function but I left it to show you where I last left off.
$('ul#main-nav > li').hover(function() {
var $this = $(this);
clearTimeout(window.menustick);
$this.find('ul.submenu').addClass('stick');
}, function() {
var $this = $(this);
if($this.siblings().hover()) {
$this.find('ul.submenu').removeClass('stick');
} else if ($('#main-nav').mouseleave()) {
window.menustick = setTimeout(function(){
$this.find('ul.submenu').removeClass('stick');
}, 2000);
}
});
Here's the jsFiddle.
Thanks in advance!
JS:
$("ul#main-nav > li").hover(
function(){
$(this).children('ul').hide().fadeIn(500);
},
function () {
$('ul.submenu', this).fadeOut(2000);
});
Fiddle: http://jsfiddle.net/3F7bJ/3/
You had a couple of issues with your scripts and CSS.
Firstly, your CSS had the following rule:
nav ul#main-nav li:hover > ul.submenu {
display: block;
}
This needs to be modified to:
nav ul#main-nav li > ul.submenu.stick {
display: block;
}
This meant that your CSS was controlling the visibility rather than the class 'stick'.
As you mentioned the use of .hover() and .mouseleave() in the script code is incorrect and not required. As at that point you are already in the mouseleave (handlerOut) of the hover.
The below code appears to perform the desired effect you were looking for:
var menuStickTimeoutId;
$('ul#main-nav > li').hover(function () {
var $this = $(this);
clearTimeout(menuStickTimeoutId);
$('#main-nav ul.submenu').removeClass('stick');
$this.find('ul.submenu').addClass('stick');
}, function () {
var $this = $(this);
clearTimeout(menuStickTimeoutId);
menuStickTimeoutId = setTimeout(function () {
$this.find('ul.submenu').removeClass('stick');
}, 2000);
});
Working demo:
http://jsfiddle.net/3F7bJ/2/

though jQuery .toggle() dropdown (less than 991px width)

I am trying to toggle a menu/submenu for smaller screens. (max-width: 991px) When you click the "product" link, the .dropdown menu should show, and when the "accessories" link is selected, the .subdropdown class should show. It would be nice to tap anywhere off of the menus to release them at any depth.
Note: On screens min-width: 991px (desktop), the :hover will come into play.
Notice how my JavaScript code will not fire the sub "accessories" menu. You will have to refresh if you resize your window to test.
Here is the live example: Click Here
Here is my js code
$(function() {
if ($(window).width() < 991) {
$('#product-link').click(function() {
$('.dropdown').toggle();
});
if ('.dropdown' === true) {
$('#accessories-link').click(function() {
$('.subdropdown').show();
});
} else {
$('.dropdown').hide();
}
}
});
Edit:
Although not perfect, it works. I am still wanting to use .click and not .hover but this gets the job done.
$(document).ready(function() {
$('.top-menu').hover(
function(){
$(this).children('.sub-menu').fadeIn(200);
},
function(){
$(this).children('.sub-menu').fadeOut(200);
}
);
})
Your if statement is going to always evaluate to false.
Line 9: if ('.dropdown' === true)
In JQuery you are setting up event listeners on specific elements however your current setup is not taking advantage of the on method for your product-link. Try switching your code up to something like
$(function() {
$('#product-link').on('click mouseover', function(){
$('.dropdown').toggle();
if($('#product-link').hasClass('.dropdown')){
//something else here
}
});
});

Categories