0

What I'm trying to achieve is basicly having navigation elements like

link1 link2 link3

and below them there's an image

[x] <- defaultImage

Now what I want is when I hover over link1 the image changes to image1, when I hover over link2 the image changes to image2,... and when I onMouseOut - the image goes back to defaultImage

I had this working with

function mouseOverImage(elm) {
var id = document.getElementById("catPic");
img.style.width = elm.getAttribute('data-cat-width');
img.style.height = elm.getAttribute('data-cat-height');
}
function mouseOutImage() {
var id = document.getElementById("catPic");
img.style.width = img.getAttribute('data-default-width');
img.style.height = img.getAttribute('data-default-height');
}

+

<ul>
<li>
<a href="link.htm" data-cat-image="images/img11.jpg"
data-cat-width="280px"
data-cat-height="336px" onmouseover="mouseOverImage(this)"
onmouseout="mouseOutImage()">link1</a>
</li>

<li><a href="link2.htm" data-cat-image="images/img22.jpg"
data-cat-width="280px"
data-cat-height="436px" onmouseover="mouseOverImage(this)"
onmouseout="mouseOutImage()">link2</a></li>

+

<div class="floatimg">
<img src="" width="0" height="0" alt="" id="catPic"
data-default-image="images/default.jpg"
data-default-width="0px" data-default-height="40px">
</div>

and it works fine

BUT

Now I want to change approach, and instead of using different images each time when calling for change via onMouseOver I want to use Sprites

And I'm really struggling how should I approach it?

I generated an image sprite out of few images and I have a code like

.sprite-1, .sprite-2, .sprite-3, .sprite-4,
{ display: block; background: url('tmp.png') no-repeat; }
.sprite-3 { background-position: -0px -0px; width: 280px; height: 441px; }
.sprite-4 { background-position: -288px -0px; width: 280px; height: 420px; }
.sprite-5 { background-position: -576px -0px; width: 280px; height: 420px; }

I have no idea about Scripts so please treat this as a total newb question and if you have and answer please tell me where to put the code

Thanks a lot for any help!

Seb
  • 113
  • 1
  • 4
  • 12

2 Answers2

1

First, make some functions to add and remove a class from a HTMLElement, you'll be interested in the Element.className property for this..

function hasClass(e, c) {
    return (' ' + e.className + ' ').indexOf(' ' + c + ' ') !== -1; // in list
}

function addClass(e, c) {
    if (!hasClass(e, c)) e.className += ' ' + c; // add if not in list
    return e;
}

function removeClass(e, c) {
    var i, s = ' ' + e.className + ' ';
    c = ' ' + c + ' ';
    while (-1 !== (i = s.indexOf(c))) { // while class in list
        s = s.slice(0, i) + ' ' + s.slice(i + c.length); // replace with space
    }
    e.className = s.slice(1, -1); // set
    return e;
}

Then attach listeners in your favourite way, for example you can use a similar pattern to your existing way if you write functions for mouseover and mouseout such as..

function chooseImage(x) {
    addClass(
        document.getElementById("catPic"),
        'sprite-'+x
    );
    // unchooseImage('default here');
}
function unchooseImage(x) {
    // chooseImage('default here');
    removeClass(
        document.getElementById("catPic"),
        'sprite-'+x
    );
}

There is another property which you could use, element.classList, but this isn't fully supported by all browsers yet (only basic support in IE 10).


The following would be for .sprite-1 and .sprite-2.

<a href="example.htm"
   onmouseover="chooseImage(1)"
   onmouseout="unchooseImage(1)">link1</a>
<a href="example.htm"
   onmouseover="chooseImage(2)"
   onmouseout="unchooseImage(2)">link2</a>
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Hey Paul, thanks for the answer. Could you please explain more clear what should I do with it? What element do I have to change in order to have it work? First I put the "function chooseImage(x) {..." in script part in Dreamweaver and it yells that there's syntax error in line where there's 'sprite-'+x; also what do I do in my hrefs? I did this link1 but I guess it's not the correct way :/ Sorry but I really have no clue about scripts, I can figure only basic stuff. Thanks – Seb Jul 05 '13 at 21:16
  • I left in `;` by accident. I've added in some HTML example, see edit. – Paul S. Jul 05 '13 at 22:20
  • OK I really tried to understand the code but I just can't get it to work - this is what I got http://jsfiddle.net/dv4ZY/3/ where did I go wrong? – Seb Jul 06 '13 at 16:27
  • Oh by the way I just found out last time I actually used your code Paul http://stackoverflow.com/questions/13512449/how-to-change-image-with-onmouseover-in-different-place-that-reverts-back-to-def/13512659#comment18500150_13512659 :) This time I probably will too if I get it to work – Seb Jul 06 '13 at 17:13
  • I fiddled some more with simpler script and I found that if I have a default attribute like text color, then I can't change the color, and if I don't have color set for default state then this works [very short code here](http://jsfiddle.net/xjG4H/) So how to turn it to a working state? – Seb Jul 06 '13 at 17:22
  • 1
    @Seb http://jsfiddle.net/dv4ZY/4/ ; changes to fiddle: 1. JavaScript no wrap in head. 2. Moved default style of _#catPic_ from _style_ attribute to new CSS _.sprite-0_ (before any other sprite definition) and gave _#catPic_ class _sprite-0_. – Paul S. Jul 06 '13 at 19:29
  • 1
    (The CSS is done as a class `.` because if it used the id `#` then it would be more strongly binding than the class, so any other class would not override it.) If you want to use jQuery's `hover` and `toggle`, that will work in the fiddle now, too. – Paul S. Jul 06 '13 at 19:31
0

Just in case someone need it, this can be achieved by pure CSS if the elements has the same parent. Usign the ~ or sibiling selector. A further explanation on how it works can be found here.

The general sibling combinator selector is very similar to the adjacent sibling combinator selector we just looked at. The difference is that that the element being selected doesn't need to immediately succeed the first element, but can appear anywhere after it.

I made a jsfiddle to enlight the trick. https://jsfiddle.net/cwh7dww1/

Iván Rodríguez Torres
  • 4,293
  • 3
  • 31
  • 47