質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

489閲覧

Html 要素の幅を取得するには?

BetterEveryday

総合スコア19

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2023/05/28 08:30

実現したいこと

幅広画面では横並びのドロップダウンメニューが、
幅狭画面では同じ幅で 1 つずつ縦に並ぶ。(折り返さない)
イメージ説明

前提

以下の処理を追加しようとしています。(他解決策でも)

  1. 各要素の幅を取得する
  2. 最長文字列の要素幅を特定する
  3. 画面幅内に全要素を横並びできない場合は、最長文字列の要素幅を全兄弟要素に設定する

発生している問題

イメージ説明

JavaScript で生成している Html 要素の幅を取得できない。

該当のソースコード

Html

1<div id="suiteBarDelta"> 2</div>

JavaScript

1let myMockListData = [ 2 { 3 URL: "/siteA.aspx", 4 URLNAME: "Home", 5 dropDown: "no", 6 id: "home" 7 }, 8 { URL: "/siteF.aspx", URLNAME: "Site F", dropDown: "yes", id: "Training" }, 9 { URL: "/siteF.aspx", URLNAME: "Site F", dropDown: "MegaMenu", id: "Training" }, 10 { 11 URL: "/siteA.aspx", 12 URLNAME: "Site A", 13 dropDown: "yes", 14 id: "SiteA" 15 } 16]; 17 18var subList = [ 19 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" }, 20 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" }, 21 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" } 22]; 23 24var megaMenuCategory = [ 25 { id: "Training", category: "DT", url: "www.gmail.com" }, 26 { id: "Training", category: "画面幅が小さいと縦並び、各アイテムの幅が揃わない", url: "www.gmail.com" }, 27 { id: "Training", category: "IT", url: "www.gmail.com" } 28]; 29 30var categoryMenu = [ 31 { category: "DT", menuItem: "DT-BT", menuUrl: "www.gmail.com" }, 32 { category: "DT", menuItem: "DT-SE", menuUrl: "www.gmail.com" }, 33 { category: "DT", menuItem: "DT-PI", menuUrl: "www.gmail.com" }, 34 { category: "画面幅が小さいと縦並び、各アイテムの幅が揃わない", menuItem: "Human Resources", menuUrl: "www.gmail.com" }, 35 { category: "IT", menuItem: "IT-IO", menuUrl: "www.gmail.com" }, 36 { category: "IT", menuItem: "IT-CS", menuUrl: "www.gmail.com" } 37]; 38 39createNavigation(myMockListData); 40 41function myFunction() { 42 var x = document.getElementById("myTopnav"); 43 if (x.className === "topnav") { 44 x.className += " responsive"; 45 } else { 46 x.className = "topnav"; 47 } 48} 49 50function createNavigation(navData) { 51 var headerElement = document.getElementById("suiteBarDelta"); 52 headerElement.insertAdjacentHTML('afterend', '<div class="topnav" id="myTopnav"><a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">&#9776;</a></div>'); 53 var topNav = document.getElementById("myTopnav"); 54 for (var x = 0; x < navData.length; x++) { 55 if (navData[x].dropDown === "no") { 56 var aLink = _createEl("a"); 57 aLink.href = navData[x].URL; 58 aLink.appendChild(document.createTextNode(navData[x].URLNAME)); 59 topNav.appendChild(aLink); 60 } else if (navData[x].dropDown === "yes") { 61 var buildSubNavigation; 62 buildSubNavigation = buildSubNavBar(navData[x].id); 63 topNav.appendChild(buildSubNavigation); 64 } else { 65 //build megamenu 66 var buildSubNavigation; 67 buildDirectorateNav = buildDirectorateMegaMenu(navData[x].id); 68 } 69 } 70} 71 72function buildDirectorateMegaMenu(navDataID) { 73 var buildNav; 74 var topNav = document.getElementById("myTopnav"); 75 buildNav = buildSubNavBar(navDataID, "megaMenu"); //Build mega menu and attach in buildSubNavBar() 76 topNav.appendChild(buildNav); 77} 78 79function buildSubNavBar(subNavID, isDirectorate) { 80 //create div and add dropdown class 81 var ddDiv = _createEl("div"); 82 if(isDirectorate === "megaMenu"){ 83 ddDiv.classList.add("Mdropdown"); 84 }else{ 85 ddDiv.classList.add("dropdown"); 86 } 87 //create button and add text 88 var btn = _createEl("button"); 89 if(isDirectorate === "megaMenu"){ 90 btn.classList.add("Mdropbtn"); 91 }else{ 92 btn.classList.add("dropbtn"); 93 } 94 //append the text to the button 95 btn.appendChild(document.createTextNode(subNavID)); 96 97 //create i tag and add "fa fa-caret-down" classes 98 var itag = _createEl("i"); 99 itag.classList.add("fa"); 100 itag.classList.add("fa-caret-down"); 101 itag.classList.add("fa-fw"); 102 btn.appendChild(itag); 103 ddDiv.appendChild(btn); 104 105 var ddContent = _createEl("div"); 106 ddContent.classList.add("dropdown-content"); 107 for (var i = 0; i < subList.length; i++) { 108 if (subList[i].id === subNavID && subList[i].id !== "Training") { 109 var a = _createEl("a"); 110 a.href = subList[i].subURL; 111 a.appendChild(document.createTextNode(subList[i].URLNAME)); 112 ddContent.appendChild(a); 113 } 114 } 115 116 if(isDirectorate !== "megaMenu"){ 117 ddContent = createContent(subNavID, ddContent, false, ddDiv); 118 119 } else { 120 121 //create div and add dropdown class 122 var megaDivDropDown = _createEl("div"); 123 megaDivDropDown.classList.add("dropdown"); 124 125 var megaBtn = _createEl("button"); 126 megaBtn.classList.add("dropbtn"); 127 128 megaDivDropDown.appendChild(megaBtn); 129 var megaI = _createEl("i"); 130 megaI.classList.add("fa"); 131 megaI.classList.add("fa-caret-down"); 132 133 megaBtn.appendChild(megaI); 134 135 var megaDDivContent = _createEl("div"); 136 megaDDivContent.classList.add("Mdropdown-content"); 137 138 ddDiv = createContent(subNavID, megaDDivContent, true, ddDiv); 139 } 140 ddDiv.appendChild(ddContent); 141 return ddDiv; 142} 143function _createEl(el) { 144 return document.createElement(el); 145} 146 147function createContent(subNavID, content, bMegaMenu, ddDiv) { 148 149 var iWidthMax = 0; 150 var iWidthAll = 0; 151 //Loop through categories & sub-categories items 152 for (var i = 0; i < megaMenuCategory.length; i++) { 153 if (megaMenuCategory[i].id === subNavID) { 154 155 var headerDiv = _createEl("div"); 156 headerDiv.classList.add("header"); 157 158 var h2 = _createEl("h2"); 159 h2.appendChild(document.createTextNode(megaMenuCategory[i].category)); 160 headerDiv.appendChild(h2); 161 162 // 幅取得箇所案 1 : h2 追加直後 163 iWidthAll = iWidthAll + headerDiv.style.width; 164 if(iWidthMax < headerDiv.clientWidth) { 165 iWidthMax = headerDiv.clientWidth; 166 } 167 168 var divCol = _createEl("div"); 169 divCol.classList.add("column"); 170 var colHr = _createEl("h3"); 171 colHr.appendChild(document.createTextNode("")); 172 divCol.appendChild(colHr); 173 for (var x = 0; x < categoryMenu.length; x++) { 174 if (megaMenuCategory[i].category === categoryMenu[x].category) { 175 var colAnchor = _createEl("a"); 176 colAnchor.href = categoryMenu[x].menuUrl; 177 colAnchor.appendChild(document.createTextNode(categoryMenu[x].menuItem)); 178 179 divCol.appendChild(colAnchor); 180 headerDiv.appendChild(divCol); 181 content.appendChild(headerDiv); 182 if(bMegaMenu) { 183 ddDiv.appendChild(content); 184 } 185 } 186 } 187 188 // 幅取得箇所案 2 : 全行追加後に最後の h2 要素を取得する 189 var nodes = document.querySelectorAll('.header>h2'); 190 var last = nodes[nodes.length- 1]; 191 } 192 } 193/* 194 // 画面幅が全要素の和より小さい場合、最大要素幅にする 195 if (window.innerWidth < iWidthAll) { 196 var childElems = content.children; 197 for (var i = 0; i < childElems.length; i++) { 198 childElems[i].style.width = iWidthMax; 199 } 200 } 201*/ 202 203 if(!bMegaMenu) { 204 return content; 205 } else { 206 return ddDiv; 207 } 208} 209

