Help me optimize this scrollTo
From a once over:


This code does not work, you did not provide $y_1, I am assuming you meant scroll_function
I built a JsBin for this : http://jsbin.com/sihoj/1/edit, because you keep calling scroll_function, you can actually prevent the user from reaching the navigation links again, that's not a good approach
As James Khoury mentioned, why not use &lt;a href="#elementid"&gt; or scrollTo ?
You should use lowerCamelCase
This : 

if (position_of_target &gt; max_scroll) {
    position_of_target = max_scroll;
}


could be 

position_of_target = Math.min( position_of_target , max_scroll );


I feel this reflects better what you are trying to accomplish    


Naming

I would much rather see

//Distance from currrent position
distance = target - window.pageYOffset; 


than

distance_from_current_position = target - window.pageYOffset; 


your code becomes a bit unwieldy when you have too many long variable names

If you have target and would have distance , then I would also go for offset, y_offset looks ugly.

Also here

position_of_target = document.getElementById(this.getAttribute('data-y')).offsetTop;


you should have some deep thoughts about the variable name, position implies usually an x/y coordinate, but you are really dealing here with an offset from the top.

Finally : up_or_down is a terrible name, there is no logical connection for 1 being up, and 0 being down. At the very least you should consider 
var UP = true, DOWN = false or var UP = 1, DOWN = 0 if you don't want to use booleans.

Magic Constants

/ 3 &lt;- That 3 should be a well named constant
target - 5 &lt;- That 5 should be a well named constant

Fake Booleans

This:

    if (window.pageYOffset &lt; position_of_target) {
        up_or_down = 1
    } else {
        up_or_down = 0
    }


is letting up_or_down be a fake boolean, you should go for 

    up_or_down = (window.pageYOffset &lt; position_of_target)


especially since you are doing falsey comparisons to up_or_down any way.

DRY

This:

        if (up_or_down) {
            if (y_offset &lt; target - 5) {
                window.scroll(0, y_offset + (distance_from_current_position / 3))
            } else {
                window.scroll(0, y_offset + 1)
            }
            if (y_offset &lt; position_of_target - 1) {
                scroll_function(target);
            }
        } else {
            if (y_offset &gt; target + 5) {
                window.scroll(0, y_offset + (distance_from_current_position / 3))
            } else {
                window.scroll(0, y_offset - 1)
            }
            if (y_offset &gt; position_of_target + 1) {
                scroll_function(target);
            }
        }


could be 

    var vector = up_or_down ? -1 : +1; 

    if (y_offset &lt; target + 5 * vector ) {
        window.scroll(0, y_offset + (distance_from_current_position / 3))
    } else {
        window.scroll(0, y_offset - vector)
    }
    if (y_offset &lt; position_of_target + vector) {
        scroll_function(target);
    }