この記事の例では、カスタムスクロールバーコンポーネントを実装するためのjsの具体的なコードを参考までに共有しています。具体的な内容は次のとおりです。 機能要件: 1. データ構造に従ってメニューコンテンツを作成し、ページに表示します。 効果を見てみましょう: デフォルトの状態: メニューをクリックすると、コンテンツがオーバーフローした後にスクロール バーが表示されます。 マウスでスクロール バーをドラッグすると、コンテンツ全体が上にスクロールします。 分析:
コードは以下に添付されています: HTML 構造、データのシミュレート、外部コンテナーの作成: <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <meta name="viewport" content="width=デバイス幅、初期スケール=1.0"> <title>スクロールバー</title> </head> <本文> <スクリプトタイプ="モジュール"> './js/Utils.js' から Utils をインポートします。 './js/Menu.js' からメニューをインポートします。 './js/ScrollBar.js' から ScrollBar をインポートします。 var arr = [ {名前:"A",カテゴリ:[ {名前:"アウディ",カテゴリ:[ {name:"アウディ A3",href:""}, {名前:"アウディ A4L",カテゴリ:[ {name:"アウディ A4L-1",href:""} ]}, {name:"アウディ Q3",href:""}, {name:"アウディ Q5L",href:""}, {name:"アウディ Q2L",href:""}, {name:"Audi Q7 (輸入車)",href:""}, {name:"Audi Q8 (輸入車)",href:""}, {name:"アウディ Q7 ニューエナジー",href:""}, ]}, {名前:"アルファロメオ",カテゴリ:[ {name:"ステルヴィオ(輸入品)",href:""}, {name:"Giulia (輸入)",href:""}, ]} ]}, {名前:"B",カテゴリ:[ {name:"メルセデス・ベンツ",カテゴリー:[ {name:"メルセデスベンツ Cクラス",href:""}, {name:"メルセデスベンツ Eクラス",href:""}, {name:"メルセデスベンツ GLA クラス",href:""}, {name:"メルセデスベンツ GLC クラス",href:""}, {name:"メルセデスベンツ Aクラス",href:""}, {name:"メルセデスベンツ Eクラス (輸入車)",href:""}, {name:"メルセデスベンツ Aクラス(輸入車)",href:""}, {name:"メルセデスベンツ Bクラス(輸入車)",href:""}, {name:"威霆",href:""}, {name:"メルセデスベンツ Vクラス",href:""}, ]}, {名前:"BMW",カテゴリー:[ {name:"BMW 5 シリーズ",href:""}, {name:"BMW 1 シリーズ",href:""}, {名前:"BMW X1",href:""}, {name:"BMW X5 (輸入車)",href:""}, {name:"BMW X6 (輸入車)",href:""}, ]}, {名前:"ホンダ",カテゴリー:[ {name:"ジンルイ",href:""}, {name:"シビック",href:""}, {name:"ホンダ CR-V",href:""}, {name:"ホンダ XR-V",href:""}, {name:"ホンダ UR-V",href:""}, {name:"エリシオン",href:""}, {name:"翔宇",href:""}, {name:"INSPIRE",href:""}, {name:"リンパイ",href:""}, {name:"アコード",href:""}, {name:"ビンジ",href:""}, ]}, {name:"ビュイック",カテゴリー:[ {name:"カイル",href:""}, {name:"英朗",href:""}, {name:"威朗",href:""}, {name:"YueLang",href:""}, {name:"リーガル",href:""}, {name:"ラクロス",href:""}, {name:"アンコラ",href:""}, {name:"Envision",href:""}, {name:"ビュイック GL8",href:""}, {name:"ビュイック GL6",href:""}, {name:"VELITE",href:""}, ]} ]} ] var コンテナ; 初期化(); 関数init(){ メニューを作成します(arr); スクロールバーを作成します。 } 関数createMenu(arr){ //メニューを作成します。let menu=new Menu(arr); //最も外側のコンテナを作成する container=Utils.createE("div",{ 幅:"235px", 高さ:"360ピクセル", 境界線:"1px 実線 #ccc", 位置:"相対", オーバーフロー:"非表示" }) menu.appendTo(コンテナ); Utils.appendTo(コンテナ、"本体") } 関数createScrollBar(){ //スクロールバーを作成します。let scrollBar=new ScrollBar(container); scrollBar.appendTo(コンテナ); } </スクリプト> </本文> </html> Menu.js ファイルは、データに従って折りたたみメニュー コンテンツを作成します。 './Utils.js' から Utils をインポートします。 デフォルトクラスMenuをエクスポートする{ 静的 SET_BAR_HEIGHT="set_bar_height"; 静的 MOUSE_WHEEL_EVENT="マウスホイールイベント"; コンストラクタ(_list){ this.elem = this.createElem(_list); } 要素を作成します(_list){ if(this.elem) は this.elem を返します。 //最も外側のulコンテナを作成する let ul=Utils.createE("ul",{ リストスタイル:"なし", パディング:"0px", マージン:"0px", 幅:"235px", 高さ:"360ピクセル", 色:"#333", フォントサイズ:"14px", ユーザー選択: "なし", 位置:"絶対" }); // li リストを作成します this.createMenu(_list,ul); //ul はクリック イベントをリッスンします ul.addEventListener("click",e=>this.clickHandler(e)); //ul はスクロールホイールイベントをリッスンします。Firefox は DOMMouseScroll を使用し、他のブラウザは mousewheel を使用します。 ul.addEventListener("マウスホイール",e=>this.mouseWheelHandler(e)); ul.addEventListener("DOMMouseScroll",e=>this.mouseWheelHandler(e)); ul を返します。 } 親に追加{ Utils.appendTo(this.elem,parent); } //第一レベルのメニューを作成する createMenu(_list,parent){ for(let i=0;i<_list.length;i++){ li = Utils.createE("li",{ 背景:"#f5f5f5", borderTop:"1px 実線 #ddd", 行の高さ:"32px", },{ data:1, //クリックして最初のレベルのメニューが折りたたまれるのを制御します}) span = Utils.createE("span",{ 左余白:"14px", フォントサイズ:"18px" },{ テキストコンテンツ:_list[i].name }) Utils.appendTo(span,li); Utils.appendTo(li,親); //サブメニューを作成します。3 番目のパラメータはサブメニューを表示するかどうかを制御します。this.createSubMenu(_list[i].category,li,0); } } //サブメニューを作成する createSubMenu(_subList,_parent,_index){ //サブメニューがない場合はジャンプします if(_subList.length===0) return; subUl=Utils.createE("ul",{ リストスタイル:"なし", 背景:"#fff", パディング:"0px", マージン:"0px", フォントサイズ:"14px", display:_index===0? "ブロック" : "なし" }) for(let i=0;i<_subList.length;i++){ subLi=Utils.createE("li",{ パディング左:"40px", 位置:"相対", カーソル:"ポインタ" }) if(!_subList[i].category){ //現在のメニューにサブメニューがない場合は、ジャンプするタグを作成します。let subA=Utils.createE("a",{ 色:"#333", テキストデコレーション:"なし", 幅:"100%", 表示:"インラインブロック" },{ テキストコンテンツ:_subList[i].name、 href:_subList[i].href || "javascript:void(0)", ターゲット:_subList[i].href ? "_blank" : "_self" }) Utils.appendTo(subA、subLi); }それ以外{ //現在のメニューにサブメニューがある場合は、span タグを作成します。let subSpan=Utils.createE("span",{ 位置:"絶対", 左:"20px", 上:"8px", 境界線: "1px 実線 #ccc", 表示: "インラインブロック", 幅: "10px", 高さ: "10px", 行の高さ:"8px" },{ textContent:_subList[i].category.length>0? "+" : "-" }) subLi.textContent=_subList[i].name; Utils.appendTo(subSpan、subLi); } Utils.appendTo(subLi,subUl); //現在のメニューにサブメニューがない場合は、次の実行をスキップします。if(!_subList[i].category) continue; //現在のメニューのサブメニューをパラメータとして使用し、再帰を実行します。this.createSubMenu(_subList[i].category,subLi,1); } Utils.appendTo(subUl、_parent); } クリックハンドラ(e){ //現在のクリックが li タグまたは span でない場合は、直接ジャンプします if(e.target.nodeName!=="LI" && e.target.nodeName!=="SPAN") return; ターゲットにします。 e.target.nodeName==="SPAN" の場合、 targ=e.target.parentElement; そうでない場合、targ=e.target; //現在のクリック Li の下にサブメニューがない場合、直接ジャンプします if(targ.children.length<=1) return; //現在のクリックが第 1 レベルのメニューの場合は、直接ジャンプします if(targ.data===1) return; //現在クリックされている Li の下の ul の表示と非表示を制御します if(!targ.bool) targ.lastElementChild.style.display="block"; それ以外の場合は、targ.lastElementChild.style.display="none"; targ.bool = !targ.bool; //span タグの内容を変更します this.changeSpan(targ); //スクロール バーの高さを変更するイベントをスローします。var evt = new Event (Menu.SET_BAR_HEIGHT); ドキュメント.dispatchEvent(evt) } changeSpan(要素){ if(elem.lastElementChild.style.display==="block"){ 要素.firstElementChild.textContent="-"; }それ以外{ 要素.firstElementChild.textContent="+"; } } マウスホイールハンドラ(e){ //イベントのバブリングを停止します e.stopPropagation(); //Firefox は e.detail をチェックします。e.detail<0 の場合、ホイールが下がっていてページが上がっていることを意味します。let tag=e.detail,wheelDir; //他のブラウザは e.deltaY を判断します。e.deltaY<0 の場合、スクロールホイールが下がっていてページが上がっていることを意味します。if(tag===0) tag=e.deltaY; if(タグ>0){ //ホイールが下にスクロールし、ページが上に移動します wheelDir="down"; }それ以外{ wheelDir="上"; } //イベントをスローし、スクロールホイールの方向を渡します。let evt = new Event(Menu.MOUSE_WHEEL_EVENT); evt.wheelDirection=ホイール方向; this.elem.dispatchEvent(evt); } } ScrollBar.js ファイルを使用して、スクロール バーを作成し、スクロール バーを操作します。 './Utils.js' から Utils をインポートします。 './Menu.js' からメニューをインポートします。 デフォルトクラスScrollBarをエクスポートします。 バー; コンハイト; メニューの高さ; ホイールスピード=6; バートップ=0; 静的 SET_BAR_HEIGHT="set_bar_height"; コンストラクタ(親) { this.container = 親; this.menuUl = this.container.firstElementChild; this.elem = this.createElem(); //メニューのクリック イベントをリッスンし、スクロール バーの高さを動的に変更します。document.addEventListener(ScrollBar.SET_BAR_HEIGHT,()=>this.setBarHeight()); //ul メニューはホイール イベントをリッスンします this.menuUl.addEventListener(Menu.MOUSE_WHEEL_EVENT,e=>this.mouseWheelHandler(e)); } 要素を作成します(){ if (this.elem) は this.elem を返します。 //スクロールバーの外側のコンテナを作成する let div = Utils.createE("div", { 幅: "8px", 高さ: "100%", 位置: "絶対"、 右: "0px", 上: "0px", }) div を作成します。 div を返します。 } 追加先(親) { Utils.appendTo(this.elem,parent); } 作成バー(_parent) { if(this.bar) は this.bar を返します。 //スクロールバーを作成する this.bar = Utils.createE("div", { 幅: "100%", 位置: "絶対"、 左: "0px", 上: "0px", 境界半径: "10px", 背景色: "rgba(255,0,0,.5)" }) //スクロールバーのホバー状態のスタイルを設定します。this.bar.addEventListener("mouseenter",e=>this.setMouseStateHandler(e)); this.bar.addEventListener("mouseleave",e=>this.setMouseStateHandler(e)); //スクロールバーの高さを設定します this.setBarHeight(); //マウスのドラッグイベントをリッスンします this.mouseHand = e => this.mouseHandler(e); this.bar.addEventListener("mousedown", this.mouseHand); Utils.appendTo(this.bar、_parent); } setBarHeight() { //外側の親コンテナの高さ this.conHeight = this.container.clientHeight; //実際のコンテンツの高さ this.menuHeight = this.container.firstElementChild.scrollHeight; // 実際のコンテンツの高さが親コンテナーの高さより小さい場合、スクロール バーは非表示になります if (this.conHeight >= this.menuHeight) this.bar.style.display = "none"; それ以外の場合は this.bar.style.display = "block"; //スクロールバーの高さを計算します。let h = Math.floor(this.conHeight / this.menuHeight * this.conHeight); this.bar.style.height = h + "px"; } マウスステートハンドラーを設定する(e){ //スクロールバーのホバー状態のスタイルを設定します if (e.type == = "mouseenter") { 背景色は rgba(255,0,0,1) です。 }それ以外{ this.bar.style.backgroundColor="rgba(255,0,0,.5)"; } } マウスハンドラ(e) { スイッチ (e.type) { ケース「マウスダウン」: e.preventDefault(); オフセットYは、 document.addEventListener("mousemove", this.mouseHand); document.addEventListener("mouseup", this.mouseHand); 壊す; ケース「マウス移動」: //注: getBoundingClientRect() によって返される結果では、幅と高さの両方に境界線が含まれます。var rect = this.container.getBoundingClientRect(); this.barTop = e.clientY - rect.y - this.y; //スクロールバーの移動 this.barMove(); 壊す; ケース「マウスアップ」: document.removeEventListener("mousemove"、this.mouseHand); document.removeEventListener("mouseup", this.mouseHand); 壊す; } } マウスホイールハンドラ(e){ //ローラーイベント if(e.wheelDirection==="down"){ //下にスクロールすると、メニュー コンテンツが上に移動します。this.barTop+=this.wheelSpeed; }それ以外{ this.barTop-=this.wheelSpeed; } //スクロールバーの移動 this.barMove(); } バー移動(){ this.barTop が 0 の場合、 this.barTop は 0 になります。 this.barTop > this.conHeight - this.bar.offsetHeight の場合、 this.barTop = this.conHeight - this.bar.offsetHeight; this.bar.style.top = this.barTop + "px"; //メニューコンテンツのスクロール this.menuMove(); } メニュー移動(){ //コンテンツのスクロール高さを計算します。let menuTop=this.barTop/(this.conHeight-this.bar.offsetHeight)*(this.menuHeight-this.conHeight); this.menuUl.style.top=-menuTop+"px"; } } Utils.js ファイルはツールキットです: デフォルトクラス Utils をエクスポートする{ 静的createE(要素、スタイル、準備){ 要素 = document.createElement(要素); if(style) for(let prop in style) elem.style[prop]=style[prop]; if(prep) for(let prop in prep) elem[prop]=prep[prop]; 要素を返します。 } 静的appendTo(要素、親){ parent.constructor === String の場合、parent = document.querySelector(parent); 親要素に子要素を追加します。 } 静的ランダム数(最小値,最大値){ Math.floor(Math.random*(max-min)+min) を返します。 } 静的ランダムカラー(アルファ){ アルファ=アルファ||Math.random().toFixed(1); isNaN(alpha)の場合、alpha=1; アルファ>1の場合、アルファ=1; アルファ<0の場合、アルファ=0; col="rgba("; とします。 (i=0;i<3;i++) の場合{ col+=Utils.randomNum(0,256)+","; } col+=alpha+")"; 列を返します。 } 静的挿入Css(選択、スタイル){ document.styleSheets.length===0の場合{ styleS = Utils.createE("style"); とします。 Utils.appendTo(styleS,document.head); } styleSheet を document.styleSheets[document.styleSheets.length-1] とします。 str=select+"{"とします。 for(var prop in スタイル){ str+=prop.replace(/[AZ]/g,function(item){ "-"+item.toLocaleLowerCase() を返します。 })+":"+styles[prop]+";"; } str+="}" styleSheet.insertRule(str、styleSheet.cssRules.length); } 静的 getIdElem(要素,obj){ if(elem.id) obj[elem.id]=elem; if(elem.children.length===0) の場合、obj を返します。 for(let i=0;i<elem.children.length;i++){ Utils.getIdElem(elem.children[i],obj); } } } 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Linuxの同時実行は簡単です。このようにするだけです
>>: Ubuntu 15.04 は MySQL リモート ポート 3306 を開きます
HTML ボタン自体を中央に配置するにはどうすればよいでしょうか? このアイデアは簡単に見つかります...
今日ご紹介したいのは、ネイティブ JS を使用してプログレス バーをドラッグし、要素の透明度を変更す...
最近、業務上のボタンの増加により、ページレイアウトにボタンが多すぎて、ページが美しくなく、ユーザーエ...
1. MySQL アーキテクチャストレージ エンジンを紹介する前に、まずは MySQL アーキテクチ...
目次序文始めるReactライフサイクルリアクトファイバーリアクトセットステートReactイベントメカ...
目次CentOS7環境での設定コマンド手順1. DHCP設定ファイルを設定する2. グローバル構成を...
mysql maxとwhereの間の実行の問題SQLを実行します: テーブル「grades」を作成し...
まず、よくある質問は、ECMAScript と JavaScript の関係は何ですか? ECMAS...
目次主キー制約一意の主キー非 Null 制約デフォルトの制約外部キー制約1NF 2NF 3NFデータ...
目次1. データベースを操作する1.1 データベースを作成する1.2 データベースをクエリする1.3...
ktl ツールを使用して、mysql から mysql にデータを同期します。 1. 新しいジョブス...
1. まずパゴダを設置するインストール要件: Python バージョン: 2.6/2.7 (Pago...
少なくとも 5 冊のベストセラー書籍の順序なしリストを含む HTML ページを作成します。各書籍の前...
導入MySQL には、SELECT ステートメントを分析し、開発者が最適化できるように SELECT...
基本的なネットワーク構成Docker はイメージに基づいて複数のコンテナを「開く」ことができ、各コン...