📝 「HTML/CSSを始めよう」と「JavaScript を始めよう」の勉強会スライドと発表用周辺機能を追加 - #82
📝 「HTML/CSSを始めよう」と「JavaScript を始めよう」の勉強会スライドと発表用周辺機能を追加#82rough-github wants to merge 15 commits into
Conversation
|
手元で |
| /* | ||
| * Marp スライドのリハーサル計測ブックマークレット | ||
| * | ||
| * slide.html を開いた状態で起動すると、スライドを送るたびに滞在時間を記録する。 | ||
| * 記録は localStorage に逐次保存するので、誤ってリロードしても続きから再開できる。 | ||
| * | ||
| * キー操作 | ||
| * Ctrl+Shift+E 記録を Markdown で書き出す (クリップボードとファイルの両方) | ||
| * Ctrl+Shift+P 一時停止 / 再開 (右上のバッジをクリックしても同じ) | ||
| * Ctrl+Shift+X 記録を破棄して最初から | ||
| */ |
There was a problem hiding this comment.
すみません、以前自分が間違えて push したリハーサル計測用のブックマークレットなんですけど、適当な状態だったので使っていなかったら消しちゃっても良さそうです 🙏
使っていたらそのまま残しておいて大丈夫です!
There was a problem hiding this comment.
承知しました!
自分も動かそうとやって見たのですが、うまくいかず...という状況でしたので削除しちゃいました🙆♂️
| ```js | ||
| const user = { name: 'じぐ太郎', age: 20 }; | ||
| // ドット / ブラケット記法 | ||
| console.log("user.name: "user.name; | ||
| console.log("user[age]: "user['age']); | ||
| // 後から追加できる | ||
| user.hobby = '釣り'; | ||
| console.log(user); | ||
| ``` |
There was a problem hiding this comment.
少しコードが崩れちゃっていそうです。
| ```js | |
| const user = { name: 'じぐ太郎', age: 20 }; | |
| // ドット / ブラケット記法 | |
| console.log("user.name: "user.name; | |
| console.log("user[age]: "user['age']); | |
| // 後から追加できる | |
| user.hobby = '釣り'; | |
| console.log(user); | |
| ``` | |
| ```js | |
| const user = { name: 'じぐ太郎', age: 20 }; | |
| // ドット / ブラケット記法 | |
| console.log("user.name: " + user.name); | |
| console.log("user[age]: " + user['age']); | |
| // 後から追加できる | |
| user.hobby = '釣り'; | |
| console.log(user); |
There was a problem hiding this comment.
ありがとうございます!
確かに崩れてしまっていますね。修正しました🙆♂️
| function fmt(v){ | ||
| if (typeof v === 'string') return v; | ||
| if (v instanceof Error) return v.message; | ||
| try { return JSON.stringify(v); } catch (e) { return String(v); } | ||
| } |
There was a problem hiding this comment.
この関数の出力について調べてみました!
| 書いたコード | 出た表示 | 期待 |
|---|---|---|
let x; console.log('undefined:', x) |
undefined: |
undefined: undefined |
console.log('NaN:', NaN) |
NaN: null |
NaN: NaN |
console.log('Infinity:', 1/0) |
Infinity: null |
Infinity: Infinity |
console.log('関数:', function f(){}) |
関数: |
関数だと分かる表示 |
console.log('Map:', new Map([['a',1]])) |
Map: {} |
中身が見える表示 |
console.log('Set:', new Set([1,2])) |
Set: {} |
同上 |
console.log('日付:', new Date(0)) |
日付: "1970-01-01T00:00:00.000Z" |
クォート無し |
const o = {}; o.self = o; console.log('循環:', o) |
循環: [object Object] |
やむなし |
console.log({ name: 'じぐ太郎' }) |
{"name":"じぐ太郎"} |
{ name: 'じぐ太郎' } |
undefined が `` になったり、NaN が `null` に化けるのは避けられそうです!
| function fmt(v){ | |
| if (typeof v === 'string') return v; | |
| if (v instanceof Error) return v.message; | |
| try { return JSON.stringify(v); } catch (e) { return String(v); } | |
| } | |
| function fmt(v){ | |
| if (typeof v === 'string') return v; | |
| if (v instanceof Error) return v.message; | |
| if (v === undefined || v === null) return String(v); | |
| if (typeof v === 'function' || typeof v === 'symbol') return String(v); | |
| if (typeof v === 'number' && !isFinite(v)) return String(v); // NaN / Infinity | |
| try { const s = JSON.stringify(v); return s === undefined ? String(v) : s; } | |
| catch (e) { return String(v); } | |
| } |
There was a problem hiding this comment.
指摘されて気がつきました!
こちらもsuggestの通りに修正しました
| var orig = console[k]; | ||
| console[k] = function(){ send(k === 'log' ? 'log' : k, arguments); if (orig) try { orig.apply(console, arguments); } catch(e){} }; | ||
| }); | ||
| window.addEventListener('error', function(e){ send('error', [e.message]); }); |
There was a problem hiding this comment.
エラー行出してみるのはどうでしょう
| window.addEventListener('error', function(e){ send('error', [e.message]); }); | |
| window.addEventListener('error', function(e){ | |
| send('error', [e.message + (e.lineno ? ' (' + (e.lineno - 1) + ' 行目)' : '')]); | |
| }); |
There was a problem hiding this comment.
ありがとうございます!
良さそうに思って修正しようとしたのですが、e.linenoが素直にPlaygroundのエラー行を表す訳でないようで、
Playground内のエラーの行数と揃えるようにするには複雑になりそうなので、スルーとしたいです 🙏
修正前はPlaygroundでconsole.log(undefined)とすると、空白の文字が表示されていた
|
|
||
| <div class="syntax"> | ||
|
|
||
| `h1` = **セレクタ**(どの要素か)、`color` = **プロパティ**(何を)、`red` = **値**(どうする)。 |
There was a problem hiding this comment.
確かにいきなり感がありますね。
こちら、「今回学習する内容一覧」のスライドを前に挟むようにしました!
| </div> | ||
| <div class="split-side"> | ||
| <svg viewBox="0 0 330 200" style="width: 100%; height: auto;" font-family="ui-sans-serif, system-ui, sans-serif" xmlns="http://www.w3.org/2000/svg"> | ||
| <defs> | ||
| <marker id="ax" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#455a64"/></marker> | ||
| <marker id="axp" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#e91e63"/></marker> | ||
| </defs> | ||
| <text x="74" y="16" font-size="11" fill="#607d8b">display: flex(親)</text> | ||
| <rect x="70" y="22" width="250" height="80" rx="6" fill="none" stroke="#90a4ae" stroke-dasharray="5 4"/> | ||
| <rect x="82" y="36" width="64" height="52" rx="4" fill="#90caf9"/><text x="114" y="67" font-size="13" text-anchor="middle" fill="#0d47a1">子</text> | ||
| <rect x="158" y="36" width="64" height="52" rx="4" fill="#90caf9"/><text x="190" y="67" font-size="13" text-anchor="middle" fill="#0d47a1">子</text> | ||
| <rect x="234" y="36" width="64" height="52" rx="4" fill="#90caf9"/><text x="266" y="67" font-size="13" text-anchor="middle" fill="#0d47a1">子</text> | ||
| <line x1="70" y1="120" x2="320" y2="120" stroke="#455a64" stroke-width="2" marker-end="url(#ax)"/> | ||
| <text x="195" y="140" font-size="13" text-anchor="middle" fill="#455a64">主軸(子が並ぶ向き)</text> | ||
| <line x1="42" y1="102" x2="42" y2="22" stroke="#e91e63" stroke-width="2" marker-end="url(#axp)"/> | ||
| <text x="42" y="120" font-size="12" text-anchor="middle" fill="#e91e63">交差軸</text> | ||
| </svg> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
こちらデフォルトが横向きということなので、スルーとしたいです 🙏
| ## 1-3. 変数と定数 | ||
|
|
||
| 値に名前をつけて保存する箱が**変数**です。`let` で宣言し、`=` で値を割り当てます。あとから | ||
| 別の値に**入れ替え(再代入)**できます。 | ||
|
|
||
| 一方、**定数**は入れ替えできない箱。`const` で宣言し、再代入しようとするとエラーになります。 | ||
|
|
||
| <div class="syntax"> |
| ## 3-6. forEach で一つずつ | ||
|
|
||
| 配列の各要素を順に処理したいときは **`forEach`** が読みやすいです。 | ||
|
|
||
| 各要素を受け取る**関数(コールバック)**を渡すと、要素の数だけ順に呼ばれます。 | ||
| index を気にせず書けるのが利点です。 | ||
|
|
||
| <div class="syntax"> | ||
|
|
| ## 4-6. クラス | ||
|
|
||
| 同じ構造のデータと操作をまとめる**設計図**が**クラス**です。`class` で定義し、`new` で | ||
| **実体(インスタンス)**を作ります。 | ||
|
|
||
| プロパティ(データ)とメソッド(関数)を持ち、メソッド内の `this` はそのインスタンス自身を指します。 | ||
|
|
|
ほかは良さそうに思います!
|
|
強調表示が崩れている部分も修正しました |





インターン/勉強会向けに、HTML/CSS と JavaScript の入門スライドを2セット新規追加します。
あわせて、発表練習・発表者ノート生成などの周辺ツールも同梱しています。
追加するもの
補足
発表用の周辺機能(使い方)
commitはしていませんが手元で行える周辺機能
1. 台本を作る(rehearsal/transcript/)
slide.md を元に読み上げ台本を作り、各スライドの発表者ノートへ自動挿入できます。
本番では投影スライドの裏で台本を見ながら話せます。
slide.md から「講師の話し言葉」の台本を章ごとに生成します(00-intro.md / 01-chapter1.md / … / 99-appendix.md)。生成ルールは transcript/README.md 参照。
2. 発表者ノートへ挿入する
node rehearsal/build-notes.mjs # slide.md + transcript/ → slide.notes.md を生成
npx marp slide.notes.md --html -o slide.notes.html --allow-local-files --theme-set themes/jig.css
リハーサル計測
rehearsal/bookmarklet.js は、スライドを送るだけで章ごと・スライドごとの所要時間を記録するブックマークレットです。詳細は rehearsal/README.md を参照。