I have this code to make my sidebar sticked when scrolling down. However, this let the sidebar scroll to the bottom of the page, which overlaps other elements on the site.
$(function () {
var counter = 0;
var s = $("#counter");
var pos = s.position();
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
if (windowpos >= pos.top) {
s.addClass("stick");
} else {
s.removeClass("stick");
}
});
});
<div id="sidebar">
<div id="counter">
* php dynamic_sidebar( 'Sidebar' ); *
<div class="clear"></div>
</div>
</div>
I have searched for an hour now without finding any solution. I want the sidebar to stop being sticked when the scroll reach the div footer.
You will have to use css to tackle this issue.
Just add padding from bottom equal to the height of the element at the bottom.
Suppose if you have a footer with height 50px.Then add padding-bottom:50px to the sidebar and give footer some z-index also like z-index:9 or z-index:99.
Let me know if this helps.
Thanks
Related
I have the following div container:
<div class="col-md-8 grid-wrapper-div chatHistory">
...
</div>
With the CSS:
.chat .chatHistory {
overflow-y:scroll;
height: 550px;
}
and if the page is loaded than the scroll bar should be at bottom -> I use AngularJS.
Is there any possibility to scroll down with css or with AngularJS
[EDIT]
I have tried it like this but chatHistoryContainer.scrollHeight is undefined. Does anyone know why?
Use ngInit, which runs upon rendering content and $timeout to postpone scrolling to the next digest cycle in order to wait for the content rendered completely.
<div id="chat_history" class="col-md-8 grid-wrapper-div chatHistory" ng-init="scrollToBottom()">
...
</div>
myApp
.controller(function($scope, $timeout){
$scope.scrollToBottom = function() {
$timeout(function(){
var objDiv = document.getElementById("chat_history");
objDiv.scrollTop = objDiv.scrollHeight;
});
};
});
From what I can tell, although jQuery-Mobile-powered pages can contain divs with overflow set to scroll or auto, and these divs can be scrolled with the one-screen bar or the mouse wheel, they cannot be scrolled using the arrow keys, page-up/page-down, or home/end.
Instead, the official "page" div (with data-role="page") absorbs all this input. Perhaps other divs can't even acquire focus, I'm not sure.
Is there any way around this?
EDIT: JSfiddle of simple example: https://jsfiddle.net/qogz0shx/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js">
</script>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css"/>
<style>
#outer {
overflow:scroll;
height: 50vh;
width: 50vw;
}
#inner {
height: 500vh;
width: 500vw;
}
</style>
<div data-role="page">
<div id="outer">
<div id="inner"></div>
</div>
</div>
Same example without the external files: https://jsfiddle.net/xr0hjjjc/
<style>
#outer {
overflow:scroll;
height: 50vh;
width: 50vw;
}
#inner {
height: 500vh;
width: 500vw;
}
</style>
<div data-role="page">
<div id="outer">
<div id="inner"></div>
</div>
</div>
In Chrome, if you click on the div in the second example and press the arrow keys, you should see the scroll bars move. If you do the same with the first one, they won't.
You're right, internal <div>s cannot be scrolled using keyboard. My approach to this limitation is simple:
create new handler for up/down/PageUp/PageDown keys
when those keys are pressed, get element under mouse
if the element contains the keyboardScroll class, scroll it accordingly
So, mouse position sets which element has to be scrolled.
Updated JSFiddle (click to focus the "run" quadrant before scrolling)
JavaScript
var currentMousePos = { x: -1, y: -1 };
$(document).on("pageinit", "#page", function(event)
{
$(document).mousemove(function(event)
{
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
// keyboard handler
$(document).on("keydown", function(e)
{
// get element under mouse
var element = document.elementFromPoint(currentMousePos.x, currentMousePos.y);
// search for scrollable element in parents
while (!$(element).hasClass("keyboardScroll") && $(element).parents().length !== 0)
element = element.parentElement;
if (!$(element).hasClass("keyboardScroll"))
return; // no scrollable element found
// set scroll "speed"
var delta = 10;
if (e.keyCode === 38) // up
delta *= -1;
else if (e.keyCode === 40) // down
delta *= 1;
else if (e.keyCode === 33) // pageup
delta *= -10;
else if (e.keyCode === 34) // pagedown
delta *= 10;
else
return;
// scroll element
$(element).scrollTop($(element).scrollTop() + delta);
// stop event from propagating to jQuery Mobile handlers
e.preventDefault();
e.stopPropagation();
});
});
On revisiting this with new searches ("focus" is a better keyword here than "scroll"), I discovered a much simpler solution.
Just give the div in question a tabindex attribute, to make it focus-able. Make the value -1 so it won't interfere with the tabindex of anything else. (This means that if the user keeps pressing tab, the div in question will never be focused. Change the index to a positive number if you want it to be focus-able that way).
<div id="outer" tabindex="-1"> </div>
<!-- Containing element with overflow:scroll or whatever -->
and that's it. Once the div is clicked it should override whatever jQuery Mobile does to prohibit focus. New JSFiddle here.
Right now when i summon a popup it appears over the header and then slides down beneath it. Check out what it looks like now.
I would like the popup to slide down from underneath the header. I've tried setting the z index of the popup lower than the header but it didnt do anything. Apparently you need to explicitly set the positioning of elements to use z index but when I did that it totally messed up the UI.
Here's the relevant code
HTML:
<div data-role="popup" id="alertPopup" class="ui-content" data-shadow="false" data-transition="slidedown" data-dismissible="false" data-corners="false" data-position-to="origin">
<p id="popupText"></p>
</div>
JS:
var horizontal = Math.floor(window.innerWidth/2);
var vertical = 80;
var popupOptions = {
x: horizontal,
y: vertical
};
if (status == google.maps.DirectionsStatus.ZERO_RESULTS) {
$("#popupText").text("No transit options could be found.");//using popups instead of alerts because these will go away by themselves instead of forcing user to tap.
$("#alertPopup").popup("open",popupOptions);
setTimeout(function() {
$("#alertPopup").popup("close");
}, 3000);
}
http://jsfiddle.net/guanzo/gvsqenvf/
I think that using a jQM popup widget will not work for this because jQM creates a transparent overlay that covers the page, then a popup container above the overlay and then it places the popup within the container. So there is no way to have the popup be under the header.
Instead, you could use an absolutely positioned DIV for your popup and use the jQuery slideToggle() method to display it.
Add the notification div to the content:
<div data-role="content" id="content">
<div id="notify" class="ui-body-inherit ui-content">
<p id="notifyText">hello</p>
</div>
I am Content
</div>
Setup the CSS to absolutely position the div and hide it until needed:
#notify {
border-width: 1px;
border-style: solid;
display: none;
position: absolute;
}
#notify p {
margin: 0;
}
In the script, set the text, calculate position and show it with slide toggle (I added a timeout on the show just so the fiddle can finish drawing the page before the notification is shown).
$("#notifyText").text("No transit options could be found.");
var $notify = $("#notify");
var vertical = $(".ui-header").outerHeight() -1; //height of header
var w = $notify.width();
var left = (Math.floor((window.innerWidth - w) / 2));
$notify.css({ left: w + "px", top: vertical + "px"});
setTimeout(function() {
$notify.slideToggle(500); //delay showing for the fiddle
}, 500);
setTimeout(function() {
$notify.slideToggle(500);
}, 5000);
Your updated FIDDLE
I´m using bootstrap3 and I´m trying to create a fixed menu for mobile devices. This menu can have submenu´s and submenu´s can have a lot of content in it. So when you watch the site on mobile phone´s (320x480 eg) and the menu is very long then you can´t scroll in the inner/submenu. In other words if your screen height is too short you can´t see all the menu items because the menu bar is sticked at the top of the screen.
I´ve read a lot of post from github and here + Bootstrap's page, but can´t seem to get it to work. I think that position fixed is the problem?!
I'll try to explain with a fiddle and here below
EDIT: You can view an example here -> example (resize browser and try to hit brands)
HTML
<div id="main-nav-container">
<div class="container">
<div class="row">
<div class="col-md-12 clearfix">
<nav id="main-nav">
<div id="responsive-nav">
<div id="responsive-nav-button">
Menu <span id="responsive-nav-button-icon"></span>
</div><!-- responsive-nav-button -->
<ul class="clearfix responsive-nav">
<li><i class="fa fa-home"></i></li>
<li><span class="menu-button"></span><a title="Camera" href="http://www.webshop.com/nl/camera/">Camera</a>
<ul>
<li><a title="Canon" href="http://www.webshop.com/nl/camera/canon/">Canon</a></li>
<li> like 40 li items more for example </li>
</ul>
</li>
etc...
JQUERY
$(function() {
var sticky_navigation_offset_top = $('#main-nav-container').offset().top;
// our function that decides weather the navigation bar should have "fixed" css position or not.
var sticky_navigation = function(){
var scroll_top = $(window).scrollTop(); // our current vertical position from the top
// if we've scrolled more than the navigation, change its position to fixed to stick to top, otherwise change it back to relative
if (scroll_top > sticky_navigation_offset_top) {
$('#main-nav-container').css({ 'position': 'fixed', 'top':0, 'left':0 });
} else {
$('#main-nav-container').css({ 'position': 'relative' });
}
};
sticky_navigation();
// and run it again every time you scroll
$(window).scroll(function() {
sticky_navigation();
});
});
So how can I make the menu so that the with the li items is scrollable so that on smaller screens the whole submenu can be viewed?
I have inherited a project, and have some questions on how to resolve a particular issue.
There is a fixed left sub-nav, seen below. As the user scrolls, there are 6-10 different "sections" that are stacked vertically. The top section has a background-image (seen below), while the remaining sections alternate between white & various colors, such as:
section 1: background-image
section 2: background-color: white
section 3: background-color: blue
section 4: background-color: white
section 5: background-color: green
... etc
The customer wants the menu items to change colors based on what background each item is over at a given time (so as you scroll, it's changing item by item). As you can see in the image, when I scroll from the header to the first content section, I'm moving to a white background, so my menu is white text on a white background (the 5th menu item is moving into the white background).
The guys that worked on this initially used jquery waypoint to trigger wholesale changes to the menu item color when a particular div scrolled to a certain location. This basically works - but only when the entire section is scrolled to the top of the menu (meaning the menu items are white-on-white until the last menu item is scrolled into the section).
Any thoughts on how to handle this?
[EDIT TO ADD]
I thought I made this pretty clear above. We're already using jquery waypoints. The problem is, waypoint cannot trigger on each menu item (primarily since the menu items are not part of the ancestral tree of the content nodes, which prohibits me from passing in a context to the waypoint handler), unless I create a handler for the section div at each offset of every menu item (which are different for each page). This would result in a crazy amount of waypoint handlers being bound, which I don't think is ideal.
Here is an example of what I'm describing. As you scroll, the menu items change all at once. You can see where this is a problem when you're scrolling down from the header into the first content section. The menu items are white. So is the background of the first content section. So until the waypoint is hit, the menu is effectively hidden. What I am looking to do is change the color of each menu item as it "enters" or "exits" a particular content div. I suppose I could do this on window.scroll, but that seems pretty expensive. Was hoping there's something I'm either missing with waypoints, or a better way to do this.
Alright, so I did solve this by creating an event handler at every offset. Given that I have 6-10 menu items per page (so 6-10 sections), I don't really like a solution where I create 36-100 event handlers, so I'm hopeful somebody has a better one (although I'm starting to doubt it).
SO is telling me I need to post code, so here goes:
HTML
<div class="menu">
<ul>
<li>
<a href='#header'>Header</a>
</li>
<li>
<a href='#getting-started'>Getting Started</a>
</li>
<li>
<a href='#zomglaserguns'>Laser Guns</a>
</li>
<li>
<a href='#pewpew'>Pew Pew</a>
</li>
</ul>
</div>
<div id="header" data-menu-color-down='#fff' data-menu-color-up='#000'>
Some header content
</div>
<div class="content">
<div id="getting-started" data-menu-color-down='#000' data-menu-color-up='#fff'>
some content
</div>
<div id="zomglaserguns" data-menu-color-down='#fff' data-menu-color-up='#000'>
laser guns!
</div>
<div id="pewpew" data-menu-color-down='#000' data-menu-color-up='#fff'>
pew pew!!!!
</div>
</div>
JS:
var myObj = {
menuOffsets: {},
pageSections: [],
init: function() {
myObj.initMenuOffsets();
myObj.initSections();
myObj.initWaypoints();
},
initMenuOffsets: function() {
$('.menu a').each(function() {
var self = $(this),
href = self.attr('href'),
menuItemHeight = self.height();
myObj.menuOffsets[href.substring(1, href.length)] = self.offset().top + self.height();
});
console.log(myObj.menuOffsets);
},
initSections: function() {
var header = $('#header'),
sections = $('.content > div');
if(header.length) {
myObj.pageSections.push('header');
}
sections.each(function() {
var self = $(this);
myObj.pageSections.push(self.attr('id'));
});
console.log(myObj.pageSections);
},
initWaypoints: function() {
var menuItemColor,
key,
i = 0,
len = myObj.pageSections.length;
for ( i; i < len; i++ ) {
for ( key in myObj.menuOffsets ) {
if( myObj.menuOffsets.hasOwnProperty( key ) ) {
(function ( key, i ) {
$('#' + myObj.pageSections[i]).waypoint(function(direction) {
var self = $(this);
menuItemColor = self.data('menuColor' + (direction === 'up' ? 'Up' : 'Down'));
$('.menu a[href="#' + key + '"]').css('color', menuItemColor);
}, { offset: myObj.menuOffsets[key] });
})(key, i);
}
}
}
}
};
myObj.init();
SEE-ESS-ESS:
.menu {
position: fixed;
top: 40px;
left: 10px;
color: white;
}
.menu li {
list-style-type: none;
}
.menu a {
color: inherit;
text-decoration: none;
}
.content {
}
#header {
background: black;
color: white;
height: 200px;
padding: 0 120px;
}
#zomglaserguns {
background: green;
color: #777;
}
.content div {
min-height: 300px;
padding: 0 120px;
}
Well, it's not too difficult to set up some ID's on the page, and use those as anchors for when to trigger the background change.
Say you had an HTML structure like this:
<header>
...
</header>
<div id="getting-started" data-background-color="lightBlue">
...
</div>
<div id="afford" data-background-color="red">
...
</div>
<div id="down-payment" data-background-color="green">
...
</div>
<div id="financing" data-background-color="blue">
...
</div>
And now you include jQuery Waypoints
<script type="text/javascript">
(function($) {
$('#getting-started').waypoint(function() {
var $this = $(this);
$('header').css('background-color', $this.data('background-color'));
});
})(jQuery)
</script>
Keep in mind this isn't a complete solution, just something to help poke you in the right direction.