Draggable drop-down menu in a website (display menu elements by touchslide) - javascript

I want to make a menu like the one in this image:
On the left side there's the complete menu (where each button is a div), but the buttons are not displayed when I open the page. I want to display the buttons by holding and sliding (possibly with a touchslide?), but this must work on mobile devices. Also, it doesn't matter if it doesn't work on a PC.
I don't know if this is possible by using jQuery mobile, Hammer, or another library. I already did a menu which displays all the buttons with a single click on the first button, but the designer is not happy with just that. My code is something like this:
<div id="main_button">Button</div>
<nav id="main_menu">
<div id="b1">Yellow</div>
<div id="b2">Red</div>
<div id="b3">Blue</div>
<div id="b4">Green</div>
<div id="b5">Orange</div>
<div id="b6">Purple</div>
</nav>
Do you know if this is possible? If so, what can I use to accomplish this task?

EDIT 1
More possible partial solutions:
JQuery Mobile : Pull to refresh list view
https://github.com/watusi/jquery-mobile-iscrollview
EDIT 0
Similar question: Does anyone know of a pulldown menu plugin in javascript?
And the solution: http://jsfiddle.net/JXeWA/46/
I think it's possible but you might have to customize the code to your specifications. Here's one example I found: http://jsfiddle.net/vxvgH/3/light/
This example uses a similar effect to refresh the page. That might helpful in customizing your code.
Below you'll find the JavaScript from the first example. It's messy but it's somewhere to start.
var startPosition = 0;
var pagePosition = 0;
var scrollY = 0;
var scrollPrevented = false;
$(document).on('vmousedown', '.dragme', function(event) {
var startPosition = pagePosition;
$(document).on('vmousemove', function(event2) {
scrollY = event2.pageY;
pagePosition = startPosition + scrollY - event.pageY;
if (pagePosition > $("#menu").height()) {
pagePosition = $("#menu").height();
} else if (pagePosition < 0) {
pagePosition = 0;
}
if (scrollPrevented == false) {
scrollPrevented = true;
$(document).on('touchmove', function(ev) {
ev.preventDefault();
});
}
$("#menu").css({
'z-index': '-1'
});
menuSlide();
$("#menu").show();
});
});
$(document).on('vmouseup', function() {
if (scrollPrevented == true) {
$('body').unbind('touchmove');
scrollPrevented = false;
}
$(document).off('vmousemove', stopScroll());
});
function menuSlide() {
var newHeight = $(window).height() - pagePosition;
$("#page1").css({
top: pagePosition,
height: newHeight
}).page();
$("#page2").css({
top: pagePosition,
height: newHeight
}).page();
}
function stopScroll() {
if (pagePosition > $("#menu").height() / 2) {
pagePosition = $("#menu").height();
$("#menu").show();
$("#menu").css({
'z-index': '1500'
});
} else {
pagePosition = 0;
$("#menu").hide();
$("#menu").css({
'z-index': '-1'
});
}
menuSlide();
}
$("#menu").css({
position: "absolute",
width: $(window).width(),
height: $(window).height * .3,
left: 0,
'z-index': '-1',
'min-height': 'initial'
}).page();
$(document).on("click", ".page1", function(){
$("#menu").css({
'z-index': '-1'
});
pagePosition = 0;
menuSlide();
$("#menu").hide();
$.mobile.changePage("#page1", {transition:"slide",
reverse: true});
});
$(document).on("click", ".page2", function(){
pagePosition = 0;
menuSlide();
$("#menu").hide();
$.mobile.changePage("#page2", {transition:"slide"});
});
​

Related

How to call a div height in jQuery and set it into the css of another div dynamically (upon window resizing)? [duplicate]

