I'm having an issue when i'm loading the pages on my website. The main page has anchors since it's a one page, however i wanted to add a blog so i made it a two pages website. The url looks like mywebsite.com#content But now when I'm on the blog and I'm trying to get back to the main page, but the url loads like that : mywebsite.com/blog#content.
So i'd like the url to look like that : mywebsite.com/#content, but i don't know if that's possible...
Here is the html for the links :
<li>Accueil</li>
<li>Projets</li>
<li>A propos</li>
<li>Contact</li>
<li>Blog</li>
To make a smooth scroll effect on the main I used the following jquery :
var scroll = {
scrollTo : function () {
var page = $(this).attr('href'); // Target page
var speed = 750; // Animation duration
$('html, body').animate( { scrollTop: $(page).offset().top }, speed ); // Go
return false;
} // attribute scrollTo
}; // object scroll
$('.js-scrollTo').on('click', scroll.scrollTo);
Is there a way to make the url this way : mywebsite.com/#content and still have the scrolling effect with jquery ?
Simple use e.preventDefault instead of return false. Also, add a control to check if your "anchor page" exists in the dom.
Example with external page: https://www.vixed.it/st/43002103
Anyway I think is better to change the name of your function, can create a misunderstand with jQuery scroll and scrollTo.
Don't forget that li tags should contains the a and and not the opposite.
var scroll = {
scrollTo : function (e) {
var page = $(this).attr('href');
if ($('div.page'+page).length) {
e.preventDefault();
var page = $(this).attr('href');
var speed = 750;
$('html, body').animate({scrollTop: $(page).offset().top}, speed);
} else {
location.href='/'+page; //your home url + #page
}
}
};
$('.js-scrollTo').on('click', scroll.scrollTo);
a{color:#09C}
.nav{
list-style:none;
position:fixed;
top:0;
right:0;
width:100%;
background:#000;
margin:0;
padding:5px 0;
}
.nav li{
display:inline;
margin:0 5px;
}
.page{
min-height:200px;
padding:35px;
border:1px solid #CCC;
}
<ul class="nav">
<li>Accueil</li>
<li>Projets</li>
<li>A propos</li>
<li>Contact</li>
<li>Blog</li>
</ul>
<div id="homepage" class="page">Accueil</div>
<div id="projects" class="page">Projets</div>
<div id="about" class="page">A propos</div>
<div id="contact" class="page">Contact</div>
<div style="height:1000px;">Footer</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Related
I was implementing that if i refresh the page, it should make active to previously selected tab(preserve selected tab) . So I Create a simple html page and add some jQuery.
But if i change URL manually like file:///home/2.html#news to file:///home/2.html#home
it changes only content of page but doesn't change tab ,that was selected. .
Here is my code.
<body>
<ul>
<li id="first">Home</li>
<li id="second">News</li>
<li id="third">Contact</li>
<li id="forth">About</li>
</ul>
<p id="home">
home section
</p>
<p id="news">
news section
</p>
<p id="contact">
contact section
</p>
<p id="about">
about section
</p>
</body>
<style>
p{
display: none;
}
:target {
display:block;
border: 2px solid #D4D4D4;
background-color: #e5eecc;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
if(localStorage.getItem("active_state") == null ){
activeStateId = "first";
}
else{
activeStateId = localStorage.getItem("active_state")
}
$('#'+activeStateId).addClass('active');
$('li').click(function(){
$('.active').removeClass('active');
$(this).addClass('active');
localStorage.setItem("active_state", $(this).attr('id'));
});
});
</script>
When you got link hashes, you dont actually reload the page, but the browser just triggers those links. You rely on CSS :target change rule which evaluates every time the #hash changes on the url.
p {
display: none;
}
:target {
display:block;
border: 2px solid #D4D4D4;
background-color: #e5eecc;
}
Thus, you have all the sections updated properly even without refreshing the page. In order to have such functionality, you don't need to store any data to the local or remote machine since you are using hashes on the url. Just use the hashes and handle the hashchange event to add the .activate class to the links like this:
$(document).ready(function() {
var hash = window.location.hash;
if(hash.length > 0) {
hash = hash.substring(1);
$('li a[href$='+hash+']').parent().addClass('active');
}
$(window).on('hashchange', function() {
$('.active').removeClass('active');
var hash = window.location.hash
if(hash.length > 0) {
hash = hash.substring(1);
$('li a[href$='+hash+']').parent().addClass('active');
}
});
});
Check my working example here: http://zikro.gr/dbg/html/urlhash.html#about
Is it possible to add a class to a link inside a li element when a certain part of the page is active?
I have a one page website and would like to change the color of the link when that specific part of the page is reached via scroll.
Here's my HTML:
<header id="header">
<section class="container">
<nav>
<a class="logo" href="index.html">Logo</a>
<div id="menu">
<ul id="links">
<li>Services</li>
<li>About</li>
<li>Clients</li>
<li class="last">Contact</li>
</ul>
</div>
</nav>
</section>
</header>
And here's the CSS:
#menu li a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:20px;
}
#menu li.last a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:0px;
}
#menu li.current a {
color: #0086be;
}
What I would like to do is to add the class .current to the link inside the li element whenever that specific part of the page is reached.
I believe this is only possible with Javascript, can anyone point me the right path to achieve this?
Thanks in advance
I think you want something like scrollspy in bootstrap,
you can use it or you can find https://gist.github.com/pascaldevink/2380129 bypascaldevink
or here is the fiddle http://jsfiddle.net/ia_archiver/Kb7xq/
You will require jquery for this,
$.fn.scrollspy = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('scrollspy')
, options = typeof option == 'object' && option
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.defaults = {
offset: 10
}
$(function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);
Using hover function you can achieve this.i.e. on hover of specific part of the page you add the class to the link present inside the li. e.g.
$('#specificPartOfPageId').hover(function(){
$('#links').children().children('a').addClass('current');
});
This would add .current class to every link present inside that UL element.
Hope this helps.
If I have understood correctly, I guess this is what you require: jsFiddle. The CSS and the HTML code remains the same and this is the jQuery code which I've used:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 500) {
$("#links li:first-child").addClass("current");
}
if (scroll > 750) {
$("#links li:first-child").removeClass("current");
$("#links li:nth-child(2)").addClass("current");
}
var scrollBottom = $(window).scrollTop() + $(window).height();
if (scroll < 500) {
$("#links li:first-child").removeClass("current");
}
if (scroll < 750) {
$("#links li:nth-child(2)").removeClass("current");
}
});
Basically what happens is that when you scroll down to 500px, the li:first-child is automatically assigned the current class. You can modify the jQuery to suit your needs by adding more if queries as per your needs. You can target different <li>'s in your list using different child-selectors like li:first-child, li:nth-child(2) etc.
I have a very long article page that I want to help mobile users scroll on. For very long lists in mobile apps there's usually a alphabetical index that can help users jump to various places in the list. How do I implement something like that for a webapp?
If it helps my stack is angularjs / jquery / phonegap.
Just use angular's built-in $anchorScroll service.
See the live example in angular's official docs. Here are the important pieces of code:
In your view template:
<div id="scrollArea" ng-controller="ScrollCtrl">
<a ng-click="gotoBottom()">Go to bottom</a>
<a id="bottom"></a> You're at the bottom!
</div>
In your controller:
function ScrollCtrl($scope, $location, $anchorScroll) {
$scope.gotoBottom = function (){
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}
iOS7 Style List Navigator
If you want something nice on the phone, I just wrote this iOS7 style list navigator. I think the way Apple solved the problem is very straightforward. So we steal it.
It's written considering that you won't probably scroll the body, because in the many designs I've seen for smartphones, scrolling a container allows you to have fixed headers and footers for Android < 4 without getting mad.
A word of warning: this code is really fresh and untested.
SEE DEMO AND CODE
CSS (extract)
#scrolling {
padding-top: 44px;
overflow: scroll;
-webkit-overflow-scroll: touch;
height: 100%;
}
.menu {
position: fixed;
right: 0;
font-size: 12px;
text-align: center;
display: inline-block;
z-index: 2;
top: 58px;
}
.list .divider {
position: -webkit-sticky; /* will stop the label when it reaches the header */
top: 44px;
}
HTML (extract)
<div id="scrolling">
<ul class="menu">
<li>A</li>
<li>B</li>
<li>C</li>
<!-- etc -->
</ul>
<ul class="list">
<li class="divider" id="a">A</li>
<li>Amelia Webster</li>
<li>Andrew WifKinson</li>
<!-- etc -->
Javascript (zepto/jquery)
$(function() {
$(window).on("touchstart touchmove mouseover click", ".menu a", function(e) {
e.preventDefault();
clearInterval(t);
var steps = 25;
var padding = 68;
var target = $( $(this).attr("href") ).next("li");
if ( target.length > 0 ) {
var scroller = $("#scrolling")[0];
var step = parseInt((target[0].offsetTop - padding - scroller.scrollTop)/steps);
var stepno = 0;
setInterval( function() {
if ( stepno++ <= steps ) {
scroller.scrollTop += step;
} else {
clearInterval(t)
}
}, 20);
};
});
});
It performs a basic check of link validity before attempting the scroll. You can change padding to your needs.
Also, you will notice that we are targeting the first element after the required target. This is because Safari seems to go nuts because of the sticky positioning.
This code uses jQuery/Zepto selectors for the sake of brevity and readability. But these libraries are not really needed to achieve the result. With just a little extra digitation you could easily go dependency-free.
http://codepen.io/frapporti/pen/GtaLD
You can use a toggleable sidebar like this one. Resize your browser to the width of the screen of a mobile phone to understand what I mean.
Then create a directive in angularjs to wrap jQuery's animate function to scroll to a specific part in the article. Like this:
angular.module('yourModule', [])
.directive('scrollTo', function() {
return {
restrict : 'EA',
link: function(scope , element, attr){
$('html, body').animate({
scrollTop: $( attr['href'] ).offset().top
}, 300);
}
};
});
where href will be an id of a specific section in the article. Then all you need to do is apply the directive to the links in the sidebar.
...
<li><a href="#section-1" scroll-to>Jump to section 1</a></li>
...
Hope this helps.
This might be what you're looking for http://www.designkode.com/alphascroll-jquery-mobile/
Haven't used it myself, but seems pretty simple to get going with.
I think something like this could work for you: http://codepen.io/aecend/pen/AsnIE. This is just a basic prototype I put together to answer but I could expand on the concept if needed. Basically, it creates a translucent bar on the right side of the screen, finds each of the headings for articles (which would need to be adapted to suit your needs) and places clickable/tappable anchors to jump to individual articles. When you click one, the page scrolls to that article. I have a few ideas to make this actually usable, but here's the proof of concept.
CSS
#scrollhelper {
position: fixed;
top: 0;
right: 0;
height: 100%;
width: 5%;
background-color: rgba(0,0,0,0.2);
overflow: hidden;
}
#scrollhelper .point {
position: absolute;
display: block;
width: 100%;
height: 10px;
margin: 0 auto;
background-color: rgba(0,0,255,0.5);
}
JavaScript
var articles;
function buildScrollHelp() {
var bodyHeight = $("body").height();
var viewHeight = window.innerHeight;
$("#scrollhelper").html("");
articles.each(function() {
var top = $(this).offset().top;
var element = document.createElement("a");
element.className = "point";
element.href = "#" + $(this).attr("id");
element.style.top = ((top / bodyHeight) * viewHeight) + "px";
$(element).on("click", function(e){
e.preventDefault();
$('html, body').animate({
scrollTop: $($(this).attr("href")).offset().top
}, 500);
});
$("#scrollhelper")[0].appendChild(element);
});
}
$(document).ready(function() {
articles = $("body").children("[id]");
$("body").append("<div id=\"scrollhelper\"></div>");
$(window).resize(function(){
buildScrollHelp();
});
buildScrollHelp();
});
So this post might get lengthy but I'm stuck with iScroll. What I'm doing is populating my list with articles and when one gets clicked, I'm sliding in a div over the list to display the article. That part works but what doesn't is when I scroll through the article and get to the end, it keeps scrolling the list with articles. You can have a look here (the site is in russian but click on an article and scroll all the way to the bottom). Here's my entire code:
<head>
<style>
body{
padding: 0;
margin: 0;
border: 0;
}
#header{
position:fixed;
top:0;
left:0;
height:100px;
width: 100%;
background-color: black;
}
header{
position: absolute;
z-index: 2;
top: 0; left: 0;
width: 100%;
height: 50px;
}
#wrapper{
position: absolute;
z-index: 1;
width: 100%;
top: 52px;
left: 0;
overflow: auto;
}
#container{
position:fixed;
top:0;
right:-100%;
width:100%;
height:100%;
z-index: 10;
background-color: red;
overflow: auto;
}
#content{
margin:100px 10px 0px 10px;
}
</style>
</head>
<body>
<header>Main News</header>
<div id="wrapper">
<ul id="daily"></ul>
<ul id="exclusive"></ul>
<ul id="must"></ul>
<ul id="main"></ul>
<ul id="ukr"></ul>
<ul id="nba"></ul>
<ul id="euro"></ul>
</div>
<div id="container">
<div id="wrapper2">
<div id="header">
<button onclick="hide();">Back</button>
</div>
<div id="content"></div>
</div>
</div>
<script src="js/zepto.js"></script>
<script>
//AJAX requests to fill the li's...
function sayhi(url){
$('#container').animate({
right:'0',
}, 200, 'linear');
$.ajax({
url: serviceURL + "getnewstext.php",
data: {link: url},
success: function(content){
$('#content').append(content);
}
});
}
function hide(){
$('#container').animate({
right:'-100%'
}, 200, 'linear');
$('#content').empty();
}
</script>
<script src="js/iscroll-lite.js"></script>
<script>
var myScroll;
function scroll () {
myScroll = new iScroll('wrapper2', {hScroll: false, vScrollbar: false, bounce: false});
myScroll2 = new iScroll('wrapper', {hScroll: false, vScrollbar: false});
}
document.addEventListener('DOMContentLoaded', scroll, false);
</script>
</body>
Is there a way to scroll on the div container, or content, or wrapper2 without scrolling the wrapper div with the list of articles? Maybe I'm not using iScroll correctly? The same problem happens on Android and iPhone.
EDIT 1:
I set the wrapper position to fixed. Now the div container is the only one scrolling but the list of articles isn't scrolling...I added another iScroll to the wrapper but it's not working. Any advice here?
EDIT 2:
So I dropped iScroll all together and trying with CSS instead. To my onclick events I added:
$('body').css('overflow', 'hidden');
And when the close button is clicked I changed the overflow to auto. Now this stops the body from scrolling in a browser but not on mobile!!! How can I make it do the same thing on mobile???
I finally got it to work. What I needed to do is add another div inside the wrapper div. I'll share the code so hopefully it helps someone else Here's what the new code looks like:
<body>
<!--Added scroller div(without iScroll it works also...just make two divs so the body isn't scrolled but the second div is scrolled-->
<div id="wrapper">
<div class="scroller">
<header>Main News</header>
<ul id="daily"></ul>
<ul id="exclusive"></ul>
<ul id="must"></ul>
<ul id="main"></ul>
<ul id="ukr"></ul>
<ul id="nba"></ul>
<ul id="euro"></ul>
</div>
</div>
<div id="container">
<div class="scroller">
<div id="header">
<button onclick="hide();">Back</button>
</div>
<div id="content"></div>
</div>
</div>
<script>
$('body').on('touchmove', function(e){
e.preventDefault();
});
//prevents native scrolling so only iScroll is doing the scrolling
//after the AJAX call to get the content, declare your iScroll variable
var myScroll;
myScroll = new iScroll('wrapper');
setTimeout (function(){
myScroll.refresh();
}, 2000);
//set time out to give the page a little time to load the content and refresh your iScroll variable so it takes in the entire content of the wrapper div
var myScroll1;
myScroll1 = new iScroll('container');
//I defined my second iScroll variable here so I can destroy it in the next part...
//function sayhi(url) stays the same but in success of AJAX looks like this:
success: function(content){
$('#content').append(content);
myScroll1.destroy();
myScroll1 = null;
myScroll1 = new iScroll('container');
setTimeout (function(){
myScroll1.refresh();
}, 2000);
}
//when the div slides on the screen and content gets loaded, destroy your second iScroll
//variable, set it to null and define it all over again so it takes in the entire content
And that's it. Works perfectly now with two divs which need to use iScroll on the same page. Hope the explanation is clear enough and helps someone!!!
So I have been looking for a solid solution for a sticky footer for quite sometime. I found one that works well on every page and in every browser; however it takes some time to load and then take effect. Is there a way I can speed this up? Maybe load it before the page loads? Someone mentioned that it could be set to "onDOMready" instead of onLoad? Does that make sense?
Anyway, here is my code:
<script>
function positionFooter() {
var mFoo = $("#myfooter");
if ((($(document.body).height() +
mFoo.height()) < $(window).height() &&
mFoo.css("position") == "fixed") ||
($(document.body).height() < $(window).height() &&
mFoo.css("position") != "fixed"))
{
mFoo.css({ position: "fixed", bottom: "0px" });
}
else
{
mFoo.css({ position: "static" });
}
}
$(document).ready(function () {
positionFooter();
$(window).scroll(positionFooter);
$(window).resize(positionFooter);
$(window).load(positionFooter);
});
</script>
<!--content --->
<div id="myfooter" style="width:100%;"><!--footer content--></div>
How do I make it load faster?
No javascript needed (though it is helpful). The best thing to do here is take advantage of the marvelous min-height property rather than calculate from total document height.
html
<div id="wrap">
<div id="content">
<footer></footer>
</div>
css
html,body{
height:100%;
}
#wrap{
min-height:100%;
position:relative;
}
#content{
padding-bottom:20px; // allow room for footer
}
footer{
position:absolute;
width:100%;
bottom:0;
left:0;
height:20px;
}
As your page may be more complex than this, if you are finding that min-height:100% in css alone is not yielding the desired result, you may want to set in with javascript.
$(document).ready(function(){
var $window = $(window),
$wrap = $('#wrap'),
setMinHeight = function(){
$wrap.css('min-height',$window.height());
};
setMinHeight();
$window.resize(setMinHeight);
});
DEMO al la #Nick
DEMO with more content