How to use Mouse Wheel for jumping to next or previous # section in html - html

I have a site with top nav menu:
<nav id="menu">
<ul id="menu-nav">
<li class="current">Home</li>
<li>Cakes</li>
<li>Candy</li>
<li>Marshmellow</li>
<li>Honey</li>
</ul>
</nav>
And all my sections are:
<div id="Cakes" class="page">
<div class="container">
This is sweet
</div>
</div>
How can I use the mouse wheel to jump directly to the next or previous section?
Currently the mouse wheel will scroll the page like normal. But I want it to jump to every section with one wheel rotation without scrolling all the entire page.

Without plugins, all we need to do is to capture the mousewheel using mousewheel event -on Firefox we use DOMMouseScroll instead- and depending on the value of the event's originalEvent.wheelDelta -again in Firefox it is originalEvent.detail, thanks Firefox- if this value is positive then the user is scrolling upward, if it's negative then the direction is down.
JS Fiddle 1
jQuery (1) :
//initialize
var winHeight = $(window).height(),
pages = $('.page'),
navLinks = $('#menu-nav a'),
currentPage = 0;
$('html, body').animate({ scrollTop: 0}, 0);
// listen to the mousewheel scroll
$(window).on('mousewheel DOMMouseScroll', function(e){
//by default set the direction to DOWN
var direction = 'down',
$th = $(this),
// depending on the currentPage value we determine the page offset
currentPageOffset = currentPage * winHeight;
// if the value of these properties of the even is positive then the direction is UP
if (e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
direction = 'up';
}
// if the direction is DOWN and the currentPage increasing won't exceed
// the number of PAGES divs, then we scroll downward and increase the value
// of currentPage for further calculations.
if(direction == 'down' && currentPage <= pages.length - 2){
$th.scrollTop(currentPageOffset + winHeight);
currentPage++;
} else if(direction == 'up' && currentPage >= 0) {
// else scroll up and decrease the value of currentPage IF the direction
// is UP and we're not on the very first slide
$th.scrollTop(currentPageOffset - winHeight);
currentPage--;
}
});
// as final step we need to update the value of currenPage upon the clicking of the
// navbar links to insure having correct value of currentPage
navLinks.each(function(index){
$(this).on('click', function(){
navLinks.parent().removeClass('current');
$(this).parent().addClass('current');
currentPage = index;
});
});
(1) UPDATE
If you don't want to use jQuery, below is pure javascript code doing the same as above, this won't work in IE8 and below though:
JS Fiddle 2
Pure Javascript:
//initialize
var winHeight = window.innerHeight,
pages = document.getElementsByClassName('page'),
navLinks = document.querySelectorAll('#menu-nav a'),
currentPage = 0;
window.addEventListener('mousewheel', function(e) {
scrollPages(e.wheelDelta);
});
window.addEventListener('DOMMouseScroll', function(e) {
scrollPages(-1 * e.detail);
});
function scrollPages(delta) {
var direction = (delta > 0) ? 'up' : 'down',
currentPageOffset = currentPage * winHeight;
if (direction == 'down' && currentPage <= pages.length - 2) {
window.scrollTo(0, currentPageOffset + winHeight);
currentPage++;
} else if (direction == 'up' && currentPage > 0) {
window.scrollTo(0, currentPageOffset - winHeight);
currentPage--;
}
}
for (var i = 0; i < navLinks.length; i++) {
navLinks[i].addEventListener('click', updateNav(i));
}
function updateNav(i) {
return function() {
for (var j = 0; j < navLinks.length; j++) {
navLinks[j].parentNode.classList.remove('current');
}
navLinks[i].parentNode.classList.add('current');
currentPage = i;
}
}

You'll need to get a plug-in to add the mousewheel event.
Maybe try this one this.
it's got pretty good examples.

Related

Scroll up drag in web page

