> 웹 프론트엔드 > JS 튜토리얼 > javascript jscroll은 html 요소 스크롤 bar_javascript 기술을 시뮬레이션합니다.

javascript jscroll은 html 요소 스크롤 bar_javascript 기술을 시뮬레이션합니다.

WBOY
풀어 주다: 2016-05-16 17:46:17
원래의
1508명이 탐색했습니다.

주류 브라우저에서 HTML 요소에 대해 기본적으로 제공하는 스크롤 막대는 아름답지 않으며 프런트엔드 개발자가 CSS를 통해 통일된 스타일로 아름답게 만드는 것은 불가능합니다. 예를 들어 IE는 스타일을 통해 간단한 미화를 달성할 수 있으며 Webkit 커널 브라우저는 스크롤 막대의 표시 효과를 제어할 수 있습니다. Firefox에서는 사용자가 스크롤 막대의 스타일을 정의하는 것을 허용하지 않습니다. 그러나 친숙한 사용자 경험을 추구하는 프런트 엔드 개발자는 이러한 브라우저의 일관되지 않은 동작으로 인해 중단되지 않습니다. 표준 HTML 요소 시뮬레이션을 통해 사용자 정의 스크롤 막대를 직접 구현할 수 있습니다.

다음은 제가 회사에서 너무 바쁘지 않을 때 작성한 사용자 정의 가능한 스크롤 막대 jscroll입니다. 이하 jscroll이라고 합니다. 기본적으로 jscroll은 하나의 스크롤 막대 스타일만 제공합니다. 일부 스타일은 Google 웹 스토어에서 가져온 것이며, 그 중 일부는 주로 둥근 모서리와 그림자 효과를 얻는 데 사용됩니다. 여러 브라우저에서 일관된 스크롤 막대 표시 효과를 얻기 위해 IE6, 7 및 8에서 CSS3을 지원하지 않는 브라우저에 PIE.htc 파일이 도입되었습니다. 다음으로 구현된 기능, 호환성, 사용 방법, 구체적인 코드 구현에 대해 설명하겠습니다.

기능 및 호환성 구현

jscroll은 시스템 기본 스크롤 막대의 거의 모든 기능을 구현합니다. 예를 들어 스크롤 막대를 드래그하여 콘텐츠 보기, 마우스 휠을 굴려 콘텐츠 보기, 스크롤 막대를 클릭하여 트리거할 영역의 상단 또는 하단에 도달 스크롤 막대 스크롤, 키보드 위쪽 및 아래쪽 키를 사용하여 스크롤 막대 스크롤을 트리거합니다. firefox, chrome, ie9 등 최신 브라우저는 css3, js의 최신 API를 지원하므로 호환성 문제는 없습니다. IE6, 7, 8에서는 css3을 지원하지 않습니다. 호환성 처리를 위해 PIE.htc의 해킹 파일이 도입되었습니다. js의 경우 지원되지 않는 API와의 호환성은 기존 API를 통해 이루어집니다. 호환성 문제가 가장 큰 브라우저는 IE6입니다. 스크롤 막대를 클릭하여 해당 영역에 도달하는 것을 지원하지 않으며, 스크롤 막대를 트리거하기 위해 키보드의 위쪽 및 아래쪽 키를 지원하지 않습니다. 이 문제의 주된 원인은 css3을 지원하는 PIE.htc 파일의 도입입니다. hack 파일이 도입되지 않으면 모든 작업이 지원될 수 있지만 일관된 표시 효과를 가지려면 일부를 지원하지 않도록 선택해야 합니다. 기능.

사용방법

사용자 정의 스크롤 막대는 페이지의 팝업 레이어나 페이지의 특정 영역에서 가장 일반적으로 사용됩니다. 전체 페이지의 스크롤 막대를 사용자 정의하지 마십시오. jscroll을 사용해야 하는 요소의 경우 사용자 정의 속성 data-scroll="true"를 추가하여 시스템 기본 스크롤 막대를 대체하기 위해 jscroll을 사용해야 함을 프로그램에 알려야 합니다. 또한 사용자 정의 속성 data-를 추가해야 합니다. width="", data- height="" 표시할 요소의 너비와 높이를 지정합니다. jscroll은 사용자 정의 너비와 높이를 기반으로 콘텐츠의 표시 너비와 스크롤 막대의 높이를 계산하고 대화형 이벤트를 추가합니다.

세부 코드 구현

