2012-07-12 1 views
4

물론 scrollIntoViewIfNeeded는 WebKit에서만 제공하는 기능입니다. 그러나 나는 IE 7과 호환되어야 할 필요가있는 무언가를 위해 일하고 있는데, 뭔가 보이는지 여부를 감지하고, 그렇지 않으면 scrollIntoView()를 호출해야한다.IE7 용 scrollIntoViewIfNeeded()

전체 창을 다루지 않는다는 점에 유의해야합니다.보기 쉬운 상자에서 요소를 스크롤 할 수있는 더 작은 DIV를 처리 할 수 ​​있습니다.

예를 들어, id가 "pleaseFindMe"인 요소는 div의 표시 가능 영역 밖으로 오버 플로우 된 경우에만보기로 스크롤해야합니다.

<div style='border:1px solid black;width:40%; overflow:scroll;'> 
     <span id='e2' style='white-space: nowrap;' >Lorem ipsum aliqua proident veniam et quis consectetur esse dolore non Ut nulla dolor eu culpa. Lorem ipsum sint cupidatat non et adipisicing esse elit officia. proident, sunt in culpa qui officia deserunt mollit anim <span id='pleaseFindMe'>id est</span> laborum. </span> 
    </div> 

답변

6

IE는 IE4부터 아름다운 요소법 getBoundingClientRect을 지원하고있다. 그것이 IE < 8에 약간의 결함이 있지만, 그것은 당신의 목적을 위해 확실히 사용될 수 있습니다.

var findMe = document.getElementById("pleaseFindMe"), 
    contRect = container.getBoundingClientRect(), 
    findMeRect = findMe.getBoundingClientRect(); 
if (findMeRect.top < contRect.top || findMeRect.bottom > contRect.bottom 
     || findMeRect.right > contRect.right || findMeRect.left < contRect.left) 
    findMe.scrollIntoView(); 
2

체크 아웃 Github에서에이 polyfill :

그래서 여기에 트릭입니다. 비표준 WebKit 메서드 scrollIntoViewIfNeeded의 JavaScript 구현을 제공합니다.

+0

^권장 사항 - 다른 용도로 사용할 수있는 좋은 포크가 있으므로 GIST 의견을 읽어보십시오. – gdibble

8

이전 질문이지만 오늘의 브라우저 (IE, Fx)와는 여전히 관련이 있습니다. 그래서 scrollIntoViewIfNeeded()에 대해 polyfill을 작성했습니다.

if (!Element.prototype.scrollIntoViewIfNeeded) { 
    Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) { 
     function withinBounds(value, min, max, extent) { 
      if (false === centerIfNeeded || max <= value + extent && value <= min + extent) { 
       return Math.min(max, Math.max(min, value)); 
      } else { 
       return (min + max)/2; 
      } 
     } 

     function makeArea(left, top, width, height) { 
      return { "left": left, "top": top, "width": width, "height": height 
        , "right": left + width, "bottom": top + height 
        , "translate": 
         function (x, y) { 
          return makeArea(x + left, y + top, width, height); 
         } 
        , "relativeFromTo": 
         function (lhs, rhs) { 
          var newLeft = left, newTop = top; 
          lhs = lhs.offsetParent; 
          rhs = rhs.offsetParent; 
          if (lhs === rhs) { 
           return area; 
          } 
          for (; lhs; lhs = lhs.offsetParent) { 
           newLeft += lhs.offsetLeft + lhs.clientLeft; 
           newTop += lhs.offsetTop + lhs.clientTop; 
          } 
          for (; rhs; rhs = rhs.offsetParent) { 
           newLeft -= rhs.offsetLeft + rhs.clientLeft; 
           newTop -= rhs.offsetTop + rhs.clientTop; 
          } 
          return makeArea(newLeft, newTop, width, height); 
         } 
        }; 
     } 

     var parent, elem = this, area = makeArea(
      this.offsetLeft, this.offsetTop, 
      this.offsetWidth, this.offsetHeight); 
     while ((parent = elem.parentNode) instanceof HTMLElement) { 
      var clientLeft = parent.offsetLeft + parent.clientLeft; 
      var clientTop = parent.offsetTop + parent.clientTop; 

      // Make area relative to parent's client area. 
      area = area. 
       relativeFromTo(elem, parent). 
       translate(-clientLeft, -clientTop); 

      parent.scrollLeft = withinBounds(
       parent.scrollLeft, 
       area.right - parent.clientWidth, area.left, 
       parent.clientWidth); 

      parent.scrollTop = withinBounds(
       parent.scrollTop, 
       area.bottom - parent.clientHeight, area.top, 
       parent.clientHeight); 

      // Determine actual scroll amount by reading back scroll properties. 
      area = area.translate(clientLeft - parent.scrollLeft, 
            clientTop - parent.scrollTop); 
      elem = parent; 
     } 
    }; 
} 

http://jsfiddle.net/08u6cxwj/

이 코드는 중첩 스크롤 영역과 상대적으로 위치 결정 요소의 존재하에 사용할 수 있도록 설계된다.

+0

나는이 솔루션을 권장합니다. 그것은 조금 복잡해 보이지만 스크롤 컨테이너가 다른 솔루션과 달리 요소의 직접적인 부모가 아닐지라도 완벽하게 작동합니다. – Markos