I have the following JQuery code:
$(document).ready(function () {
var $containerHeight = $(window).height();
if ($containerHeight <= 818) {
$('.footer').css({
position: 'static',
bottom: 'auto',
left: 'auto'
});
}
if ($containerHeight > 819) {
$('.footer').css({
position: 'absolute',
bottom: '3px',
left: '0px'
});
}
});
The only problem is that this only works when the browser first loads, I want containerHeight to also be checked when they are resizing the window?
Any ideas?
Here's an example using jQuery, javascript and css to handle resize events.
(css if your best bet if you're just stylizing things on resize (media queries))
http://jsfiddle.net/CoryDanielson/LAF4G/
css
.footer
{
/* default styles applied first */
}
#media screen and (min-height: 820px) /* height >= 820 px */
{
.footer {
position: absolute;
bottom: 3px;
left: 0px;
/* more styles */
}
}
javascript
window.onresize = function() {
if (window.innerHeight >= 820) { /* ... */ }
if (window.innerWidth <= 1280) { /* ... */ }
}
jQuery
$(window).on('resize', function(){
var win = $(this); //this = window
if (win.height() >= 820) { /* ... */ }
if (win.width() >= 1280) { /* ... */ }
});
How do I stop my resize code from executing so often!?
This is the first problem you'll notice when binding to resize. The resize code gets called a LOT when the user is resizing the browser manually, and can feel pretty janky.
To limit how often your resize code is called, you can use the debounce or throttle methods from the underscore & lodash libraries.
debounce will only execute your resize code X number of milliseconds after the LAST resize event. This is ideal when you only want to call your resize code once, after the user is done resizing the browser. It's good for updating graphs, charts and layouts that may be expensive to update every single resize event.
throttle will only execute your resize code every X number of milliseconds. It "throttles" how often the code is called. This isn't used as often with resize events, but it's worth being aware of.
If you don't have underscore or lodash, you can implement a similar solution yourself:
JavaScript/JQuery: $(window).resize how to fire AFTER the resize is completed?
Move your javascript into a function and then bind that function to window resize.
$(document).ready(function () {
updateContainer();
$(window).resize(function() {
updateContainer();
});
});
function updateContainer() {
var $containerHeight = $(window).height();
if ($containerHeight <= 818) {
$('.footer').css({
position: 'static',
bottom: 'auto',
left: 'auto'
});
}
if ($containerHeight > 819) {
$('.footer').css({
position: 'absolute',
bottom: '3px',
left: '0px'
});
}
}
Try this solution. Only fires once the page loads and then during window resize at predefined resizeDelay.
$(document).ready(function()
{
var resizeDelay = 200;
var doResize = true;
var resizer = function () {
if (doResize) {
//your code that needs to be executed goes here
doResize = false;
}
};
var resizerInterval = setInterval(resizer, resizeDelay);
resizer();
$(window).resize(function() {
doResize = true;
});
});
jQuery has a resize event handler which you can attach to the window, .resize(). So, if you put $(window).resize(function(){/* YOUR CODE HERE */}) then your code will be run every time the window is resized.
So, what you want is to run the code after the first page load and whenever the window is resized. Therefore you should pull the code into its own function and run that function in both instances.
// This function positions the footer based on window size
function positionFooter(){
var $containerHeight = $(window).height();
if ($containerHeight <= 818) {
$('.footer').css({
position: 'static',
bottom: 'auto',
left: 'auto'
});
}
else {
$('.footer').css({
position: 'absolute',
bottom: '3px',
left: '0px'
});
}
}
$(document).ready(function () {
positionFooter();//run when page first loads
});
$(window).resize(function () {
positionFooter();//run on every window resize
});
See: Cross-browser window resize event - JavaScript / jQuery
Give your anonymous function a name, then:
$(window).on("resize", doResize);
http://api.jquery.com/category/events/
function myResizeFunction() {
...
}
$(function() {
$(window).resize(myResizeFunction).trigger('resize');
});
This will cause your resize handler to trigger on window resize and on document ready. Of course, you can attach your resize handler outside of the document ready handler if you want .trigger('resize') to run on page load instead.
UPDATE: Here's another option if you don't want to make use of any other third-party libraries.
This technique adds a specific class to your target element so you have the advantage of controlling the styling through CSS only (and avoiding inline styling).
It also ensures that the class is only added or removed when the actual threshold point is triggered and not on each and every resize. It will fire at one threshold point only: when the height changes from <= 818 to > 819 or vice versa and not multiple times within each region. It's not concerned with any change in width.
function myResizeFunction() {
var $window = $(this),
height = Math.ceil($window.height()),
previousHeight = $window.data('previousHeight');
if (height !== previousHeight) {
if (height < 819)
previousHeight >= 819 && $('.footer').removeClass('hgte819');
else if (!previousHeight || previousHeight < 819)
$('.footer').addClass('hgte819');
$window.data('previousHeight', height);
}
}
$(function() {
$(window).on('resize.optionalNamespace', myResizeFunction).triggerHandler('resize.optionalNamespace');
});
As an example, you might have the following as some of your CSS rules:
.footer {
bottom: auto;
left: auto;
position: static;
}
.footer.hgte819 {
bottom: 3px;
left: 0;
position: absolute;
}
Use this:
window.onresize = function(event) {
...
}
can use it too
function getWindowSize()
{
var fontSize = parseInt($("body").css("fontSize"), 10);
var h = ($(window).height() / fontSize).toFixed(4);
var w = ($(window).width() / fontSize).toFixed(4);
var size = {
"height": h
,"width": w
};
return size;
}
function startResizeObserver()
{
//---------------------
var colFunc = {
"f10" : function(){ alert(10); }
,"f50" : function(){ alert(50); }
,"f100" : function(){ alert(100); }
,"f500" : function(){ alert(500); }
,"f1000" : function(){ alert(1000);}
};
//---------------------
$(window).resize(function() {
var sz = getWindowSize();
if(sz.width > 10){colFunc['f10']();}
if(sz.width > 50){colFunc['f50']();}
if(sz.width > 100){colFunc['f100']();}
if(sz.width > 500){colFunc['f500']();}
if(sz.width > 1000){colFunc['f1000']();}
});
}
$(document).ready(function()
{
startResizeObserver();
});
You can bind resize using .resize() and run your code when the browser is resized. You need to also add an else condition to your if statement so that your css values toggle the old and the new, rather than just setting the new.

JQuery for fixed position of navigation bar [duplicate]

This question already has answers here:
JQuery Position:Fixed 'NAVBAR' by scrolling the page
(2 answers)
Closed 6 years ago.
Hello I am new to JavaScript please can anyone tell me the JQuery for keeping the navigation bar fixed on top while I scroll down.
I am using the following code but i think some contents are missing
Code Snippet :
var fixmeTop = $('.fixme').offset().top;
$(window).scroll(function() {
var currentScroll = $(window).scrollTop();
if (currentScroll >= fixmeTop) {
$('.fixme').css({ position: 'fixed', top: '0', left: '0' });
}
else {
$('.fixme').css({ position: 'static' });
}
});
$( document ).ready(function() {
var fixmeTop = $('.fixme').offset().top;
$(window).scroll(function () {
var currentScroll = $(window).scrollTop();
if (currentScroll > fixmeTop) {
$('.fixme').css({position: 'fixed', top: '0', left: '0'});
} else {
$('.fixme').css({position: 'static'});
}
});
});
If you want it fixed all the time, use something like:
.class_name {
position: fixed;
}
If you want it fixed only when you scroll, but relative when you are at the top of the page, then use something like:
$('body').scroll(function(){
var $class_name = $('.class_name');
if($(this).scrollTop() >= $class_name.height()) {
$class_name.addClass('scrolled');
}
});
You can then use css to change the position based on the class on the element.
.class_name.scrolled {
position: fixed;
}
If you couple this will transition css, you will be able to animate it smoothly.

Bootstrap Slide in Navbar Clean Up jQuery remove active when user resizes to the min-width

I have this script below working well but I can't figure out how to do 1 thing:
A: When a user sizes to below the min-width threshold and clicks the toggle to view the menu and then just resizes back to > 767 -- though highly unlikely in real world situations -- the .slide-active class is still there and I can't figure out how to get rid of it. I can fake it with the css (which I've done) but it'd be nice to actually remove it when it's large, tried wrapping the script in an if .navbar-toggle is visible and it only worked on reload, so can't have that.
DEMO:
http://jsbin.com/ucARonA/1/edit
http://jsbin.com/ucARonA/1
$(document).ready(function () {
//stick in the fixed 100% height behind the navbar but don't wrap it
$('#slide-nav.navbar .container').
append($('<div id="navbar-height-col"></div>'));
// Enter your ids or classes
var toggler = '.navbar-toggle';
var pagewrapper = '#page-content';
var navigationwrapper = '.navbar-header';
var menuwidth = '100%'; // the menu inside the slide menu itself
var slidewidth = '80%';
var menuneg = '-100%';
var slideneg = '-80%';
$("#slide-nav").on("click", toggler, function (e) {
var selected = $(this).hasClass('slide-active');
$('#slidemenu').stop().animate({
left: selected ? menuneg : '0px'
});
$('#navbar-height-col').stop().animate({
left: selected ? slideneg : '0px'
});
$(pagewrapper).stop().animate({
left: selected ? '0px' : slidewidth
});
$(navigationwrapper).stop().animate({
left: selected ? '0px' : slidewidth
});
$(this).toggleClass('slide-active', !selected);
$('#slidemenu').toggleClass('slide-active');
$('#page-content, .navbar, body, .navbar-header').
toggleClass('slide-active');
});
});
If you need to toggle something on a browser size change and if it meets a min-width, combind a resize event with a if statement.
$(window).on("resize",function(){
if ($(window).width() > 760) {
$(selected).removeClass('slide-active');
}
});