jscroll의 구현 로직은 복잡하지 않습니다. 특정 기능을 구현하는 js 코드는 400줄 미만이지만 일부 기본 메서드에 의존하므로 기본 메서드 지원으로 squid.js를 도입해야 합니다. 스크롤 막대 스타일을 제어하는 ​​CSS는 별도의 jscroll-1.0.css 파일에 있습니다. 사용자는 자신의 필요에 맞게 이를 수정하고 확장할 수 있습니다. 다음은 특정 기능을 달성하기 위한 각 방법에 대한 간단한 분석입니다.

코드 복사 코드는 다음과 같습니다.

init: function(selector, context) {
selecotr = 선택기 || 'data-scroll'
context = context || document

var elems = squid.getElementsByAttribute( 선택기, 컨텍스트)
this.initView(elems)
}

init()는 지정된 선택기를 기반으로 사용자 정의 스크롤 막대를 사용해야 하는 요소를 가져옵니다. 및 컨텍스트 기본 선택기는 data -scroll이고 컨텍스트는 현재 문서로 기본 설정됩니다. 여기서 요소의 사용자 정의 속성 data-scroll="true" 또는 data-scroll="false"에 관계없이 사용자 정의 스크롤 막대는 시스템 기본 스크롤 막대를 덮어쓰는 데 사용됩니다. Squid의 getElementsByAttribute() 메서드는 찾기 기능만 제공합니다. 요소가 속성을 지정했는지 여부에 따라 요소를 기반으로 합니다. 속성 값을 무시하면 Squid는 여기서 가장 기본적인 지원만 제공하기 때문에 고급 브라우저에서 제공되는 jquery 선택기 또는 querySelectorAll() 메서드만큼 강력하지 않습니다. 커스터마이징이 필요한 요소를 찾은 후 initView 메소드를 호출하여 스크롤바의 전체 구조와 표시를 초기화합니다.
코드 복사 코드는 다음과 같습니다.

initView: function(elems) {
var i = 0,
length = elems.length,
elem;

for(; i < length; i ) {
elem = elems[i]
if (this.haScroll(elem)) {
this.create(elem)
}
}

this.initEvent()
}

initView() 메소드는 먼저 페이지에서 얻은 사용자 정의 속성 data-scroll을 사용하여 요소를 순회한 후 hasScroll() 메소드를 통해 각 요소에 스크롤 막대가 나타날지 여부를 결정합니다. 요소에 스크롤 막대가 나타나면 create() 메서드를 호출하여 각각 사용자 정의 스크롤 막대를 만듭니다. initView() 메서드가 종료되면 initEvent() 메서드가 호출됩니다.
코드 복사 코드는 다음과 같습니다.

//스크롤바 유무
hasScroll: function (elem) {
return elem.offsetHeight < elem.scrollHeight
}

hasScroll() 메서드는 스크롤 막대가 화면에 나타날지 여부를 결정하는 데 사용됩니다. 요소를 입력하고 true 또는 false를 반환합니다. 여기서는 요소의 여백과 패딩이 무시됩니다. jscroll을 통해 생성된 스크롤 막대의 기본 여백과 패딩은 모두 0입니다.
코드 복사 코드는 다음과 같습니다.

//스크롤의 전체 구조를 만듭니다. bar 요소
create : function(elem) {
var Wrapper,
list,
//스크롤 막대 요소
s,
//스크롤 막대 요소와 함께 표시되는 높이
height = elem[' data-height'] || elem.getAttribute('data-height'),
//스크롤 막대가 있는 요소의 너비
width = elem['data-width'] | | elem.getAttribute(' data-width'),
//스크롤 막대 표시 높이
value

//wrapper
wrapper = document.createElement('div')
wrapper.className = ' jscroll-wrapper'
//ie9의 경우 선택 텍스트 금지
/*
* Wrapper.onselectstart = function() {
* return false
* }
*/
squid.css(wrapper, {
height: height 'px',
width: width 'px'
})

squid.addClass(elem, 'jscroll-body')
//사용자 정의 스타일 덮어쓰기
squid.css(elem, {
overflow: 'visible',
position: 'absolute',
height: ' auto',
너비: (너비 - 40) 'px',
padding: '0 20px 0 23px'
})

//list
list = document.createElement ('div')
list.className = 'jscroll-list unselectable'
list.unselectable = 'on'
squid.css(list, {
height: (height - 5) ' px'
} )

//스크롤 막대
s = document.createElement('div')
s.className = 'jscroll-drag unselectable'
s.unselectable = 'on'
s.setAttribute('tabindex', '1')
s.setAttribute('hidefocus', true)

list.appendChild(s)
wrapper.appendChild( list)
/ /스크롤 막대를 표시해야 하는 요소 래핑
elem.parentNode.replaceChild(wrapper, elem)
wrapper.insertBefore(elem, list)

//스크롤 막대 height
value = this.scrollbarHeight(elem, height)
squid.css(s, {
height: value 'px'
})

//이벤트 추가
this.regEvent(wrapper )
}

