ホームページ  >  記事  >  ウェブフロントエンド  >  javascript jscrollはHTML要素のスクロールバーをシミュレートします_javascriptスキル

javascript jscrollはHTML要素のスクロールバーをシミュレートします_javascriptスキル

WBOY
WBOYオリジナル
2016-05-16 17:46:171495ブラウズ

主流のブラウザーがデフォルトで HTML 要素に提供するスクロール バーは美しくなく、フロントエンド開発者が CSS を介して統一されたスタイルでスクロール バーを美しくすることは不可能です。たとえば、IE はスタイルを通じて単純な美化を実現できますが、Webkit カーネル ブラウザはスクロール バーの表示効果を制御できます。Firefox ではユーザーがスクロール バーのスタイルを定義できません。しかし、フレンドリーなユーザー エクスペリエンスを追求するフロントエンド開発者は、これらのブラウザーの一貫性のない動作によって妨げられることはありません。標準の HTML 要素シミュレーションを通じてカスタム スクロール バーを自分で実装できます。

これは、仕事があまり忙しくないときに書いたユーザー定義可能なスクロール バー jscroll (以下、jscroll と呼びます) です。デフォルトでは、jscroll は 1 つのスクロール バー スタイルのみを提供します。一部のスタイルは Google ウェブストアから提供されており、その一部は主に丸い角と影の効果を実現するために使用されます。ブラウザ間で一貫したスクロール バーの表示効果を実現するために、IE6、7、および 8 で CSS3 をサポートしていないブラウザ用に PIE.htc ファイルが導入されました。次に、実装されている機能、互換性、利用方法、具体的なコードの実装について説明します。

機能と互換性の実装

jscroll は、システムのデフォルトのスクロール バーのほぼすべての機能を実装します。たとえば、スクロール バーをドラッグしてコンテンツを表示する、マウス ホイールを回転してコンテンツを表示する、スクロール バーをクリックして領域の上部または下部に到達してトリガーするなどです。スクロール バーのスクロール、キーボードの上下キーでスクロール バーのスクロールをトリガーします。 Firefox、Chrome、IE9などの最新ブラウザはcss3やjsの最新APIに対応しているので互換性の問題はありません。 IE6、7、8はcss3をサポートしていません。互換処理のためにPIE.htcのハックファイルが導入されています。 js に関しては、サポートされていない API との互換性は古い API を通じて行われます。互換性に最も大きな問題があるブラウザは IE6 です。IE6 は、スクロール バーのスクロールをトリガーする領域に到達するためのスクロール バーのクリックをサポートしていません。また、スクロール バーのスクロールをトリガーするキーボードの上下キーもサポートしていません。この問題の主な原因は、css3 をサポートする PIE.htc ファイルの導入です。ハック ファイルが導入されていない場合、一貫した表示効果を得るには、一部の操作をサポートしないことを選択する必要があります。機能。

使用方法

カスタム スクロール バーの最も一般的な使用は、ページのポップアップ レイヤーまたはページ上の特定の領域で行う必要があります。ページ全体のスクロール バーをカスタマイズしないでください。 jscroll を使用する必要がある要素については、カスタム属性 data-scroll="true" を追加して、システムのデフォルトのスクロール バーを置き換えるために jscroll を使用する必要があることをプログラムに伝える必要があります。また、カスタム属性 data- も追加する必要があります。 width="", data-height="" は、表示する要素の幅と高さを指定します。 jscroll は、ユーザー定義の幅と高さに基づいてコンテンツの表示幅とスクロール バーの高さを計算し、インタラクティブなイベントを追加します。

詳細なコード実装

jscroll の実装ロジックは複雑ではありません。特定の機能を実装するための js コードは 400 行未満ですが、いくつかの基本的なメソッドに依存しているため、基本的なメソッドのサポートとしてsquid.jsを導入する必要があります。スクロール バーのスタイルを制御する CSS は、別の jscroll-1.0.css ファイルにあり、ユーザーは独自のニーズに合わせて変更および拡張できます。以下は、特定の機能を実現するための各メソッドの簡単な分析です:

コードをコピーします コードは次のとおりです:

