multiple pages in one html file without fixed nav on each page - javascript

Main page would only have several buttons that will show the user designated content.
Those buttons in #home is not in header, so buttons will be only shown on #home only.
<section id="home">
content
something
someelse
</section>
<section id="content">
<section id="something">
<section id="someelse">
I found :target method on css which seems very easy to use and works ok, but #home is not displaying.
It seems like it would only work when I have a fixed header outside section
section {
display: none;
}
section:target {
display: block;
}
Each section other than #home will have back button which will send user to #home as well. This was fairly easy on :target method because I just used a href="#", and it worked.
What other method would I be able to use ?

I can't think of any pure CSS ways to do this, but it can easily be done with a little JavaScript to check if the hash is empty, and then show #home and hide it when there is a value.
window.onhashchange = checkHash;
checkHash();
function checkHash() {
var home = document.getElementById('home');
//Check if the hash is empty
if (window.location.hash.substring(1) == '') {
home.style.display = 'block';
} else {
home.style.display = 'none';
}
}
.section {
display: none;
}
.section:target {
display: block !important;
}
<div id="home" class="section">
Content
Somthing Else
<h3>Home</h3>
</div>
<div id="content" class="section">
Home
<h3>Content</h3>
</div>
<div id="somthingElse" class="section">
Home
<h3>Somthing Else</h3>
</div>
Fade
I used position: absolute so they will stack on top of each other. z-index: -1 will keep all the rest of the sections to the clear back to stop pointer events from overlapping. opacity: 0 was obviously used for the fade.
I changed the JS script to simplify my CSS. Now when you go to example.com/html.html you get redirected to example.com/html.html#home (without a history change for the back button).
window.onhashchange = checkHash;
checkHash();
function checkHash() {
//Check if the hash is empty
if (window.location.hash.substring(1) == '') {
history.replaceState(undefined, undefined, "#home")
}
}
.section {
position: absolute;
z-index: -1;
opacity: 0;
transition: opacity 0.5s;
}
.section:target {
z-index: 1;
opacity: 1;
}
<div id="home" class="section">
Content
Somthing Else
<h3>Home</h3>
</div>
<div id="content" class="section">
Home
<h3>Content</h3>
</div>
<div id="somthingElse" class="section">
Home
<h3>Somthing Else</h3>
</div>

Related

How to use css bootstrap list-group with affix to create a sticky menu in a column?

I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.
I manage to get most of it to work except for when the user scrolls down.
When the user scrolls down, the menu seems to take the entire with of the page.
I tried to set it up via data attributes
using something like this
<div class="container">
<div class="row">
<div class="col-md-3" id="leftCol">
<div data-spy="affix">
<div class="list-group list-group-root well">
<a class="list-group-item" href="#introduction">Introduction</a>
<a class="list-group-item" href="#features">Features</a>
<a class="list-group-item" href="#dependencies">Dependencies</a>
</div>
</div>
</div>
<div class="col-md-9" id="mainCol">
Some long text for the body along with some tables.
</div>
</div>
</div>
But the data attribute did not make the menu stick! it just kept it on the top.
So I tried to use JS to get the job done like this
$(function(){
$('#leftCol').affix({
offset: {
top: 100,
bottom: function () {
return (this.bottom = $('.footer').outerHeight(true))
}
}
});
});
I created jsFiddle to show you the current behavior.
How can I fix this affix so when the user scrolls down the menu maintain the same shape?
First of all, you should use either data-attributes or JS.
I updated your jsFiddle. The position of id="leftCol" was changed:
<div class="col-md-3" >
<div id="leftCol">
...
</div>
</div>
and style was added:
#leftCol {
width: 220px;
}
Also, you should add media queries to remove affix from mobile view.
As an "unacceptable" workaround, I set a max width of the menu to 250px like so
.list-group.list-group-root {
padding: 0;
max-width: 250px;
}
I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"
UPDATED
javascript to the rescue!
I added the following JS code to solve this problem once an for all.
It basically resize the menu everytime affix.bs.affix event is fired
$(document).on('affix.bs.affix', '#docs-menu', function() {
$(this).width($(this).width());
});
From the docs
affix.bs.affix => This event fires immediately before the element has
been affixed.
Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:
#leftCol {
display: block;
height: auto;
padding: 0;
width: 100%;
}
.navbar-fixed-top-again {
position: static;
top: 60px;
z-index:1031;
}
.navbar-inner {
background: red;
padding: 5px;
}
.affix {
position: fixed !important;
}
and I changed up some of the structure on your HTML:
<div class="container body-content">
<div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>
<!-- new nav section -->
<div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
<div class="navbar-inner">
<div class="list-group list-group-root well">
*the rest of your code*
</div>
</div>
</div>
</div>
The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).
Heres the link to your updated Fiddle. Hope that helps.

