2011-01-11 140 views
7

我只是试着原型的scrollTo功能和作为文档状态,它滚动页面,以便元素可见

滚动,使元素 出现在视口上方的窗口

我想要一个功能

  1. 只滚动如果元素在视口内不完全可见
  2. 滚动,使元素出现在视口的中心

没有人知道在原型这样的功能的,Scriptaculous的或独立?

+0

不知何故有关[如何滚动使用JavaScript的元素(http://stackoverflow.com/questions/5007530/how-do-i-scroll-to-an-元素使用JavaScript)和[滚动到div的底部](http://stackoverflow.com/questions/270612/scroll-to-bottom-of-div)。 – 2016-06-03 19:29:34

回答

6

我猜你需要像这样demo

window.height

function getWindowHeight() { 
    var body = document.body; 
    var docEl = document.documentElement; 
    return window.innerHeight || 
     (docEl && docEl.clientHeight) || 
     (body && body.clientHeight) || 
     0; 
} 

滚动

function scrollElemToCenter(id, duration) { 
    var el = document.getElementById(id); 
    var winHeight = getWindowHeight(); 
    var offsetTop = el.offsetTop; 
    if (offsetTop > winHeight) { 
    var y = offsetTop - (winHeight-el.offsetHeight)/2; 
    // wo animation: scrollTo(0, y); 
    scrollToAnim(y, duration); 
    } 
} 

动画(可选,您可以使用script.aculo.us等)

function interpolate(source,target,pos) { return (source+(target-source)*pos); } 
function easing(pos) { return (-Math.cos(pos*Math.PI)/2) + 0.5; } 

function scrollToAnim(targetTop, duration) { 
    duration || (duration = 1000); 
    var start = +new Date, 
     finish = start + duration, 
     startTop = getScrollRoot().scrollTop, 
     interval = setInterval(function(){ 
     var now = +new Date, 
      pos = (now>finish) ? 1 : (now-start)/duration; 
     var y = interpolate(startTop, targetTop, easing(pos)) >> 0; 
     window.scrollTo(0, y); 
     if(now > finish) { 
      clearInterval(interval); 
     } 
     }, 10); 
} 

获取滚动根

var getScrollRoot = (function() { 
    var SCROLL_ROOT; 
    return function() { 
    if (!SCROLL_ROOT) { 
     var bodyScrollTop = document.body.scrollTop; 
     var docElScrollTop = document.documentElement.scrollTop; 
     window.scrollBy(0, 1); 
     if (document.body.scrollTop != bodyScrollTop) 
     (SCROLL_ROOT = document.body); 
     else 
     (SCROLL_ROOT = document.documentElement); 
     window.scrollBy(0, -1); 
    } 
    return SCROLL_ROOT; 
    }; 
})(); 
+0

谢谢,这是非常好的,但我不认为它考虑到文档的当前滚动位置,即如果你在页面的底部它不会向上滚动... – pstanton 2011-01-11 21:04:52

+0

是的,没错。实际上代码考虑了它,但它不是跨浏览器的。因为`document.body`并不总是滚动的根元素。添加了一个测试函数以及更新的测试页面(带有`#盒子下面的链接)。 – galambalazs 2011-01-11 21:34:56

2

这是一种替代方法,即使用了一些原型是内置的与视口和滚动尺寸一起工作的功能...

function scrollToCenterOfElement(id){ 
    // Cache element and property lookups... 

    var element = $(id); 
    var height = element.measure('height'); 
    var top = element.cumulativeOffset().top; 
    var scroll = document.viewport.getScrollOffsets(); 
    var dimensions = document.viewport.getDimensions(); 

    // Checks to see if the top offset plus the height of the element is greater 
    // than the sum of the viewport height and vertical scroll offset, which means 
    // that the element has yet to be fully scrolled in to view, or if the 
    // top offset is smaller than the vertical scroll offset, which means the element 
    // has already been (at least partly) scrolled out of view.. 

    if ((top + height > dimensions.height + scroll.top) || (top < dimensions.height + scroll.top)) { 

    // Scroll window to sum of top offset plus half the height of the element 
    // minus half of the viewport height, thus centering the element vertically. 
    window.scrollTo(0, top + (height/2) - (dimensions.height/2)); 

    } 

} 

scrollToCenterOfElement('my-element'); 
0

我的解决方案不会不覆盖要求的100%,但也许有人认为它有用。

/** 
* Scroll container so that given element becomes visible. Features: 
* <ol> 
* <li>If element is already visible, then no action is taken. 
* <li>If element is above view port, the viewport is scrolled upwards so that element becomes visible at the top. 
* <li>If element is below view port, the viewport is scrolled downwards so that element becomes visible at the bottom. 
* </ol> 
* 
* @param element 
*   optional string (selector) or jQuery object that controls the scrolling of the element 
* @param options 
*   optional extra settings 
* @param options.animationSpeed 
*   if defined, then scrolling is animated; determines time in milliseconds after which the element should 
*   be scrolled into viewport 
* @param options.heightScale 
*   double number from 0 to 1; when scrolling the element from bottom sometimes it is desirable to scroll 
*   element close to the top; e.g. to scroll it to the center specify 0.5; to scroll it to the top specify 0 
* @param options.complete 
*   function to be called after animation is completed; if there is no animation, the function is called straight away 
*/ 
$.fn.scrollTo = function(element, options) { 
    options = options || {}; 
    var elementTop = element.offset().top; 
    var containerTop = this.offset().top; 
    var newScrollTop = null; 

    if (elementTop < containerTop) { 
     // Scroll to the top: 
     newScrollTop = Math.round(this.scrollTop() + elementTop - containerTop); 
    } else { 
     // Scroll to the bottom: 
     var elementBottom = elementTop + element.outerHeight(true); 
     var containerHeight = this.height(); 

     if (elementBottom > containerTop + containerHeight) { 
      if (options.heightScale != null) { 
       if (options.heightScale === 0) { 
        // This will effectively turn the formulae below into "elementTop - containerTop": 
        containerHeight = element.outerHeight(true); 
       } else { 
        containerHeight *= options.heightScale; 
       } 
      } 

      newScrollTop = Math.round(this.scrollTop() + elementBottom - containerTop - containerHeight); 
     } 
    } 

    if (newScrollTop !== null) { 
     if (options && options.animationSpeed) { 
      this.animate({ 
       scrollTop : newScrollTop 
      }, { 
       "duration" : options.animationSpeed, 
       "complete" : options.complete 
      }); 
     } else { 
      this.scrollTop(newScrollTop); 

      if ($.isFunction(options.complete)) { 
       options.complete(); 
      } 
     } 
    } else { 
     if ($.isFunction(options.complete)) { 
      options.complete(); 
     } 
    } 

    return this; 
}; 

Demo

相关问题