Errore Fatale
Errore Fatale

Reputation: 988

A HTML container doesn't scroll properly after the position of its child is changed

To understand my problem you can see the jsfiddle I've created.

https://jsfiddle.net/hxzLeL6x/2/

When you click on the second image, the gray container which contains the two images slips towards left until the second image is at the extreme left of its father.

The father, as you can see, doesn't scroll properly after its child has been moved.

How can I solve the problem?

Here below the HTML code

<div id="tapeContainer">
    <div id="tape">
       <img id="firstImage" src="http://www.fotosd.it/wp-content/uploads/paesaggio-montano-della-val-di-fassa-in-estate_imagelarge.jpg">

       <img id="secondImage" src="http://www.improntaunika.it/wp-content/uploads/2014/01/paesaggio20toscano.jpg">
    </div>
</div>

Here the css code

#tapeContainer{
  overflow: scroll;
  width:600px;
}

#tape{
  background-color: #616161;
  position: relative;
  height: 50px;
  width:3000px;
}

img{
  width:50px;
  height:50px;
}

And finally, the javascript code

document.getElementById("secondImage").addEventListener("click", onImageClick.bind(null));


function onImageClick(e) {
            var clickedImage = e.currentTarget;
            var displacement = 0;


            var targetPosition = document.getElementById("tapeContainer").getBoundingClientRect().left;
            var tape = document.getElementById("tape");
            move();


            function move() {
                displacement += 1;
                tape.style.setProperty("right", displacement + "px");

                if(clickedImage.getBoundingClientRect().left !== targetPosition)
                {
                    setTimeout(move, 1);
                }
            }
}

Upvotes: 0

Views: 55

Answers (2)

Luke Benting
Luke Benting

Reputation: 168

I believe this gets you the functionality you require in a much simpler way:

function onImageClick(e) {
    var clickedImage = e.currentTarget;        
    var tapeContainer = document.getElementById("tapeContainer");
    tapeContainer.scrollLeft = clickedImage.offsetLeft;
}

https://jsfiddle.net/hxzLeL6x/3/

If you would like to retain the animation you can use this code:

function onImageClick(e) {
    var clickedImage = e.currentTarget;        
    var tapeContainer = document.getElementById("tapeContainer");
    var goal = clickedImage.offsetLeft;
    move();

    function move() {
        if(tapeContainer.scrollLeft < goal) {
            tapeContainer.scrollLeft += 1;
        }

        if(tapeContainer.scrollLeft > goal) {
            tapeContainer.scrollLeft -= 1;
        }

        if(Math.round(tapeContainer.scrollLeft) != goal) {
            setTimeout(move, 1);
        }
    }
}

http://jsfiddle.net/hxzLeL6x/14/

Upvotes: 1

Errore Fatale
Errore Fatale

Reputation: 988

A better solution is to use the property scrollLeft instead of changing the position of #tape.

The updated jsfiddle: https://jsfiddle.net/hxzLeL6x/9/

The following line of javascript

tape.style.setProperty("right", displacement + "px");

is replaced by this one

document.getElementById("tapeContainer").scrollLeft = displacement;

Upvotes: 0

Related Questions