How to Stick elements on page scroll

I have a one page, scrolling site with 5 main sections that have title bars that span across the top of each respective section. I want each title bar to stick at the top (well, relative top-underneath the top sticky header) as you scroll down the section. I can get one to stick, but I am having trouble making it so that one sticks and then it goes away once the next section's title bar gets to the sticky point.
I can't figure out another way to bind the HTML or CSS with the jQuery if else statement to make this work. I was thinking I could try to make it work within each sections' id but I don't think there's like a "withinId" jQuery selector.
I'm posting the latest jQuery I attempted (with just 2 out of the 5 variables I will need to make work here). I know it's wrong but I'm seriously stuck. Any ideas here? Thanks a million.
(abbreviated) HTML:
<div id="welcome">
<div class="title-bar">
<p>WELCOME</p>
</div>
</div>
<div id="global">
<div class="title-bar">
<p>GLOBAL ENGAGEMENT</p>
</div>
</div>
<div id="community">
<div class="title-bar">
<p>COMMUNITY</p>
</div>
</div>
<div id="resources">
<div class="title-bar">
<p>RESOURCES</p>
</div>
</div>
<div id="horizon">
<div class="title-bar">
<p>ON THE HORIZON</p>
</div>
</div>
CSS:
.title-bar {
padding: 5px;
position: relative;
}
.title-bar.sticky {
position: fixed;
top: 111px;
width: 100%;
z-index: 1040;
}
jQuery:
$(document).ready(function() {
var welcomeTitle = $('#welcome .title-bar');
var globalTitle = $('#global .title-bar');
var communityTitle = $('#community .title-bar');
var resourcesTitle = $('#resources .title-bar');
var horizonTitle = $('#horizon .title-bar');
var stickyOffset = $('#header').offset().top;
if ($w.scrollTop() > stickyOffset + 225) {
welcomeTitle.addClass('sticky');
globalTitle.addClass('sticky');
} else {
welcomeTitle.removeClass('sticky');
globalTitle.addClass('sticky');
}
if (welcomeTitle.hasClass('sticky') && globalTitle.hasClass('sticky')) {
welcomeTitle.removeClass('sticky');
} else {
//
}
});
jsBin demo
Give your "pages" a class="page" and listen for their positions using JS's Element.getBoundingClientRect on: DOM Ready, window Load, window Scroll
$(function() { // DOM ready
var $win = $(window),
$page = $(".page").each(function(){
// Memorize their titles elements (performance boost)
this._bar = $(this).find(".title-bar");
});
function fixpos() {
$page.each(function(){
var br = this.getBoundingClientRect();
$(this._bar).toggleClass("sticky", br.top<0 && br.bottom>0);
});
}
fixpos(); // on DOM ready
$win.on("load scroll", fixpos); // and load + scroll
});
*{box-sizing: border-box;}
html, body{height:100%;}
body{margin:0;font:16px/1 sans-serif; color:#777;}
.page{
position:relative;
min-height:100vh;
}
.title-bar {
position: absolute;
top:0;
width: 100%;
background:#fff;
box-shadow: 0 3px 4px rgba(0,0,0,0.3);
}
.title-bar.sticky {
position: fixed;
}
#welcome {background:#5fc;}
#global {background:#f5c;}
#community{background:#cf5;}
#resources{background:#fc5;}
#horizon {background:#5cf;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="welcome" class="page">
<div class="title-bar">
<h2>WELCOME</h2>
</div>
</div>
<div id="global" class="page">
<div class="title-bar">
<h2>GLOBAL ENGAGEMENT</h2>
</div>
</div>
<div id="community" class="page">
<div class="title-bar">
<h2>COMMUNITY</h2>
</div>
</div>
<div id="resources" class="page">
<div class="title-bar">
<h2>RESOURCES</h2>
</div>
</div>
<div id="horizon" class="page">
<div class="title-bar">
<h2>ON THE HORIZON</h2>
</div>
</div>
Design-wise > add a padding-top to the first container element (inside your .page) to prevent content going underneath the title element (since it toggles from absolute/fixed positions).
Have a look at the Waypoints plugin.
You can probably make it a little easier on yourself by assigning each section a class and then add and remove the class from each section with jquery each function.
Try something like the following:
$(window).on( "scroll", function() {
$( ".section" ).each(function() {
if ( $(window).scrollTop() >= $(this).offset().top - 50 ) {
$( this ).addClass("sticky");
}else{
$( this ).removeClass("sticky");
}
});
});
Then your css
.section{
height: 200px;
background: #333;
border:1px solid #222;
position:relative;
}
.section .title-bar{
position:absolute;
top:0;
left:0;
width:100%;
height:50px;
}
.section.sticky .title-bar {
position:fixed;
}
And html
<div class="section">
<div class="title-bar"></div>
</div>
<div class="section">
<div class="title-bar"></div>
</div>
<div class="section">
<div class="title-bar"></div>
</div>

Reset position after .animate() method

I'm trying to combine the .toggle() method with an animation. I've followed the methods laid out in this fiddle as well as in this SO post, but the second click isn't returning my div to the original position.
The behavior should be:
Click the title
Content expands
Slide up over the headline
Click again
Content contracts
Slide back down to the original position <-- This isn't happening
HTML
<div id="headline">
<h1>This is the headline</h1>
</div>
<div id="page-wrap"> <!-- contains more than one article, need the whole thing to slide -->
<article class="post">
<div class="title"><h1>Feedback</h1></div>
<div class="content">
<p>Videos can be more than direct instruction. Currently, how do you give feedback on assignments?</p>
<p>It takes a lot of time, right?</p>
<p>Video can be used to give direct feedback to the student because it communicates areas of improvement more effectively than written feedback alone.</p>
</div>
</article>
</div>
CSS
#headline {
position:fixed;
top:10px;
left:10px;
width:380px;
}
#page-wrap {
position:relative;
top:200px;
}
.post {
width:300px;
}
.post .title {
cursor: pointer;
}
.post .content {
display:none;
}
Script
$(".title").click(function() {
$title = $(this);
$content = $title.next();
$content.toggle(
function() {
$("#page-wrap").animate({"margin-top":"200px"}, 'fast')
},
function () {
$("#page-wrap").animate({"margin-top":"-200px"}, 'fast')
}
)
});
CodePen Demo
Here's a live page for more context.

