雑記帳

整理しない情報集

JSONをHTMLとしてダンプする

公開日:

カテゴリ: Javascript

JSONデータをパースして画面にそのまま出力する方法が、探しても意外と見当たらないので作ってみました。

仕様

  • Grid Layoutで表示させることを想定
  • ネストされたJSONに対応
  • 配列が入る親要素にclassを追加
  • 空オブジェクト、空配列、nullの項目にclassと代替文字列を追加

サンプル

  • 別途CSSを適用しています(サンプルで使用しているスタイルは下記を参照)

ソースコード

const traverseJSON = (obj, elem) => {
	if (obj !== null && typeof obj === "object" && Object.entries(obj).length) {
		Object.entries(obj).forEach(([key, val]) => {
			const h4 = document.createElement("h4");
			h4.title = key;
			h4.appendChild(document.createTextNode(key));
			elem.insertAdjacentElement("beforeend", h4);
			if (val !== null && typeof val === "object") {
				const child = document.createElement("div");
				child.classList.add("grid");
				if (Array.isArray(val)) child.classList.add("array");
				elem.insertAdjacentElement("beforeend", child);
				traverseJSON(val, child);
			} else {
				traverseJSON(val, elem);
			}
		});
	} else {
		const str = obj === null ? "null" : Array.isArray(obj) ? "empty array" : typeof obj === "object" ? "empty object" : obj;
		const p = document.createElement("p");
		p.title = str;
		if (obj === null || typeof obj === "object") p.classList.add("empty");
		p.appendChild(document.createTextNode(str));
		elem.insertAdjacentElement("beforeend", p);
	}
};

使い方

traverseJSON(JSONオブジェクト, 出力先要素);

使用例(上記サンプル)

const jsonText = `{"arr":["text1","text2","text3"],"obj":{"sub":"sub text"},"str":"text","empty":{"obj":{},"arr":[]}}`;
const target = document.getElementById("target");
traverseJSON(JSON.parse(jsonText), target);

サンプルで使用しているCSS

以下のスタイルは、あまりネストが深くなると幅をとります。ご使用の際は適宜調整してください。

また、色・ブレイクポイントについては上記サンプルとは異なる指定となっています(当ブログがレスポンス仕様・ダークモード対応のため、以下のサンプルとは異なるコードを使用しています)。

ひとまず displaygrid-template-columnsgrid-column-end プロパティがあれば最低限は動くと思います。

#target {
	font-size: 14px;
	overflow-x: hidden;
	display: grid;
	grid-template-columns: 100px 1fr;
	--border-color: #aaa;
	--empty-color: #ccc;
	--title-bg: #ddd;
	--array-bg: #eee;
	--name-width: 100px;
	--array-width: 30px;

	@media (max-width: 1000px) {
		display: block;
		border: 1px solid var(--border-color);
	}

	h4 {
		background-color: var(--title-bg);
		overflow-x: hidden;
	}

	:where(h4, p) {
		margin: 0;
		padding: 0 3px;
	}

	div.grid {
		display: grid;
		grid-template-columns: var(--name-width) 1fr;

		&.array {
			grid-template-columns: var(--array-width) 1fr;

			>h4 {
				background-color: var(--array-bg);
				text-align: right;
			}

			>div {
				@media (max-width: 1000px) {
					margin-left: 0;
				}
			}

			&>*:not(:last-of-type) {
				@media (max-width: 1000px) {
					border-bottom: 1px dashed var(--border-color);
				}
			}
		}

		&:not(.array) {
			@media (max-width: 1000px) {
				display: block;
				margin-left: 5px;
				border-left: 1px solid var(--border-color);
			}
		}
	}

	.empty {
		color: var(--empty-color);
	}

	.array>.empty {
		grid-column-end: span 2;
	}
}

余談

JSONからテンプレートHTMLに埋め込むことを放棄した人の末路です。自分しか使わないシステムの場合、JSONのキーだけで内容がわかりますし・・・。

(普通にデバッグ目的で使用する場合は console.dir() を使用した方が断然良いです)

カテゴリ: Javascript