I'm looking to scroll up a page when I have a div selected, so the goal is to drag a div and move the page up. The scoll down works strangely.
Is there a problem with angular or html that would be listed?
(I don't want to use Jquery)
<div class="panel panel-default">
<div class="panel-body">
<p class="h4">Commandes</p>
<div class="row">
<div class="col-md-12 col-xs-12 text-right" draggable="true">
<button type="button" (click)="addCommande()" class="btn btn-labeled btn-purple m-l-4">
<span class="btn-label"><i class="fa fa-plus"></i></span><span class="hidden-xs">Ajouter une commande</span>
</button>
</div>
</div>...
editadding solutions based on our discussion in the comments section
im still not sure if I got your end goal, but I hope I did
[first solution] add `scrollPositionRestoration: 'enabled'` to `app-routing.module.ts` 's `RouterModule`:
RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'})
[second solution] try implementing this logic]
export class ScrollToTopComponent implements OnInit {
windowScrolled: boolean;
constructor(#Inject(DOCUMENT) private document: Document) {}
#HostListener("window:scroll", [])
onWindowScroll() {
if (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop > 100) {
this.windowScrolled = true;
}
else if (this.windowScrolled && window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop < 10) {
this.windowScrolled = false;
}
}
scrollToTop() {
(function smoothscroll() {
var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
if (currentScroll > 0) {
window.requestAnimationFrame(smoothscroll);
window.scrollTo(0, currentScroll - (currentScroll / 8));
}
})();
}
ngOnInit() {}
[third solution]
If all fails, then create some empty HTML element (eg: div) at the top (or desired scroll to location) with id="top":
<div id="top"></div>
And in component:
ngAfterViewInit() {
// Hack: Scrolls to top of Page after page view initialized
let top = document.getElementById('top');
if (top !== null) {
top.scrollIntoView();
top = null;
}
}
I dont have much to work with regarding how you built your code, but I hope this might solve it (it will make draggable items scroll your screen) :)
var stop = true;
document.quertSelector(".draggable").on("drag", function (e) {
stop = true;
if (e.originalEvent.clientY < 150) {
stop = false;
scroll(-1)
}
if (e.originalEvent.clientY > ($(window).height() - 150)) {
stop = false;
scroll(1)
}
});
document.querySelector(".draggable").on("dragend", function (e) {
stop = true;
});
var scroll = function (step) {
var scrollY = window.pageYOffset;
window.pageYOffset(scrollY + step);
if (!stop) {
setTimeout(function () { scroll(step) }, 20);
}
}

JQuery - delay function

I have a function that positions a side nav to a fixed position depending on other elements (including a fixed header) on scroll/resize/load. The position top is calculated next to the content container (#timelineFulltext) OR below a header (.sticky).
The problem is the position is kicking in before the sticky header hides, which is another function.
Is there a way I can delay the execution of this function:
jQuery(window).on('load scroll resize', function (){
// Position TOC on load, scroll and resize
var isSticky = jQuery('.sticky'); // Check if sticky header is present
if(isSticky.length && jQuery('#timelineFulltext').offset().top < jQuery(window).scrollTop()){
var timelinePosition = isSticky.height() + 38;
}
else{
var timelinePosition = jQuery('#timelineFulltext').offset().top - jQuery(window).scrollTop();
}
jQuery('.fixed-timeline').css({'top': timelinePosition + 'px'});
});
A solution is to use setTimeOut. In this example it will wait 3 seconds before executing your function.
jQuery(window).on('load scroll resize',function() {
setTimeout(function() {
// Position TOC on load, scroll and resize
var isSticky = jQuery('.sticky'); // Check if sticky header is present
if(isSticky.length && jQuery('#timelineFulltext').offset().top < jQuery(window).scrollTop()){
var timelinePosition = isSticky.height() + 38;
}
else{
var timelinePosition = jQuery('#timelineFulltext').offset().top - jQuery(window).scrollTop();
}
jQuery('.fixed-timeline').css({'top': timelinePosition + 'px'});
},
3000);
});
you can create a function say hideStickyBar to apply header sticky bar script. Call this function as callback from hide function in jquery. See below sample code
$('#elementTohide').hide(400, hideStickyBar);
jQuery(window).on('load scroll resize', function (){
hideStickyBar();
});
function hideStickyBar() {
// Position TOC on load, scroll and resize
var isSticky = jQuery('.sticky'); // Check if sticky header is present
if(isSticky.length && jQuery('#timelineFulltext').offset().top < jQuery(window).scrollTop()){
var timelinePosition = isSticky.height() + 38;
}
else{
var timelinePosition = jQuery('#timelineFulltext').offset().top - jQuery(window).scrollTop();
}
jQuery('.fixed-timeline').css({'top': timelinePosition + 'px'});
}

Dropdown menu not working on mobile

I have searched high and low and tried many different options from here, but i need a point in the right direction now :)
On this site:
http://www.michael-smith-engineers.co.uk
On the main nav, (in mobile view) if you click on Pumps, there should be further dropdown options, but i can not get this working. Any ideas would be appreciated.
I have tried adding the following script, without any luck...
<script>
// see whether device supports touch events (a bit simplistic, but...)
var hasTouch = ("ontouchstart" in window);
var iOS5 = /iPad|iPod|iPhone/.test(navigator.platform) && "matchMedia" in window;
// hook touch events for drop-down menus
// NB: if has touch events, then has standards event handling too
// but we don't want to run this code on iOS5+
if (hasTouch && document.querySelectorAll && !iOS5) {
var i, len, element,
dropdowns = document.querySelectorAll("#nav-site li.children > a");
function menuTouch(event) {
// toggle flag for preventing click for this link
var i, len, noclick = !(this.dataNoclick);
// reset flag on all links
for (i = 0, len = dropdowns.length; i < len; ++i) {
dropdowns[i].dataNoclick = false;
}
// set new flag value and focus on dropdown menu
this.dataNoclick = noclick;
this.focus();
}
function menuClick(event) {
// if click isn't wanted, prevent it
if (this.dataNoclick) {
event.preventDefault();
}
}
for (i = 0, len = dropdowns.length; i < len; ++i) {
element = dropdowns[i];
element.dataNoclick = false;
element.addEventListener("touchstart", menuTouch, false);
element.addEventListener("click", menuClick, false);
}
}
</script>
This script above is ridiculous for what i was trying so, tried this:
<script type="text/javascript">
function is_touch_device() {
return (('ontouchstart' in window) || (navigator.MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
}
if(is_touch_device()) {
jQuery('.toggle-menu').on('click', function(){
jQuery(this).toggleClass('activate');
jQuery(this).find('ul').slideToggle();
return false;
});
}
</script>
</head>
Still no luck tho?!!!!

Scrolling child div makes parent div scrolls

I have the following test page:
(didn't post code 'cause would be too big)
As noticed, when you finish scrolling the little div in the bottom, the main div also scrolls. Is there anything, propriety to disable this behaviour?
Thanks.
See the plugin mentioned on this question:
Prevent scrolling of parent element?
Or take a look at the JS here (not my code). This code adds classes to the children and traps the scroll event which can be used to prevent the parent from scrolling.
http://codepen.io/LelandKwong/pen/edAmn
var trapScroll;
(function($){
trapScroll = function(opt){
var trapElement;
var scrollableDist;
var trapClassName = 'trapScroll-enabled';
var trapSelector = '.trapScroll';
var trapWheel = function(e){
if (!$('body').hasClass(trapClassName)) {
return;
} else {
var curScrollPos = trapElement.scrollTop();
var wheelEvent = e.originalEvent;
var dY = wheelEvent.deltaY;
// only trap events once we've scrolled to the end
// or beginning
if ((dY>0 && curScrollPos >= scrollableDist) ||
(dY<0 && curScrollPos <= 0)) {
opt.onScrollEnd();
return false;
}
}
}
$(document)
.on('wheel', trapWheel)
.on('mouseleave', trapSelector, function(){
$('body').removeClass(trapClassName);
})
.on('mouseenter', trapSelector, function(){
trapElement = $(this);
var containerHeight = trapElement.outerHeight();
var contentHeight = trapElement[0].scrollHeight; // height of scrollable content
scrollableDist = contentHeight - containerHeight;
if (contentHeight>containerHeight)
$('body').addClass(trapClassName);
});
}
})($);
var preventedCount = 0;
var showEventPreventedMsg = function(){
$('#mousewheel-prevented').stop().animate({opacity: 1}, 'fast');
}
var hideEventPreventedMsg = function(){
$('#mousewheel-prevented').stop().animate({opacity: 0}, 'fast');
}
var addPreventedCount = function(){
$('#prevented-count').html('prevented <small>x</small>' + preventedCount++);
}
trapScroll({ onScrollEnd: addPreventedCount });
$('.trapScroll')
.on('mouseenter', showEventPreventedMsg)
.on('mouseleave', hideEventPreventedMsg);
$('[id*="parent"]').scrollTop(100);

HTML5 Touchmove event only in one direction

Im creating an object to drag with "touchmove" in Y but i want it only to be dragged in one direction, up!
But it also makes it go down.. How can i solve this?
In each interval of Y some actions will take place there and the objective is to drag the item only in one way disabling the possibility to the user dont go to the previews actions.
Here is the code:
var moveMe = function(e) {
e.preventDefault();
var orig = e.originalEvent;
var y = event.touches[0].pageY;
if(y<=600 && y>420){
$(this).css({
top: orig.changedTouches[0].pageY
});
if(y<570 && y>=540){
}else {
if(y<540 && y>=510){
}else {
if(y<510 && y>=480){
}else {
if(y<480 && y>=450){
}else {
if(y<450 && y>=420){
}
}
}
}
}
}
};
$("#draggable").bind("touchstart touchmove", moveMe);
Not tested, but is it possible that you have a mistake in the following line?
var y = event.touches[0].pageY;
shoudn't you use here "e" instead of "event"?
hope it helps.