create() 메소드 사용자는 사용자 정의 스크롤 막대를 사용하여 요소 생성의 전체 구조를 조정합니다. 먼저 요소 elem을 래핑하기 위해 래퍼 요소가 생성됩니다. 스크롤 막대가 표시되는 위치. 스크롤 막대 스크롤 가능 영역 요소 목록 및 스크롤 막대 요소 s. 스크롤 막대 요소에서 설정된 사용자 정의 속성 data-width 및 data-height를 통해 래퍼 요소의 너비와 높이를 각각 설정합니다. 스크롤바 요소가 표시하는 높이는 scrollbarHeight() 메소드를 통해 계산되며 전체적인 구조는 복잡하지 않습니다. 사용자 정의 스크롤 막대의 전체 구조를 생성한 후 스크롤 막대 요소 s 및 스크롤 막대 도달 가능 영역 요소 목록에 대한 이벤트 처리를 추가합니다. 이는 regEvent() 메서드를 통해 구현됩니다.
코드 복사 코드는 다음과 같습니다.

//스크롤 막대 높이 계산
scrollbarHeight: function(elem, height) {
var value = elem.scrollHeight;

return(높이 / 값) * 높이
}

scrollbarHeight () 메소드가 간단히 전달됩니다. 수학적 계산은 스크롤 막대 요소가 표시해야 하는 높이를 반환합니다.
코드 복사 코드는 다음과 같습니다.

initEvent: function() {
var that = this,
_default,
elem,
top,
min,
max,
prev,
부모,
몸,
단위;

//滚动条滚动
squid.on(document, 'mousemove', function(event) {
elem = that.scrolling.elem
if(elem !== null) {
squid.addClass(elem, 'scrolling')
top = event.clientY - that.scrolling.diffy
parent = that.ie6 ? elem.parentNode.parentNode : elem.parentNode
min = that.limits[elem].min
max = that.limits[elem].max
prev = parent.previousSibling
sbody = prev.tagName.toLowerCase() === 'div' ? : prev.previousSibling
_default =parseInt(sbody['data-height'] || sbody.getAttribute('data-height'), 10)
unit = (sbody.scrollHeight - _default) / max

squid.addClass(sbody.parentNode, 'unselectable')
if(top < min) {
top = min
}else if(top > max) {
top = max
}
elem.style.top = top 'px'
that.doScroll(sbody, top *unit)
}
})

//滚动结束
squid.on(document, 'mouseup', function(event) {
elem = that.scrolling.elem
if(elem) {
prev = that.ie6 ? elem.parentNode. parentNode.previousSibling : elem.parentNode.previousSibling
sbody = prev.tagName.toLowerCase() === 'div' ? prev : prev.previousSibling
squid.removeClass(sbody.parentNode, 'unselectable')
}

that.scrolling.elem = null
that.scrolling.diffy = 0
})
}

initEvent()방법법实现了为document素添加mousemove 및 mouseup사건,mousemove实现了에서 拖动滚动条元素滚动时查看的内容跟随变化。代码首先判断当前是否有拖动滚动条查看内容计算滚动条被拖动到的位置,然后计算查看内容应该멋진 장소.了원유의 结构(为了实现跨浏览器下显示效果的一致,付ude大了!!!)素。
复主代码 代码如下:

//스크롤바 이벤트 추가
regEvent: function(elem) {
var that = this,
sbody = elem.firstChild,
list = sbody.nextSibling,
//스크롤바 요소
s = list.firstChild,
//스크롤바 스크롤 최소값
min = 0,
//스크롤바 스크롤 최대값
max = list.offsetHeight - s.offsetHeight,
_default =parseInt(sbody['data-height'] || sbody.getAttribute('data-height'), 10),
unit = (sbody.scrollHeight - _default) / max ,
//firefox browser
firefox = document.documentElement.style의 'MozBinding',
//mousewheel event
mousewheel = firefox ? 'DOMMouseScroll' : 'mousewheel',
// Opera browser
opera = window.oprea && navigator.userAgent.indexOf('MSIE') === -1,
//mousedown 이벤트 발생
fireing = false,
/ /마우스 클릭 , 타이머 실행 시간
간격,
//컨테이너의 스크롤 막대 높이
top,
//스크롤 막대 현재 최고 값
cur,
//매번 몇 픽셀까지 스크롤
속도 = 18;

//변수 캐시 최소, 최대
this.limits[s] = {
최소: 0,
최대: 최대
}
//scroll 이벤트 마우스가 휠을 밀어 스크롤 막대를 이동합니다.
squid.on(elem, mousewheel, function(event) {
var delta;

if(event.wheelDelta) {
delta = Opera ? -event.wheelDelta / 120 : event.wheelDelta / 120
}else{
delta = -event.detail / 3
}

cur = parseInt( s .style.top || 0, 10)
//위로 스크롤
if(delta > 0) {
top = 현재 - 속도
if(top < min) {
top = min
}
}else{//아래로 스크롤
top = 현재 속도
if(top > max) {
top = max
}
}
s.style.top = top 'px'
that.doScroll(sbody, top *unit)

//본문 요소 스크롤 막대의 스크롤 방지
event.preventDefault()
})

//ie6, 7, 8, 마우스를 연속으로 두 번 클릭하고 시간 간격이 너무 짧은 경우 두 번째 이벤트가 발생하지 않습니다.
//스크롤 드래그 표시줄을 클릭하여 도달 가능한 영역
squid.on(list, 'mousedown', function(event) {
var target = event.target,
y = event.clientY;

target = event .target
if(target.tagName.toLowerCase() === 'shape')
target = s

//마우스로 클릭한 요소는 스크롤 막대
if(target === s) {
//invoke elem setCapture
s.setCapture && s.setCapture()

that.scrolling.diffy = y - s.offsetTop
//마우스 이동 중 판단 스크롤 막대가 드래그되는지 여부
that.scrolling.elem = s
}else if(target.className.match('jscroll-list')){
fireing = true
interval = setInterval( function() {
if(firing) {
that.mouseHandle(list, y, unit)
}
}, 80)
}
})

//마우스가 스크롤 막대를 놓아 스크롤을 중지합니다
squid.on(list, 'mouseup', function() {
//invoke elem releaseCapture
s.releaseCapture && s.releaseCapture()

fireing = false
clearInterval(interval)
})

//스크롤 막대 요소가 포커스를 얻고 키업 이벤트를 트리거할 수 있습니다
squid.on(s, 'click', function () {
this.focus()
})

//스크롤 막대가 포커스를 얻은 후 스크롤 막대에서 위쪽 및 아래쪽 키를 트리거합니다. 키보드, 스크롤 막대는
squid.on(s, 'keydown' , function(event) {
var keyCode = event.keyCode,
state = false;

cur =를 스크롤합니다. parseInt(s.style.top || 0, 10)
switch(keyCode ) {
case 38:
top = cur - 속도
if(top < min) {
top = min
}
state = true
break
사례 40:
top = 현재 속도
if(top > max) {
top = max
}
state = true
break
default:
break
}
if(state) {
s.style.top = top 'px'
that.doScroll (sbody, top * 단위)
}

event.preventDefault()
})
}

regEvent() 메소드는 다음 기능을 구현하며, jscroll 구성 요소의 핵심 메서드가 됩니다.

1. 스크롤바가 포함된 요소 영역에 마우스가 있을 때 마우스 휠을 위아래로 굴리면 콘텐츠가 스크롤 휠을 따라 위아래로 움직입니다

2. 스크롤 막대를 클릭하면 해당 영역, 즉 스크롤 막대 위 또는 아래에 도달할 수 있으며, 스크롤 막대와 표시된 콘텐츠가 위 또는 아래로 스크롤될 수 있습니다. 마우스가 스크롤 막대를 클릭하면 놓지 않고도 해당 영역에 도달할 수 있으며, 스크롤 막대와 표시된 내용을 계속해서 스크롤할 수 있습니다. 이 기능은 구체적으로 mouseHandle() 메서드를 호출하여 구현됩니다.

3. 스크롤 막대 요소를 클릭한 후 키보드의 위쪽 및 아래쪽 키를 사용하여 스크롤 막대를 실행하고 콘텐츠를 스크롤할 수 있습니다.

코드 복사코드는 다음과 같습니다.