init: function(selector, context) {
selector = selector || 'data-scroll'
context = context || ドキュメント

var elems = suck.getElementsByAttribute( selector, context)
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 element
create : function(elem) {
var Wrapper,
list,
//スクロールバー要素
s,
//スクロールバー要素で表示される高さ
height = elem[' data-height'] || elem.getAttribute('data-height'),
//スクロールバーのある要素の幅
width = elem['data-width'] | | elem.getAttribute(' data-width'),
//スクロールバー表示の高さ
値;

//wrapper
wrapper = document.createElement('div')
wrapper.className = ' jscroll-wrapper'
//ie9 の場合、テキストの選択を禁止
/*
* Wrapper.onselectstart = function() {
* return false
* }
*/
squid.css(wrapper, {
高さ: 高さ 'px',
幅: 幅 'px'
})

squid.addClass(elem, 'jscroll-body')
//ユーザー定義スタイルを上書きします
squid.css(elem, {
overflow: 'visible',
position: 'absolute',
height: ' auto',
width: (width - 40) 'px',
padding: '0 20px 0 23px'
})

//list
list = document.createElement ('div')
list.className = 'jscroll-list unselectable'
list.unselectable = 'on'
squid.css(list, {
高さ: (高さ - 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() メソッド ユーザーは、カスタム スクロール バーを使用して要素を作成する全体的な構造を調整します。まず、要素要素をラップするラッパー要素が作成されます。およびスクロール バーが表示される場所。 スクロール バーのスクロール可能領域要素リストとスクロール バー要素。スクロール バー要素から設定されたカスタム属性 data-width および data-height を使用して、ラッパー要素の幅と高さをそれぞれ設定します。スクロール バー要素によって表示される高さは、scrollerHeight() メソッドによって計算され、全体の構造は複雑ではありません。カスタム スクロール バーの全体的な構造を作成した後、スクロール バー要素 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 = events.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() メソッドは、ドキュメント要素にmousemoveおよびmouseupイベントを追加するために実行され、mousemoveは、アクティブ要素の起動時に表示されるコンテンツの変化を実現します。 ie6 では、現在、アクティブなストリップがコンテンツを閲覧しているかどうかの操作が行われ、その場合は、挿入された PIE.htc ファイルが破損しているため、そのコンテンツが閲覧されている場所が計算されます。元々あった構造(オーバービューカの下表示効果の一致を実現するために、大幅に追加しました!
复制代码代码如下:

//スクロールバーイベントを追加します
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 ブラウザ
firefox = 'MozBinding' in document.documentElement.style,
//マウスホイール イベント
マウスホイール = 'DOMMouseScroll' : 'mousewheel',
// opera ブラウザ
opera = window.oprea && navigator.userAgent.indexOf('MSIE') === -1,
//マウスダウン イベントを発生させます
firing = false,
/ /マウス クリック、タイマー実行時間
interval,
//コンテナからのスクロール バーの高さ
top,
//スクロール バーの現在の上部値
cur,
//毎回 ピクセル数スクロール
speed = 18;

//変数キャッシュ min, max
this.limits[s] = {
min: 0,
max: max
}
//スクロールイベント マウスホイールをスライドさせてスクロールバーを移動します
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 = cur - 速度
if(top トップ = 最小
}
}else{//下にスクロール
トップ = 速度
if(トップ > 最大) {
トップ = 最大
}
}
s.style.top = top 'px'
that.doScroll(sbody, top *unit)

//body要素のスクロールバーがスクロールしないようにします
event.preventDefault()
})

//ie6、7、8、マウスが 2 回連続してクリックされ、時間間隔が短すぎる場合、2 番目のイベントはトリガーされません
// スクロールをドラッグしますバーをクリックしてスクロールします。 到達可能な領域
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')){
firing = true
interval = setInterval( function() {
if(firering) {
that.mouseHandle(list, y, Unit)
}
}, 80)
}
})

//マウスがスクロールバーを放してスクロールを停止します
squid.on(list, 'mouseup', function() {
//invoke elem releaseCapture
s.releaseCapture && s.releaseCapture()

firing = 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 ) {
ケース 38:
top = cur - 速度
if(top < min) {
top = min
}
state = true
break
ケース 40:
top = cur 速度
if(top > max) {
top = max
}
state = true
break
default:
break
}
if(state) {
s.style.top = top 'px'
that.doScroll (sbody, top *unit)
}

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,
//到達可能なエリアの上部または下部までの距離スクロール バー上でマウスをクリックすると、スクロール バーが自動的に上部または下部に移動します。

min = this.limits[s].min
max = this.limits[s].max
height = s.offsetHeight
top = parseInt(s.style.top || 0, 10)
value = suck.getOffset(elem).top
sTop = suck.getOffset(s).top
//スクロールバーの下の領域をマウスでクリックすると、スクロールバーが下にスクロールします
if(place > sTop) {
if(値 elem.offsetHeight - 場所 < 距離 && (elem.offsetHeight - 高さ - 上部) < 距離) {
上部 = 最大
}else{
if((s上部の高さのステップ) <= 場所) {
top = step
}else{
top = 場所 - 値 - 高さ
}
}
}else {
//マウスのクリック領域が小さい場合スクロール バーの上部からスクロール バーの長さよりも長い場合、スクロール バーは自動的に上部までスクロールします
if(place - value < distance && top < distance) {
top = min
}else{
//ページの上部からマウス clientY の値を引いたスクロール バーの高さがステップより大きいです
if(sTop - place >= step) {
top -= step
}else {
top = 場所 - 値
}
}
}
if(top < min) {
top = min
}else if(トップ > 最大) {
トップ = 最大
}

s.style.top = トップ 'px'
this.doScroll(a, トップ * ユニット)
}

mouseHandle() メソッドは、ページ上のマウスクリック位置とスクロールバー要素の位置座標を判断して、スクロールバーの上部領域がクリックされたか下部領域がクリックされたかを判定します。ページ。下の領域をクリックするとスクロール バーが下にスクロールし、それ以外の場合は上にスクロールします。クリックされた位置が上の領域にある場合、または下の領域が距離値未満の場合は、スクロール バーは最小値または最大値まで自動的にスクロールします。

表示効果

このコントロールのデモは、淘宝網のユーザー登録規約の内容を使用しています。Firefox や Chrome などの高度なブラウザは良好な互換性と表示効果を保証できるため、ここでは低バージョンの IE ブラウザの表示効果のみを示します。デバイス表示のスクリーンショットは次のとおりです:

IE6 未満

初期化後

スクロール中

一番下までスクロールします

ie7

スクロールバーの初期化後

スクロール中

一番下までスクロールします

ie9

スクロールを始める前に

スクロール中

一番下までスクロールします

概要: 基本的な関数の実装コードは非常に多く、分析が十分に詳細に行われていない可能性があります。最も複雑なものは、位置の計算とイベントのバインディング処理です。質問がある場合は、一緒にコミュニケーション、学習、交換することを歓迎します。

: PIE.htc ファイルへのパスは正しく配置する必要があり、引用するときに絶対パスを記述する必要があります。そうしないと、ie6、7、および 8 では css3 効果がありません (その場合、コードで行われる互換性処理は意味がありません!)、参照パスを変更する必要がある場合は、jscroll-1.0.css ファイルで変更できます。最後にソースコードを添付しますので、興味のある方はダウンロードして試してみてください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。