dealing with sliding in jquery?

i have this script that with li list, if you click on one of the list items, a box slides to the right, and if you click again, its slides back to its orginal place(toggle)
the demo is here:
http://www.kornar.co.uk/home2.php
the problem that i have is on slideout, i want the width of the panel to be 700px
$(".panel").css("width","700px");
on slide back in, i want the width to be 350px, so it hides behind the list again.
$(".panel").css("width","350px");
but the problem im having is on when it slides back, it deosnt hide behind the list, it still shows the panel on the right? thanks
Hey dude, I made a couple of assumptions about what you were trying achieve on the whole, but maybe this is what you were trying to do... The following is all I changed:
<script type="text/javascript">
$(document).ready(function() {
$('.block').click(function(){
var id= $(this).attr('id');
var data_id= $(".data").html();
var panelPositionLeft=$('.panel').css('left');
if(panelPositionLeft=='0px') {
//the .panel is hidden, so slide it out and populate .data with the new id
$('.panel').animate({left: 350, width:700});
$('.data').html(id);
} else if (data_id!=id){
//something other than the previous .block was clicked and the .panel is obviously open, so don't collapse, just add the new id into .data
$('.data').html(id);
} else {
//neither of the previous situations are true, so it must be that the previously clicked block is being clicked again. Just slide it closed and don't change the value of .data
$('.panel').animate({left: 0, width: 350});
}
});
$('.close').click(function(){
// just slide it closed.
$('.panel').animate({left: 0, width: 350});
});
});
</script>
There are still a few things you could clean up, but I thought this would be a little easier to read and understand. Try this out, let me know if I misunderstood the problem.
Thanks!
Try surrounding the "+" with quotes (i.e. "+" + panel.outerWidth()). I think this should work.
Richard
For getaways reference: this is what I would have posted had masondesu not got there first. As you can see it is very similar, but has if statements where none are actually required (as in masondesu's solution.
$(document).ready(function () {
$('.block').click(function () {
var id = $(this).attr('id');
var data_id = $(".data").html();
var panel = $('.panel');
var panel_width = $('.panel').css('left');
var currLeft = panel.css('left');
var blockWidth = $(".left").outerWidth();
if (data_id == id) {
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
}
else {
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
}
$('.data').html(id);
return false;
});
$('.close').click(function () {
var panel = $('.panel');
var currLeft = panel.css('left');
if (currLeft == "0px") {
panel.animate({ left: blockWidth, width: "700px" });
} else {
panel.animate({ left: "0px", width: "350px" });
}
return false;
});
});
Regards,
Richard
You don't resize the panel on "li"-click, it resizes only on ".close"-click. so it won't resize ;)