//마우스가 스크롤 막대를 클릭하여 해당 영역의 상단이나 하단에 도달하면 스크롤 막대가 스크롤됩니다.
mouseHandle: function(elem, place, unit) {
var prev = elem.previousSibling,
//스크롤 막대 표시 콘텐츠 요소 포함
a = prev.tagName.toLowerCase() === 'div' ? prev : prev.previousSibling,
//
n = elem.firstChild,
//스크롤 막대 요소
s = this.ie6 ? n.lastChild : n.tagName.toLowerCase() === 'div' ? n : n.nextSibling,
// 스크롤 막대 높이
height ,
//본문에서 목록 요소의 최상위 값
value,
//컨테이너에서 스크롤 막대의 높이
top,
//본체에서 스크롤바의 상단값
sTop,
//스크롤바 스크롤 최소값
min,
//스크롤바 스크롤 최대값
max,
//스크롤바를 클릭하여 해당 영역에 도달할 때마다 스크롤바가 10px씩 아래 또는 위로 이동합니다.
step = 10,
//도달 가능한 영역의 상단 또는 하단까지의 거리가 스크롤 막대에서 마우스를 클릭하면 스크롤 막대가 자동으로 위쪽 또는 아래쪽으로 이동할 수 있습니다.
distance = 20
min = this.limits[s].min
max; = this.limits[s].max
height = s.offsetHeight
top = parseInt(s.style.top || 0, 10)
value = squid.getOffset(elem).top
sTop = squid.getOffset(s).top
//스크롤 바 아래 영역을 마우스로 클릭하면 스크롤 바가 아래로 스크롤됩니다
if(place > sTop) {
if( value elem.offsetHeight - place < distance && (elem.offsetHeight - height - top) < distance) {
top = max
}else{
if((sTop height step) <= place ) {
top = 단계
}else{
top = 위치 - 값 - 높이
}
}
}else {
//마우스 클릭 영역이 작은 경우 스크롤바 상단에서 스크롤바의 길이보다 스크롤바가 자동으로 위로 스크롤됩니다.
if(place - value < distance && top < distance) {
top = min
}else{
//페이지 상단의 스크롤 막대 높이에서 마우스 clientY 값을 뺀 값이 step보다 큽니다.
if(sTop - place >= step) {
top -= step
}else {
top = 장소 - 값
}
}
}
if(top < min) {
top = min
}else if( top > max) {
top = max
}

s.style.top = top 'px'
this.doScroll(a, top * 단위)
}

mouseHandle() 메서드는 페이지에서 마우스 클릭 위치의 위치 좌표와 스크롤 막대 요소의 위치를 ​​판단하여 스크롤 막대의 위쪽 영역 또는 아래쪽 영역을 클릭했는지 여부를 결정합니다. 페이지. 아래쪽 영역을 클릭하면 스크롤 막대가 아래로 스크롤되고, 그렇지 않으면 위로 스크롤됩니다. 클릭한 위치가 위쪽 영역에 있거나 아래쪽 영역이 거리 값보다 작을 경우 스크롤 막대는 자동으로 최소 또는 최대 값으로 스크롤됩니다.

디스플레이 효과

이 컨트롤의 데모는 Taobao 사용자 등록 계약 내용을 사용합니다. Firefox 및 Chrome과 같은 고급 브라우저는 우수한 호환성 및 디스플레이 효과를 보장할 수 있으므로 낮은 버전의 IE 브라우저의 디스플레이 효과만 여기에 표시됩니다. 장치 디스플레이의 스크린샷은 다음과 같습니다.

ie6 아래

초기화 후

스크롤하는 동안

하단으로 스크롤

ie7

스크롤바 초기화 후

스크롤하는 동안

하단으로 스크롤

ie9

스크롤을 시작하기 전에

스크롤하는 동안

하단으로 스크롤

요약: 기본 기능 구현 코드가 너무 많아서 분석이 충분히 상세하지 않을 수 있습니다. 가장 많이 관련된 것은 위치 계산 및 이벤트 바인딩 처리일 수 있습니다. 궁금한 점이 있으면 함께 소통하고 배우고 교류할 수 있습니다.

참고: PIE.htc 파일의 경로는 올바르게 배치해야 하며 인용 시 절대 경로를 작성해야 합니다. 그렇지 않으면 ie6, 7, 8(in)에서 CSS3 효과가 없습니다. 이 경우 내 코드에서 수행된 호환성 처리는 의미가 없습니다!), 참조 경로를 변경해야 하는 경우 jscroll-1.0.css 파일에서 수정할 수 있습니다. 마지막으로 소스 코드가 첨부되어 있으니 관심 있는 분들은 다운로드하여 사용해 보시기 바랍니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