CSS

1body {margin:0;} 2 3.topnav { 4 display: flex; 5 overflow: hidden; 6 background-color: #5A7FA2; 7} 8 9.topnav a { 10 display: block; 11 color: #f2f2f2; 12 text-align: center; 13 padding: 14px 16px; 14 text-decoration: none; 15 font-size: 17px; 16} 17 18.active { 19 background-color: #4CAF50; 20 color: white; 21} 22 23.topnav .icon { 24 display: none; 25} 26 27.dropdown { 28 overflow: hidden; 29} 30 31.dropdown .dropbtn { 32 font-size: 17px; 33 border: none; 34 outline: none; 35 color: white; 36 padding: 14px 16px; 37 background-color: inherit; 38 font-family: inherit; 39 margin: 0; 40} 41 42.dropdown-content { 43 display: none; 44 position: absolute; 45 background-color: #f9f9f9; 46 min-width: 160px; 47 left: auto; 48 box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); 49 z-index: 1; 50} 51 52.dropdown-content a { 53 float: none; 54 color: black; 55 padding: 12px 16px; 56 text-decoration: none; 57 display: block; 58 text-align: left; 59} 60 61.topnav a:hover, .dropdown:hover .dropbtn { 62 background-color: #555; 63} 64 65.dropdown-content a:hover { 66 background-color: #ddd; 67 color: black; 68} 69 70.dropdown:hover .dropdown-content { 71 display: flex; 72 flex-wrap: wrap; 73} 74 75.dropdown:last-child .dropdown-content { 76 flex-direction: column; 77} 78 79/*MEGA-MENU*/ 80* { 81 box-sizing: border-box; 82} 83 84.Mnavbar { 85 overflow: hidden; 86 background-color: #333; 87 font-family: Arial, Helvetica, sans-serif; 88} 89 90.Mnavbar a { 91 font-size: 16px; 92 color: white; 93 text-align: center; 94 padding: 14px 16px; 95 text-decoration: none; 96} 97 98.Mdropdown { 99 overflow: hidden; 100} 101 102.Mdropdown .Mdropbtn { 103 font-size: 16px; 104 border: none; 105 outline: none; 106 color: white; 107 padding: 14px 16px; 108 background-color: inherit; 109 font: inherit; 110 margin: 0; 111} 112 113.Mnavbar a:hover, .Mdropdown:hover .Mdropbtn { 114 background-color: #555; 115} 116 117.Mdropdown-content { 118 display: none; 119 position: absolute; 120 background-color: #f9f9f9; 121 left: 0; 122 box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); 123 z-index: 1; 124} 125 126.header { 127 float: left; 128 background: #555; 129 padding: 16px; 130 color: white; 131 overflow: hidden; 132 flex-grow: 1; 133} 134 135.header h2 { 136 padding: 16px; 137 color: white; 138} 139 140.Mdropdown:hover .Mdropdown-content { 141 display: flex; 142 flex-wrap: wrap; 143} 144 145.column { 146 margin: 0 -16px -16px; 147 padding: 10px; 148 background-color: #ccc; 149 height: 250px; 150} 151 152.column a { 153 float: none; 154 color: black; 155 padding: 16px; 156 text-decoration: none; 157 display: block; 158 text-align: left; 159} 160 161.column a:hover { 162 background-color: #ddd; 163} 164 165.header:hover h2 { 166 color: orange; 167}

試したこと

  • style.width
  • clientWidth

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BetterEveryday

2023/05/29 02:55 編集

「同じ質問」かどうかにつきまして ■ 最初の質問から派生し、解決したい全 3 件の質問があり、 1. 幅狭画面で縦並びするメニュー幅を揃える (必須技術は CSS) 2. JavaScript 関数化 (必須技術は JavaScript) 3. Html 要素幅を取得する (必須技術は JavaScript) 違いは以下になります。 1 件目は実現したいこと全容であり、幅広い技術が必要となり、解決したら、 今後ドロップダウン/メガメニューを作成される方に知見となる内容、 2 件目、3 件目は、1 件目を模索する中で、 1 つの仮定に基づいて進めるにあたって発生してきた小さな質問であり、 必要な技術領域も少なく、1 件目とは回答できる人も異なるのではないかと考え、 最終的に 1 件目の解決につながるように、分割しています。 したがって、投稿しているソースコードも「似て非なり」であり、 注目してもらいたい部分は、 1 件目は全ソースコード、 2 件目は JavaScipt 関数化部分、 3 件目は JavaScipt Html 要素取得部分 というように、異なってきます。 -------------------------------------------------------------------------------- ■ 3 件目に、1 件目と同じ 2 枚の画像 - 実現したいこと - 発生している問題 を付加した理由は、 JavaScript コードを読み解くにあたって、 画面要素の構成があると、可読性が高まると考え、 この 3 件目の質問には背景として、画面の画像や他のコードも付加しています。 また、1 件目の回答者からも、 「再投稿するほうが解決に近づきやすい」と 助言いただいたことにより、分割投稿に至りました。
shinoharat

2023/05/30 06:52 編集

すみません。 質問文に書いてある仕様が複雑でかなり理解しづらいです。 確認❶ とりあえずメニュー階層だけ解読したのですが、これで合っているでしょうか? ・親メニューは4つ(Home, Traning, Traning, Site A)ある。 ・Training の下に子メニュー、更にその下に孫メニューがある ・Training が2つ存在するが、どちらもメニュー内容は同じ ------------------------------------------ Home Training │ ├ DT │ ├ DT-BT │ ├ DT-SE │ └ DT-PI │ ├ 画面幅が...揃わない │ └ Human Resources │ └ IT   ├ IT-IO   └ IT-CS Training ( 内容は上と同じ。こちらはメガメニューで表示 ) Site A ├ Site A ├ Site A └ Site A ------------------------------------------
shinoharat

2023/05/30 06:52 編集

確認❷ ・1個目の「Traning」は通常のドロップダウン ・2個目の「Traning」はメガメニュー と認識しています。 添付画像だと1個目の「Traning」が展開されていますが、メガメニューではなく通常のドロップダウンとして表示した場合に上手くいかないということでしょうか? > 実現したいこと > 幅広画面では横並びのドロップダウンメニューが、 > 幅狭画面では同じ幅で 1 つずつ縦に並ぶ。(折り返さない) とありますが、通常のドロップダウンでも、幅広画面のときメニューを横並びにするのですか?
shinoharat

2023/05/30 06:54

確認❸ 画像が3枚添付されていますが、すべて「幅狭画面」のときの画像でしょうか?
shinoharat

2023/05/30 06:58

確認❹ 「画面幅が...揃わない」の文字色がオレンジになっていますが、これは :hover の影響ですか? 「Human Resources」の背景色が明るいのも、同じく :hover の影響ですか? これら2つが何か特別なメニューというわけでは無いと考えて良いですか?
Lhankor_Mhy

2023/05/30 10:47

試してみましたが、clientWidth で問題なく取得できるようでした。
BetterEveryday

2023/05/30 13:42

shinoharat さま、ご検討ありがとうございます。 確認❶ はい、ご認識のとおりになります。 実現したいこと全体の仕様は以下の前提に記述しています。 https://teratail.com/questions/v2xhan6ck1jc82 確認❷ メガメニュー、通常のドロップダウン、どちらも 画面幅によっては、縦横混在の並び、バラバラの幅になります。 はい、現状の詳細設計では、通常のドロップダウンでも、 幅広画面での横並びを準備したいと考えています。 これら機能につきましても、以下の前提に記述しています。 https://teratail.com/questions/v2xhan6ck1jc82 確認❸ はい、3 枚の画像は、すべて「幅狭画面」の時の画像になります。 確認❹ はい、すべて hover の影響で、 特別なメニューのわけではありません。 なにとぞどうぞよろしくお願いいたします。
BetterEveryday

2023/05/30 14:05

Lhankor_Mhy さま、ご確認どうもありがとうございます。 質問に載せました、JavaScript コード行数 164 の直前で headerDiv.clientWidth をコンソール出力すると、ゼロになります。 どこで、どの要素に対して、どのように記述したら、 clientWidth を問題なく取得できたか、教示いただけませんでしょうか? なにとぞどうそよろしくお願いいたします。
BetterEveryday

2023/05/31 05:32

Lhankor_Mhy さま、コメントありがとうございます。紹介いただきましたように、 質問に載せました、JavaScript コード行数 188 の直前で 以下の記述で明示的に display: block を指定してみても、 コンソール出力で clientWidth はゼロになります。 if(bMegaMenu) { var listHeader = document.querySelectorAll('.header h2'); var eleHeader = listHeader[1]; eleHeader.style.display='block'; console.log("document.querySelectorAll('.header h2').textContent : " + eleHeader.textContent); console.log("document.querySelectorAll('.header h2').clientWidth : " + eleHeader.clientWidth); eleHeader.style.display='none'; } textContent は取得できていますが、要素の取得に問題があるのでしょうか? なにか、お気づきの点はありますでしょうか?
Lhankor_Mhy

2023/05/31 07:35

祖先要素の .dropdown-content が display:none になっているのではないでしょうか。 display:none は子孫要素ごと非表示にします。
BetterEveryday

2023/05/31 09:43

Lhankor_Mhy さま、ご返信ありがとうございます。 祖先要素は .Mdropdown-content で display:none になっているため、 要素取得できた .header と同様の記述で .Mdropdown-content を取得すると、配列要素数がゼロであり、 配列要素を参照すると undefined になってしまいます。 // var listContent = document.querySelectorAll('.Mdropdown-content'); var listContent = document.getElementsByClassName("Mdropdown-content"); var eleContent = listContent[0]; console.log("document.querySelectorAll('.Mdropdown-content').length : " + listContent.length); console.log("document.querySelectorAll('.Mdropdown-content')[0] : " + eleContent); どのようにしたら、 .Mdropdown-content や .dropdown-content を取得できるものでしょうか?
Lhankor_Mhy

2023/05/31 10:06

引数 content の中に入ってそうな気がしますけど。
Lhankor_Mhy

2023/05/31 11:16 編集

といいますか、この段階では、document に挿入されてなくないですか? topNav.appendChild(buildSubNavigation) が実行されてから取得してみてはどうでしょうか?
BetterEveryday

2023/06/01 18:14 編集

Lhankor_Mhy さま、何度も検討いただきましてどうもありがとうございます。 応答遅れまして申し訳ございません。 たしかに、topNav.appendChild( 以降である必要があるため、 createContent 関数内では、 最後の要素「.Mdropdown-content」では undefined になり、 その前の要素「.dropdown-content」については幅を取得できることを確認できました。 質問に載せました、JavaScript コード行数 76、 buildDirectorateMegaMenu 関数内の topNav.appendChild(buildNav); の直後に、以下の記述により、一時的に display: block へ変更し、要素幅を取得後、 display: none へ戻すと、 var iWidthMax = 0; var iWidthAll = 0; listContent = document.getElementsByClassName("Mdropdown-content"); eleContentLast = listContent[listContent.length - 1]; eleContentLast.style.display = 'block'; var listHeader = document.querySelectorAll('.Mdropdown-content .header h2'); var eleHeader; var eleColumnLast; for (var iHeader = 0; iHeader < listHeader.length; iHeader++) { eleHeader = listHeader[iHeader]; iWidthAll = iWidthAll + eleHeader.clientWidth; if(iWidthMax < eleHeader.clientWidth) { iWidthMax = eleHeader.clientWidth; } } eleContentLast.style.display = 'none'; // 画面幅が全要素の和より小さい場合、最大要素幅にする if (window.innerWidth < iWidthAll) { var childElems = eleContentLast.children; for (var i = 0; i < childElems.length; i++) { childElems[i].style.width = iWidthMax; } } hover でメニュー表示されなくなってしまいます。 JavaScript で以下のようにホバーイベントを追加すると、 var targetsMdropdown = document.getElementsByClassName("Mdropdown"); var targetMdropdown = targetsMdropdown[targetsMdropdown.length - 1]; var popupMcontents = document.getElementsByClassName("Mdropdown-content"); var popupMcontent = popupMcontents[popupMcontents.length - 1]; // ドロップダウンに hover した時 targetMdropdown.addEventListener('mouseover', () => { popupMcontent.style.display = 'flex'; }, false); // ドロップダウンから離れた時 targetMdropdown.addEventListener('mouseleave', () => { popupMcontent.style.display = 'none'; }, false); 狙い通り、Mdropdown-content については幅を揃えることができました。 ただし、複数要素が存在する dropdown-content について、 ループ処理してみると、最後の要素が常に表示されてしまったり、 その他の要素が表示されない状態になってしまいます。 この質問でこれらの問題解明を継続することは分かりにくいと思いますので、新たな質問として分割投稿し、 この質問については Html 要素幅取得の解決のみで close しようと思います。 Lhankor_Mhy さまに、どこで、どの要素に対して、とコメントいただいたことで 要素幅を取得することができました。「助かりました」を示すために、 いただいたコメントで回答いただければ、ベストアンサーに設定したいと思います。 よろしくお願いいたします。
BetterEveryday

2023/06/02 01:57

Lhankor_Mhy さま、 私を思いやる、優しいお言葉、ありがとうございます。 では、教示いただたきました自己解決にいたします。 周りに相談できる開発者がいない環境の中で、自分ではどうしようもなく、 半ば諦めていた中での、ダメ元での投稿でしたので、たいへん助かりました。 私の問題解決のために貴重なお時間とお気持ちを、 助けていただきましてどうもありがとうございました。
guest

回答1

0

自己解決

Lhankor_Mhy さまにコメントで教示いただきました、

  • document に挿入される位置後に、
  • 祖先要素のdisplay : none を一時的に解除
  • clientWidth により

要素幅取得を実現できました。

JavaScript

1let myMockListData = [ 2 { 3 URL: "/siteA.aspx", 4 URLNAME: "Home", 5 dropDown: "no", 6 id: "home" 7 }, 8 { URL: "/siteF.aspx", URLNAME: "Site F", dropDown: "yes", id: "Training" }, 9 { URL: "/siteF.aspx", URLNAME: "Site F", dropDown: "MegaMenu", id: "Training" }, 10 { 11 URL: "/siteA.aspx", 12 URLNAME: "Site A", 13 dropDown: "yes", 14 id: "SiteA" 15 } 16]; 17 18var subList = [ 19 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" }, 20 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" }, 21 { subURL: "/site/a", id: "SiteA", URLNAME: "Site A" } 22]; 23 24var megaMenuCategory = [ 25 { id: "Training", category: "DT", url: "www.gmail.com" }, 26 { id: "Training", category: "画面幅が小さいと縦並び、各アイテムの幅が揃わない", url: "www.gmail.com" }, 27 { id: "Training", category: "IT", url: "www.gmail.com" } 28]; 29 30var categoryMenu = [ 31 { category: "DT", menuItem: "DT-BT", menuUrl: "www.gmail.com" }, 32 { category: "DT", menuItem: "DT-SE", menuUrl: "www.gmail.com" }, 33 { category: "DT", menuItem: "DT-PI", menuUrl: "www.gmail.com" }, 34 { category: "画面幅が小さいと縦並び、各アイテムの幅が揃わない", menuItem: "Human Resources", menuUrl: "www.gmail.com" }, 35 { category: "IT", menuItem: "IT-IO", menuUrl: "www.gmail.com" }, 36 { category: "IT", menuItem: "IT-CS", menuUrl: "www.gmail.com" } 37]; 38 39createNavigation(myMockListData); 40 41function myFunction() { 42 var x = document.getElementById("myTopnav"); 43 if (x.className === "topnav") { 44 x.className += " responsive"; 45 } else { 46 x.className = "topnav"; 47 } 48} 49 50function createNavigation(navData) { 51 var headerElement = document.getElementById("suiteBarDelta"); 52 headerElement.insertAdjacentHTML('afterend', '<div class="topnav" id="myTopnav"><a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">&#9776;</a></div>'); 53 var topNav = document.getElementById("myTopnav"); 54 for (var x = 0; x < navData.length; x++) { 55 if (navData[x].dropDown === "no") { 56 var aLink = _createEl("a"); 57 aLink.href = navData[x].URL; 58 aLink.appendChild(document.createTextNode(navData[x].URLNAME)); 59 topNav.appendChild(aLink); 60 } else if (navData[x].dropDown === "yes") { 61 var buildSubNavigation; 62 buildSubNavigation = buildSubNavBar(navData[x].id); 63 topNav.appendChild(buildSubNavigation); 64 } else { 65 //build megamenu 66 var buildSubNavigation; 67 buildDirectorateNav = buildDirectorateMegaMenu(navData[x].id); 68 } 69 } 70} 71 72function buildDirectorateMegaMenu(navDataID) { 73 var buildNav; 74 var topNav = document.getElementById("myTopnav"); 75 buildNav = buildSubNavBar(navDataID, "megaMenu"); //Build mega menu and attach in buildSubNavBar() 76 topNav.appendChild(buildNav); 77 78 var iWidthMax = 0; 79 var iWidthAll = 0; 80 81 listContent = document.getElementsByClassName("Mdropdown-content"); 82 console.log("listContent.length : " + listContent.length); 83 84 eleContentLast = listContent[listContent.length - 1]; 85 eleContentLast.style.display = 'block'; 86 87 var listHeader = document.querySelectorAll('.Mdropdown-content .header'); 88 var listColumn = document.querySelectorAll('.column'); 89 90 var eleHeader; 91 for (var iHeader = 0; iHeader < listHeader.length; iHeader++) { 92 eleHeader = listHeader[iHeader]; 93 iWidthAll = iWidthAll + eleHeader.clientWidth; 94 if(iWidthMax < eleHeader.clientWidth) { 95 iWidthMax = eleHeader.clientWidth; 96 } 97 98 } 99 eleContentLast.style.display = 'none'; 100 101 // 画面幅が全要素の和より小さい場合、最大要素幅にする 102 if (window.innerWidth < iWidthAll) { 103 var childElems = eleContentLast.children; 104 for (var i = 0; i < childElems.length; i++) { 105 childElems[i].style.width = iWidthMax; 106 } 107 } 108} 109 110var targetsMdropdown = document.getElementsByClassName("Mdropdown"); 111var targetMdropdown = targetsMdropdown[targetsMdropdown.length - 1]; 112var popupMcontents = document.getElementsByClassName("Mdropdown-content"); 113var popupMcontent = popupMcontents[popupMcontents.length - 1]; 114 115// ドロップダウンに hover した時 116targetMdropdown.addEventListener('mouseover', () => { 117 popupMcontent.style.display = 'flex'; 118}, false); 119 120// ドロップダウンから離れた時 121targetMdropdown.addEventListener('mouseleave', () => { 122 popupMcontent.style.display = 'none'; 123}, false); 124 125function buildSubNavBar(subNavID, isDirectorate) { 126 //create div and add dropdown class 127 var ddDiv = _createEl("div"); 128 if(isDirectorate === "megaMenu"){ 129 ddDiv.classList.add("Mdropdown"); 130 }else{ 131 ddDiv.classList.add("dropdown"); 132 } 133 //create button and add text 134 var btn = _createEl("button"); 135 if(isDirectorate === "megaMenu"){ 136 btn.classList.add("Mdropbtn"); 137 }else{ 138 btn.classList.add("dropbtn"); 139 } 140 //append the text to the button 141 btn.appendChild(document.createTextNode(subNavID)); 142 143 //create i tag and add "fa fa-caret-down" classes 144 var itag = _createEl("i"); 145 itag.classList.add("fa"); 146 itag.classList.add("fa-caret-down"); 147 itag.classList.add("fa-fw"); 148 btn.appendChild(itag); 149 ddDiv.appendChild(btn); 150 151 var ddContent = _createEl("div"); 152 ddContent.classList.add("dropdown-content"); 153 for (var i = 0; i < subList.length; i++) { 154 if (subList[i].id === subNavID && subList[i].id !== "Training") { 155 var a = _createEl("a"); 156 a.href = subList[i].subURL; 157 a.appendChild(document.createTextNode(subList[i].URLNAME)); 158 ddContent.appendChild(a); 159 } 160 } 161 162 if(isDirectorate !== "megaMenu"){ 163 ddContent = createContent(subNavID, ddContent, false, ddDiv); 164 165 } else { 166 167 //create div and add dropdown class 168 var megaDivDropDown = _createEl("div"); 169 megaDivDropDown.classList.add("dropdown"); 170 171 var megaBtn = _createEl("button"); 172 megaBtn.classList.add("dropbtn"); 173 174 megaDivDropDown.appendChild(megaBtn); 175 var megaI = _createEl("i"); 176 megaI.classList.add("fa"); 177 megaI.classList.add("fa-caret-down"); 178 179 megaBtn.appendChild(megaI); 180 181 var megaDDivContent = _createEl("div"); 182 megaDDivContent.classList.add("Mdropdown-content"); 183 184 ddDiv = createContent(subNavID, megaDDivContent, true, ddDiv); 185 } 186 ddDiv.appendChild(ddContent); 187 return ddDiv; 188} 189function _createEl(el) { 190 return document.createElement(el); 191} 192 193function createContent(subNavID, content, bMegaMenu, ddDiv) { 194 195 var listContent; 196 var eleContentLast; 197 //Loop through categories & sub-categories items 198 for (var i = 0; i < megaMenuCategory.length; i++) { 199 if (megaMenuCategory[i].id === subNavID) { 200 var iWidthMax = 0; 201 var iWidthAll = 0; 202 203 var headerDiv = _createEl("div"); 204 headerDiv.classList.add("header"); 205 206 var h2 = _createEl("h2"); 207 h2.appendChild(document.createTextNode(megaMenuCategory[i].category)); 208 headerDiv.appendChild(h2); 209 210 var divCol = _createEl("div"); 211 divCol.classList.add("column"); 212 var colHr = _createEl("h3"); 213 colHr.appendChild(document.createTextNode("")); 214 divCol.appendChild(colHr); 215 for (var x = 0; x < categoryMenu.length; x++) { 216 if (megaMenuCategory[i].category === categoryMenu[x].category) { 217 var colAnchor = _createEl("a"); 218 colAnchor.href = categoryMenu[x].menuUrl; 219 colAnchor.appendChild(document.createTextNode(categoryMenu[x].menuItem)); 220 221 divCol.appendChild(colAnchor); 222 headerDiv.appendChild(divCol); 223 content.appendChild(headerDiv); 224 if(bMegaMenu) { 225 ddDiv.appendChild(content); 226 } 227 } 228 } 229 } 230 } 231 232 if(!bMegaMenu) { 233// ddDiv.appendChild(ddContent); 234 return content; 235 } else { 236 return ddDiv; 237 } 238}

投稿2023/06/02 02:04

BetterEveryday

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問