wolfsburg
wolfsburg

Reputation: 17

jquery mouseover / mouseout to change scroll position

I am new to jquery and I am struggling with the following:

From research I have come up with a quick jsfiddle. It's not quite working yet, what I would like to achieve is:

I want 'Link30' to go to the top when I mouseover 'DIV 1' (and for 'Link30' to remain at the top on mouseout).

Then I want 'Link50' to go to the top when I mouseover 'DIV 2' (and for 'Link50' to remain at the top on mouseout).

I want to mouseover the divs any number of times and still have the relevant links go to the top of the scrolling div each time.

At the moment you mouseover 'DIV 1' and 'Link30' goes to the top however then when you mouseover 'DIV 2' it stays at 'Link30' rather than moving to 'Link50' as I would like.

Hope this makes sense. Thanks.

Here is a sample of my code but you are best seeing the jsfiddle.

$( "div.overout1" )

.mouseover(function() {
$( this ).find( "span" ).text( "mouse over " );
$('a').filter(function(index) { return $(this).text() === 'Link30';    }).addClass('on');
var offset = $('.on').offset().top - $('.links').scrollTop();
if(offset > window.innerHeight)
    {
    $('.links').scrollTop(offset);
    }
})

.mouseout(function() {
$( this ).find( "span" ).text( "mouse out " );
$('a').filter(function(index) { return $(this).text() === 'Link30'; }).removeClass('on');
});

$( "div.overout2" )

.mouseover(function() {
$( this ).find( "span" ).text( "mouse over " );
$('a').filter(function(index) { return $(this).text() === 'Link50'; }).addClass('on');
var offset = $('.on').offset().top - $('.links').scrollTop();
if(offset > window.innerHeight)
    {
    $('.links').scrollTop(offset);
    }
})

.mouseout(function() {
$( this ).find( "span" ).text( "mouse out " );
$('a').filter(function(index) { return $(this).text() === 'Link50'; }).removeClass('on');
});

Upvotes: 0

Views: 1756

Answers (3)

Alessandro Incarnati
Alessandro Incarnati

Reputation: 7248

Given your requirements, you could create a function that you can reuse passing it different parameters ($elem as which div to apply the hover effect, and the link number for example):

Let's call the function hoverLink for instance.

You could this in so many ways but modifying quickly your code...

**

$('document').ready(function() {
    var hoverLink = function($elem, link) {

        $elem.hover(function() {
            var offset = $('.links').position().top;
            $('a').removeClass('on');

            $('a').filter(function(index) {
                return $(this).text() === 'Link' + link;
            }).addClass('on');

            offset = $('.on').position().top;
            $('.links').scrollTop(offset);

        });
    };
    var div = $('.overout1');
    var div2 = $('.overout2');
    var div3 = $('.overout3');

    hoverLink(div, 10);
    hoverLink(div2, 25);
    hoverLink(div3, 50);
});
html,body{height:100%;}
.overout1,.overout2,.overout3 {
    width: 100px;
    height:100px;
    margin:10px;
    float: left;
    color:white;
    font-weight:bold;
    font-family:helvetica;
    padding:5px;
    position:relative;
    z-index:2;
  }
.overout1 {
    background-color: green;
  } 
.overout2 {
    background-color: blue;
  } 
.overout3 {
    background-color: red;
  } 
.links{
    width: 40%;
    height: 100px;
    background-color: orange;
    float: left;
    color:white;
    font-weight:bold;
    font-family:helvetica;
    overflow:auto;
    position:relative;    
}
 
  p,span {
    line-height: 1em;
    margin: 0;
    padding: 0;
    position:relative;
    z-index:1;
  }
