Deborah
Deborah

Reputation: 4575

javascript (but not jQuery please) fixed position on x-axis but not y?

I've looked everywhere and so far have not found a non-jQuery js to handle this. I would like to avoid using a library for just this one simple task.

I would like to fix three navigation divs ("#header", "#tabs" and "#footer") to viewport left (or alternatively, to the x position of a div "#helper" with "position: fixed; left: 0; top: 0;") -- but not fix y. They can not be vertically fixed.

I've created a working js that forces the divs to reposition based on scrolling, but it's not smooth in the real page (too many dynamic and graphic elements) - I'd like it to either animate smoothly, or mimic fixed-left and not appear to reposition at all.

Anyone who can give pointers or a quick script, or review and modify the script I have made? I've noticed people tend to ask why an obvious solution is not used instead of answering the question... I will be glad to answer, but would prefer help with the actual problem.

Here is a jsFiddle with the problem: http://jsfiddle.net/BMZvt/6/

Thank you for any help!

Upvotes: 1

Views: 1104

Answers (3)

Deborah
Deborah

Reputation: 4575

This is for people who view this post - I wound up going with the solution I initially put together in the jsFiddle that used a simple javascript to mimic fixed x.

The javascript in the first answer was hefty and wound up buggy, and the second answer sounded good but did not work in practice. So, I'm recommending the javascript from the jsFiddle (below) as the best answer to fixed x and fluid y without a javascript library. It's not perfect and has a minimal delay but is the best answer I've found.

function fixLeft() {

            function getScrollX() {
                var x = 0, y = 0;
                if( typeof( window.pageYOffset ) == 'number' ) {
                    x = window.pageXOffset;
                } else if( document.body && ( document.body.scrollLeft) ) {
                    x = document.body.scrollLeft;
                } else if( document.documentElement && ( document.documentElement.scrollLeft) ) {
                    x = document.documentElement.scrollLeft;
                }
                return [x];
            }

            var x = getScrollX();
            var x = x[0];

        // have to get and add horizontal scroll position px
        document.getElementById('header').style.left = x + "px";
        document.getElementById('tabs').style.left = x + "px";
        document.getElementById('footer').style.left = x + "px";
    }

    window.onscroll = fixLeft;

Upvotes: 0

Peter
Peter

Reputation: 16943

Smooth animation example:

var box = document.getElementById('box');

var moveTo = function(obj, target) {
    // start position
    // you should obtain it from obj.style
    var cpos = {
        x: 0,
        y: 0
    }        
    var iv = setInterval(function(){
        cpos.x += (target.x - cpos.x) * 0.3; // 0.3 is speed
        cpos.y += (target.y - cpos.y) * 0.3; // 0.3 is speed
        obj.style.left = Math.floor(cpos.x) + 'px';
        obj.style.top = Math.floor(cpos.y) + 'px';
        var dist = Math.abs(cpos.y - target.y); // distance (x+y) from destination
        dist += Math.abs(cpos.x - target.x); // < 1 = object reached the destination

        if(dist < 1) { // here we are checking is box get to the destination 
           clearInterval(iv);
        }
    }, 30); // this is also the speed
}

box.onclick = function(){
    moveTo(box, {x: 90, y: 75}); // fire this function to move box to specified point
}

Your script is your job, but this is a quick start how to solve animation problem

You can also do some fancy stuff with speed for example use sin(x) to set the speed


Upvotes: 3

Euimin Jung
Euimin Jung

Reputation: 11

I don't think there's a straight way to do this...

But here's a way.

First, You need to be able to detect the direction of the scrolling when window.onscroll event happens. You would do this by comparing the current page offsets with the newly acquired page offsets whenever the scroll event happens. (http://stackoverflow.com/questions/1222915/can-one-use-window-onscroll-method-to-include-detection-of-scroll-direction)

Now suppose you know the direction of the scroll, you want to change the styling for the divs depending on the direction of the scroll.

Let FixAtX be the value of the x coordinate that you want to fix your divs at. Let OriginalY be the y coordinate of the divs. Also whenever scrolling happens, despite of the direction, you want to remember the pageoffset X and Y. Let's call them OldX and OldY

If scrolling vertically:

  • Set position value for divs' style to be absolute.
  • Set top value for divs' style to be OriginalY
  • Set left value for divs' style to be OldX + FixAtX

If scrolling horizontally:

  • Set position value for divs' style to be fixed.
  • set top value for divs' style to be OriginalY - OldY (<- this may be different depending on how the browser computes pageOffset value,)
  • Set Left value for divs' style to be FixAtX

I think this should work... Since you are just using browser's rendering for positioning, it should be very smooth!

hope I understood the question correctly.

Upvotes: 0

Related Questions