lock a div on header when window scrolled past element

I want a circle div to lock in the header when the user scrolls past in.
I'm using the following code but it doesn't work
var circle$ = $('.circle'),
oCircleBottom = circle$.offset().top + circle$.outerHeight(true),
window$ = $(window);
window$.scroll(function() {
if (window$.scrollTop() > oCircleBottom) {
}
}.bind(this));
I want to perform an action when the user scrolls pass the circle div; however, the code above does not seem to work. Is oCircleBottom computed correctly?
Enclose your code in $(document).ready function
$(document).ready(function () {
var circle$ = $('.circle'),
oCircleBottom = circle$.offset().top + circle$.outerHeight(true),
window$ = $(window);
window$.scroll(function () {
if (window$.scrollTop() > oCircleBottom) {
$('.circle').css({
position: 'fixed',
top: '0',
left: '0'
});
}
else{
$('.circle').css({
position: 'static'});
}
}.bind(this));
});
You need to take window height into account because if the height of the page isnt enough to scroll down, your code doesnt work. Take a look at this example
However, if the increase page height, you code will work fine without subtracting window height. Take a look at this example
Hence, its better to subtract the window height. jsFiddle
$(window).bind('scroll', function() {
if($(window).scrollTop() >= $('.circle').offset().top + $('.circle').innerHeight() - window.innerHeight) {
//Do you stuff
}
});

Categories

Resources