.on {color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<html>
<head></head>
<body>
 <div class="overout1">
       <p>DIV 1</p>
      <span>move your mouse</span>
</div>
<div class="overout2">
        <p>DIV 2</p>
      <span>move your mouse</span>
</div>
<div class="overout3">
        <p>DIV 3</p>
      <span>move your mouse</span>
</div>

<div class="links">
<a href="#">Link1</a><br />
<a href="#">Link2</a><br />
<a href="#">Link3</a><br />
<a href="#">Link4</a><br />
<a href="#">Link5</a><br />
<a href="#">Link6</a><br />
<a href="#">Link7</a><br />
<a href="#">Link8</a><br />
<a href="#">Link9</a><br />
<a href="#">Link10</a><br />
<a href="#">Link11</a><br />
<a href="#">Link12</a><br />
<a href="#">Link13</a><br />
<a href="#">Link14</a><br />
<a href="#">Link15</a><br />
<a href="#">Link16</a><br />
<a href="#">Link17</a><br />
<a href="#">Link18</a><br />
<a href="#">Link19</a><br />
<a href="#">Link20</a><br />
<a href="#">Link21</a><br />
<a href="#">Link22</a><br />
<a href="#">Link23</a><br />
<a href="#">Link24</a><br />
<a href="#">Link25</a><br />
<a href="#">Link26</a><br />
<a href="#">Link27</a><br />
<a href="#">Link28</a><br />
<a href="#">Link29</a><br />
<a href="#">Link30</a><br />
<a href="#">Link31</a><br />
<a href="#">Link32</a><br />
<a href="#">Link33</a><br />
<a href="#">Link34</a><br />
<a href="#">Link35</a><br />
<a href="#">Link36</a><br />
<a href="#">Link37</a><br />
<a href="#">Link38</a><br />
<a href="#">Link39</a><br />
<a href="#">Link40</a><br />
<a href="#">Link41</a><br />
<a href="#">Link42</a><br />
<a href="#">Link43</a><br />
<a href="#">Link44</a><br />
<a href="#">Link45</a><br />
<a href="#">Link46</a><br />
<a href="#">Link47</a><br />
<a href="#">Link48</a><br />
<a href="#">Link49</a><br />
<a href="#">Link50</a><br />
<a href="#">Link51</a><br />
<a href="#">Link52</a><br />
<a href="#">Link53</a><br />
<a href="#">Link54</a><br />
<a href="#">Link55</a><br />
<a href="#">Link56</a><br />
<a href="#">Link57</a><br />
<a href="#">Link58</a><br />
<a href="#">Link59</a><br />
<a href="#">Link60</a><br />
</div>
</body>
</html>

** https://jsfiddle.net/a_incarnati/fkhbcxzw/16/

Upvotes: 1

Shikkediel
Shikkediel

Reputation: 5205

Here's a somewhat optimised version :

https://jsfiddle.net/fkhbcxzw/15/

linkScroll($('div.overout1'), 'Link30');
linkScroll($('div.overout2'), 'Link50');

function linkScroll(item, identify) {

    var object;

    item
    .on('mouseenter touchstart', function() {

        object = $(this).find('span');
        object.text('mouseenter-touchstart');
        $('a').removeClass('on').filter(function() {return $(this).text() === identify}).addClass('on');

        var offset = $('.on').position().top;
        var current = $('.links').scrollTop();
        $('.links').scrollTop(current+offset);
    })
    .mouseleave(function() {

        object.text('mouseleave');
    });
}

Because only a single action is needed on entering each div, it's better to use mouseenter which only fires on the parent. The mouseover events keeps unnecessarily firing as long as you're hovering. Also added some mobile support.

Upvotes: 1

Tasos
Tasos

Reputation: 5361

Its better if you use a class for the positions you want to scroll to together with some flags e.g on/off.

Demo https://jsfiddle.net/jc8aqz65/

Script

var tclass;
var cla = 0;
var clab = 0;
var topa = $('.30').position().top - 10;
var topb = $('.50').position().top - 10;
$(".overout1, .overout2").mouseover(function () {
    tclass = $(this).attr("class")
    $(this).find("span").text("mouse over ");
    if (cla == 0 && tclass == "overout1") {
        $('.links').animate({
            scrollTop: topa
        }, 500);
        cla = 1;
    } else if (clab == 0 && tclass == "overout2") {
        $('.links').animate({
            scrollTop: topb
        }, 500);
        clab = 1;
    }
}).mouseout(function () {
    $(this).find("span").text("mouse out ");
    if (tclass == "overout1") {
        clab = 0;
    } else {
        cla = 0;
    }
});

Upvotes: 1

Related Questions