JavaScriptでDOMを操作するTips.

 
Web Tips.
Booskanium's
Booskanium's Web Tips.

構文が長くてすぐ忘れるので、コピペで使えるようにφ(..)メモメモ

document.getElementById('ID名');

var item = document.getElementById('ID名');

document.querySelectorAll('CSSセレクタ');

与えられたCSSセレクタに一致する文書中の要素のリストを示す静的*1なNodeListを取得。

detailsタグを一括処理する例

//detailsのtoggleイベントリスナーに呼び出し関数をセット
let details = document.querySelectorAll('details');
details.forEach((details) => {
	details.addEventListener('toggle', function(e){ openCloseDetails(e); });
});

//detailsのtoggleイベントを処理する
function openCloseDetails(e) {
	//イベントが発火した(summaryタグ)のID名と同じダータセット名を持つアイテムを取得する
	let item = document.querySelector(`[data-id=${e.target.dataset.id}]`);
	//上記ののアイテムのクラスリストにクラス名をトグル(有れば除外,無ければ追加)
	item.classList.toggle('segDetailsVisible');
}
※上記の例の様にdetailsの開閉で見え方を変えることはCSSのみでも可能
 detailsとsummaryでコンテンツ開閉

参考文献:Document.querySelectorALL()

document.querySelector('CSSセレクタ');

与えられたCSSセレクタに一致する文書中の最初の要素を取得

最初のaudio要素を取得

document.querySelector('audio');

参考文献:Document.querySelector()

document.getElementsByClassName('cssクラス名');

注意点はgetElementsByClassNameが戻すリストはHTMLCollectionであり配列では無いことです。
HTMLCollectionはオブジェクトへの参照であり、for文で回すと、そのオブジェクトを削除したり、クラス名を替えたりすると、HTMLCollectionの状態が変わり、HTMLCollectionが変わりforでの全件処理に支障をきたします。
そこで、配列としてforEachで単純に全件処理するのは、配列に変換してから処理します。
配列として扱うには
Array.from(document.getElementsByClassName('myClass')).forEach(v=>{ ~処理~; };
または
[].forEach.call(document.getElementsByClassName("test"),function(e){ ~処理~; });
または
[...document.getElementsByClassName('myClass'))].forEach(v=>{ ・・・

// test クラスを持つすべての要素に対して処理する
var elements = document.getElementsByClassName('test');
elements = Array.from(elements);	//HTMLCollectionを配列に変換
elements.forEach((elements) => {
	elements.~処理~;
});
// test および red の両クラスを持つすべての要素に対して処理する
var elements = document.getElementsByClassName('test red');
elements = Array.from(elements);	//HTMLCollectionを配列に変換
elements.forEach((elements) => {
	elements.~処理~;
});
// main という ID を持つ要素内にある test クラスを持つすべての要素に対して処理する
var elements = document.getElementById('main').getElementsByClassName('test');
elements = Array.from(elements);	//HTMLCollectionを配列に変換
elements.forEach((elements) => {
	elements.~処理~;
});
// test クラスを持つ最初の要素を取得します(一致する要素がなければ undefined を返す)
var elements = document.getElementsByClassName('test')[0];

参考:MDN:Document.getElementsByClassName()

サンプル

サンプル

サンプル

							

root:{}内のカスタムプロパティの値を取得

:root {
  --main-color: #abc;
}
getComputedStyle(document.documentElement).getPropertyValue('--main-color')	

クラス(複数指定あり)の中の特定タグ(複数あり)に対する処理

この事例は、アコーディンメニューの開閉による、windowサイズの変更を親windowに通知する例です。

	var navs = document.getElementsByClassName('accordion_nav');
	if (navs) {
		for(let i=0; i<navs.length; i++) {
			var labels = navs[i].getElementsByTagName('label');
			for(let j=0; j<labels.length; j++) {
				labels[j].addEventListener('click', 
					function() {
						setTimeout(function (e) {
							// 当該window自体が子windowの場合は、親windowにサイズ変更を通知
							if (window == window.parent) {
								//当該windowがTOPなら何もしない
							} else {
								//親windowに変更後のwindowサイズを通知
								// ※上記のiframe.style.heightの変更で、当該windowサイズ変更イベント(resizechild)が発火しない、そこで能動的にサイズ変更を通知する。
								window.parent.postMessage('{"sender":"__resizeChild","height":' + document.body.scrollHeight + ',"width":' + document.body.clientWidth + ',"winName":"' + window.name + '"}', '*');
							}
						},100);
					}
				, false );
			}
		}
	}

コンテキストメニュー無効を解除する方法

落書き人はコンテキストメニューを無効にしているバズワード満載のウェブページは速攻で閉じたくなります。
わからない単語部分を選択できないので字引するのに不便で読む気が失せます。

どうしても読みたい記事だったらコンテキストメニュー無効を解除しています。
デベロッパーモードのConsoleで解除処理をJavaScrptで記述してenterキーを押します。
そのJavaScriptのコードは以下のいづれかです。

document.oncontextmenu = function () {return true;}
document.getElementsByTagName('html')[0].oncontextmenu = function () {return true;}
document.body.oncontextmenu = function () {return true;}

CSSを弄る必要がある場合もありますので、手っ取り早く「bsolute Enable Right Click & Copy」という拡張機能でコンテキスメニュー無効を無効にしなうのがお薦めです。

エレメントのHTMLトップからのオフセットを求める

「element.offsettop」は
・全親エレメントがrerative以外ならHTMLトップからのオフセット
・親エレメントがrerativeならその親エレメントからのオフセット
これでは、HTMLトップからのエレメント位置を求めたい場合は駄目です。
実務ではHTMLトップからのエレメント位置を求めたい場合の方が多い。

地道にHTMLトップからのオフセットを求めるなら、offsetParent内のoffsetを、offsetParentの中のoffsetParentがnullになるまで再規呼び出しで加算する。
しかしこの方法はちょっと処理コストが大きすぎます。

そこでもっと簡単に、

Element.getBoundingClientRect().top + window.pageYOffset;
で求められます。
Element.getBoundingClientRect().topは
スクリーントップからのオフセット
window.pageYOffsetは
HTMLトップからのスクリントップまでのオフセット
です。