0

Every time I use the mouse wheel (you know normal scrolling) I want the JS (jquery or whatever) to scroll to a specific class (or id doesn't matter).

I have multiple divs so code like $('body').scrollTo($nextdiv) is not an option.

I just want to make every wheel cycle to move to a next div with a specific class/id. The same for the reverse scroll. To move one div (with a specific class) up.

I found mouse wheel event and how to move to a specific div but can't manage to make it work together.

Animated scroll would be cool.

Simple question. Can I have class AND id in the same div? ex <div class="a" id="b"> ?

Limon Monte
  • 44,025
  • 43
  • 163
  • 189
user1947700
  • 59
  • 1
  • 15

2 Answers2

0

You could use the following plugins: jquery.mousewheel and jquery.scrollTo plugin, like:

/*!
 * jQuery Mousewheel 3.1.13
 *
 * Copyright 2015 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});

// The actual code:
$(document).ready(function () {

var targets = $('.scroll'); // List of elements to scroll to
var index = 0;
var duration = 500;
var canScroll = true;
var cache;

function limit(x, min, max) {
 return Math.min(max, Math.max(min, x));
}

$(window).mousewheel(function (ev) {
 
 if (canScroll) {
  
  cache = index;
  
  if (ev.deltaY < 0) {
   index = index + 1; // Scrolling down, so increase index
  } else {
   index = index - 1; // Scrolling up, so decrease index
  }
 
  // Make sure the index is between 0 and (targets.length - 1)
  index = limit(index, 0, targets.length - 1);
  
  console.log(index);
   
  // Make sure to scroll if and only if the value has changed
  if (index !== cache) {
  
  // Scroll to the target element:
  $(window).scrollTo(targets.get(index), {
    duration: duration,
   easing: 'swing'
  });

  canScroll = false;
  setTimeout(function () {
   canScroll = true;
  }, duration);
 }
}
  
ev.preventDefault();
return false;
});
});
div {
    content: ' ';
    height: 500px;
    background-color: #f2f2f2;
}

div:nth-child(even) {
    background-color: #d0d0d0;
}
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.scrollto/2.1.0/jquery.scrollTo.min.js"></script>

<div class="scroll">div1</div>
<div class="scroll">div2</div>
<div class="scroll">div3</div>
<div class="scroll">div4</div>
<div class="scroll">div5</div>
<div class="scroll">div6</div>
Tim
  • 5,137
  • 7
  • 32
  • 62
  • Will this work for any div? I want to the it to scroll down to multiple divs. Like class="div1" class="div2" class="div3". So every time I scroll it will go to the next div with the same class name. – user1947700 Aug 13 '15 at 20:48
  • Yes, see the edit. You could use the modulo operator to make it start over again. – Tim Aug 13 '15 at 20:50
  • It would be better to use IDs instead of classes here: use `#div` instead of `.div` and use classes and IDs on the element together. – Sebastian Simon Aug 13 '15 at 20:50
  • Ok. I will try it. What about the reverse scroll? I want ti go one div up. – user1947700 Aug 13 '15 at 20:51
  • Then you would use `--i` instead of `++i`. Or maybe somewhat more obvious: `i -= 1` instead of `i += 1`. – Tim Aug 13 '15 at 20:53
  • @user1947700 I would use the [`wheel`](https://developer.mozilla.org/en-US/docs/Web/Events/wheel) event instead of the `scroll` event for that: use an argument in the function: `function(e)` and in the function body, test whether e.deltaY is positive or negative. If you want more compatibility, you’d have to do it with a comparison of `window.scrollY` between two states. – Sebastian Simon Aug 13 '15 at 20:55
  • Am I doing something wrong? I added scrollTo.js to my website. Added "div1" "div2" etc to the divs I want it to scroll, but nothing happens. Any help? – user1947700 Aug 13 '15 at 20:58
  • I've adjusted the code and added a working code snippet. – Tim Aug 13 '15 at 21:19
  • Look like it what I need but it doesn't work on my local server. I added the css, copied the body. In header placed "HTTP:" so scripts can be loaded. Created a file mousewheel.js and added it to the website. Doesn't work. But code snipped here works fine. – user1947700 Aug 13 '15 at 21:38
  • Copied all the scripts to local directory. Even downloaded jquery 1.11.3 and added to the website. Did it 4 times. Not working on my local server. STRANGE. Your code snippet is working fine. – user1947700 Aug 13 '15 at 21:54
  • @user1947700 Press F12 on Chrome and check the error messages after running local website. – Tim Aug 14 '15 at 09:23
  • The page is loading well, no errors. But every time I scroll the error "Uncaught TypeError: Cannot read property 'left' of undefined" appears. The problem is in jquery.scrollTo.min.js:7. Note: It worked when I got the code **directly** from code snippet. The strange thing... the code inside – user1947700 Aug 14 '15 at 15:08
  • @user1947700 That error occurs because the jQuery selector `$('.scroller')` returns a empty list, which means that it can't find any elements with the class attribute `scroller`. You might want to wrap the code in a DOM ready event handler or put the code snippet before the closing `body` tag. – Tim Aug 16 '15 at 14:35
  • I'm a bit lost right now. What is the easiest way to fix it? And are you sure it's "scroller" and not "scroll"? Thank you for your time. – user1947700 Aug 16 '15 at 17:16
  • You're right. It is `scroll`. The easiest way to fix it: check that there are elements with the class attribute `scroll`, wrap the code in a DOM ready event handler (I've updated the script with that handler). – Tim Aug 17 '15 at 12:51
  • It works but behaves strangely. The problem is that it start scrolling before the last scrolled is finished. If the user scrolled 3 times it will go 3 divs down and it's very confusing before the user will understand how the scrolls work. So I want ti do ignore the scrolling if the screen is still animating. I would also need the script to stop when it reach the bottom (same for the top). Thank you. I really don't understand how the code is working PERFECTLY fine in the code snippet and not on my machine and server (any browser). – user1947700 Sep 02 '15 at 14:34
  • Maybe changing the sensitivity of mouse wheel will resolve this problem. Maybe putting a single wheel scroll to be equivalent to three scrolls. Thanks. – user1947700 Sep 02 '15 at 14:53
  • @user1947700 I've solved both your problems by adding a `canScroll` boolean variable in combination with a time-out. Also the `modulo` function is replaced by a `limit` function which limits the current index to larger than or equal to zero and less than the total number of elements. If this is what you seek, you should accept this answer. Good luck! – Tim Sep 03 '15 at 11:32
  • Thank you. Works great BUT... The scroll on IE and CHROME looks like crazy when scrolling. And when the page is most bottom (no more to scroll) and there are still divs it thinks that is scrolled and when you scroll up you have to scroll those divs without the actual page being scrolled. So, it looks like the page froze and not going up until you scrolled enough. Try it so you can understand better my issue. I will choose your question as the answer anyway but if you can fix those two issues I would be very happy :D Thanks again. – user1947700 Sep 04 '15 at 19:30
  • Is there a way to make this script to "understand" when the scrollbar is not moving and reached the bottom? As for the "crazy" scroll bar, if I'm not wrong, with the previous code it worked pretty well. – user1947700 Sep 04 '15 at 19:32
  • I'm testing the code in other page not in the code snippet you provided. Just a page with some text and titles (divs with scroll class). – user1947700 Sep 04 '15 at 19:39
  • @user1947700 Can you send me the code? Or replicate the issue in jsfiddle? – Tim Sep 05 '15 at 08:24
  • How do I send a private message? – user1947700 Sep 05 '15 at 18:25
  • Theere is no way so, ok here is the link: http://www71.zippyshare.com/v/j1eAZIb7/file.html – user1947700 Sep 07 '15 at 15:04
  • @user1947700 Ok, now I see the problem. I've updated the code which provides a fix for the problem. Note that if the `.scroll` elements are larger, you will observe a difference scrolling the last elements down. – Tim Sep 08 '15 at 11:01
  • Works great. Thank you. Any way to fix the problem with the last item? I can just remove the scroll class from the last two divs if there is no easy way to fix it. – user1947700 Sep 08 '15 at 15:22
  • You're welcome. Yes, use this function from this answer: http://stackoverflow.com/a/488073/1717562. You only have to change `if (index !== cache)` to `if (index !== cache && !isScrolledIntoView(targets.get(index)))`. If this solutions fits your requirements you could accept the answer. – Tim Sep 08 '15 at 15:30
  • It's not really works. It also skips some divs when scrolling down. But works fine when scrolling up. I found a piece of code which send an alert/message when a scrollbar reaches the bottom. Maybe replacing the alert(""); with a variable with a certain number will make it work. (maybe setting the canScroll to false will work or decreasing the index). – user1947700 Sep 09 '15 at 16:49
0

Quick example, this code can be improved. Better to test on jsfiddle. Point mouse over list and scroll.

Note: I didn't use class but if you understand what I did it's easy to use classes.

Note 2: I just change color but logic can be replace with anything you want.

demo

demo 2 (with classes)

var i = 0;

var list = document.getElementById("list"), length = list.children.length;
list.addEventListener("wheel", ColorLi);

function ColorLi(e) {
    //reset colors
    for(var j = 0; j < length; j++)
        list.children[j].style.color = "black";
    //calculate index
    if(e.wheelDelta > 0)
        i++;
    else
        i--;
    //fix index out of range
    i = i < 0 ? 0 : i;
    i = i > length-1 ? length-1 : i;
    //set color
    list.children[i].style.color = "red";
}
<ul id="list">
    <li style="color: red">A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
</ul>
Almis
  • 3,064
  • 2
  • 25
  • 52