How to scroll back to the top of page on button click?

I am creating my product pages by using the object tag code, but every time I click the "view" button, the next page is staying at the same position of previous page which I just viewed. How can I add functionality that will let me view from the top of page every time I click the "view" button?
<div id="container" class="clearfix"><!--! end of #sidebar -->
<div class="holder"></div>
<div id="content" class="defaults"><!-- navigation holder -->
<div id="title2">Office Section</div>
<!-- item container -->
<ul id="itemContainer">
<li>
<div id="product">
<div id="title">FuBangĀ®</div>
<div class="imageOuter" style="margin:0">
<a class="image" href="officesection010.html">
<span class="rollover" ></span>
<img class="imgborder" src="product/officesection/010.jpg" width="165" height="165" />
</a>
</div><br />
<div id="text">Sofa </div><br />
<div id="button">
View Details
</div>
</div>
</li>
</ul>
<br />
<div id="title2"></div>
<div class="holder"></div>
</div>
</div> <!--! end of #content -->
</div> <!--! end of #container -->
When I click the "View Details" button at a specific position "x" here: http://postimg.org/image/vgs0lwhtr/
The next page shows the same position "x", but I want it to jump to the top of page:
http://postimg.org/image/vn80e2lph/
Using Javascript:
document.body.scrollTop = document.documentElement.scrollTop = 0;
Using jQuery:
$(function() {
$('body').scrollTop(0);
});
jQuery(document).ready(function($){
$(window).scroll(function(){
if ($(this).scrollTop() > 50) {
$('#backToTop').fadeIn('slow');
} else {
$('#backToTop').fadeOut('slow');
}
});
$('#backToTop').click(function(){
$("html, body").animate({ scrollTop: 0 }, 500);
//$("html, body").scrollTop(0); //For without animation
return false;
});
});
please refere this, may this help
Sometimes placing scroll to body doesn't work if your current content is generated through jQuery (as it was in my case). In such situation you can just do following.
$(function() {
$('html').scrollTop(0);
});
A small issue with Subhash's jQuery solution is that you must call this code within $(document).ready() in order for your $('body') selector to work. The ready event may not fire before parts of your page have been rendered to the screen.
An better approach is to simply modify the user's location as a work-around to this browser 'feature':
//Above all of your $(document).ready(...) code
document.location = "#";
Simple HTML solution for jumping between page parts
// Place a tag like this where you would like to go
// in your case at the top
<a name="top"></a>
// you will reach there by click of this link better use an image reach their by clicking on this we can also use an image, align in right
last
Back to top button, works in all browsers.To change the scroll speed simply change the x in counter -= x here x = 10
function scrollToTop(){
var myBody = document.body;
var id = setInterval(secondFunction,1);
var height = window.pageYOffset;
var counter = height;
function secondFunction(){
if(window.pageYOffset == 0){
clearInterval(id);
}
else {
if(!!navigator.userAgent.match(/Trident/g) || !!navigator.userAgent.match(/MSIE/g)){
counter -= 10;
counter--;
document.documentElement.scrollTop = counter;
}
else {
counter -= 10;
counter--;
myBody.scrollTop = counter;
}
}
}
}
body {
height: 5000px;
margin: 0;
padding: 0;
}
.backToTop {
position: fixed;
/* Fixed at page */
top: auto;
bottom: 20px;
left: auto;
right: 20px;
background-color: crimson;
color: white;
padding: 5px;
cursor: pointer;
}
header {
position: relative;
top: 0;
left: 0;
width: 100%;
height: 100px;
background-color: black;
}
<!-- back to top button -->
<span class="backToTop" onclick="scrollToTop()">TOP</span>
<!-- Header -->
<header>
</header>
Assign an id="#body" and tabindex in the <body> tag
<body id="#body" tabindex="1">
and use jquery focus()
$(function() {
$("#body").attr("tabindex",-1).focus();
}
You can use this method:
function gototop() {
if (window.scrollY>0) {
window.scrollTo(0,window.scrollY-20)
setTimeout("gototop()",10)
}
}

content of fixed div changes as other divs scroll past it

I'm trying to fix a div at the top of a layout that will contain a blog post's information (date posted, # of notes, permalink, etc.) and change this information as you scroll down past posts. I'm not sure if it would require any kind of javascript or just some intricate positioning using css. Here's how I would layout the posts. How can I get the specific post information from each post to change within that fixed div as the posts scroll past it?
#container {
width: 960px;
margin: 0px auto;
}
#changingpostinformation {
position: fixed;
margin: 0px auto;
}
<div id="container">
<div id="changingpostinformation">fixed post information div that's information changes as each post below reaches the top of #container</div>
<div class="post">
<h3>Post Title>
<p>This is the body of this example post.</p>
</div>
<div class="post">
<h3>Post Title>
<p>This is the body of this example post.</p>
</div>
</div>
Like #ShankarSangoli says, you should add top: 0;, and also left: 0; to #changingpostinformation (or other values to position it however you like)
You'll need some javascript to find out which post appears first on the page and show its info.
$(function() {
$(window).bind('load resize scroll', function() {
var doctop = $('body').scrollTop();
// loop over all posts, from top to bottom
$('.post').each(function() {
if ($(this).position().top > doctop) {
put_postinfo_in_fixed_div($(this));
return false; // breaks from the loop
}
});
});
});
This function runs once when page is loaded, and also when the window is resized or scrolled.
You need to implement put_postinfo_in_fixed_div() which gets an post div, and does what it says.
Use this CSS:
#changingpostinformation {
position: fixed;
top: 0px;
}

Categories

Resources