[{"data":1,"prerenderedAt":11228},["ShallowReactive",2],{"articles-page-4":3},{"count":4,"content":5},63,[6,110,443,971,2725,2944,3172,4032,8362,9583],{"id":7,"title":8,"body":9,"category":95,"createdAt":97,"description":8,"extension":98,"index":99,"meta":100,"navigation":101,"path":102,"publish":101,"seo":103,"series":99,"seriesTitle":99,"stem":104,"tag":105,"thumbnail":108,"updatedAt":99,"__hash__":109},"articles\u002Farticles\u002Fwordpress-asset-chache.md","WordpressのJS・CSSファイルのキャッシュ対策",{"type":10,"value":11,"toc":89},"minimark",[12,16,21,33,41,48,58,61,64,67,70,77,83,86],[13,14,15],"p",{},"こんにちはjunです。wordpressのテーマを本番運用してスタイルに修正があり、修正をアップロードしてもクライアントのキャッシュが原因でユーザー側で変更されないことがあります。今回はテーマ内で読み込むjs,cssのキャッシュ対策について忘備録がてら記事として共有したいと思います。",[17,18,20],"h2",{"id":19},"wp_enqueue_stylewp_enqueue_scriptに記述","wp_enqueue_style,wp_enqueue_scriptに記述",[13,22,23,24,28,29,32],{},"wordpressのアセット読み込みには",[25,26,27],"code",{},"wp_enqueue_style",",",[25,30,31],{},"wp_enqueue_script","を使用します。それらの第４引数にはバージョンの文字列を入力することができます。",[13,34,35],{},[36,37,31],"a",{"href":38,"rel":39},"https:\u002F\u002Fdeveloper.wordpress.org\u002Freference\u002Ffunctions\u002Fwp_enqueue_script\u002F",[40],"nofollow",[13,42,43,44,47],{},"例えば、",[25,45,46],{},"1.3","など入力すれば読み込んだアセットのURLで以下の様に設定されます。",[49,50,55],"pre",{"className":51,"code":53,"language":54},[52],"language-text","https:\u002F\u002Fexample.com\u002Fwp-content\u002Fthemes\u002Fminato\u002Fassets\u002Fcss\u002Fstyle.css?ver=1.3\n","text",[25,56,53],{"__ignoreMap":57},"",[13,59,60],{},"GETパラメーターでバージョンの文字列をつけることで、バージョンを識別できる様になります。ブラウザは同じURLのCSS、JS、画像を手元にキャッシュします。普段は通信が早くなるのでありがたいですが、修正が発生した時などは古いコードが残るのでユーザーによって動きに差異が生まれる原因になります。そして大体のユーザーはキャッシュクリアのやり方を知らないですし、スマホは特に強力なキャッシュが効いています。",[13,62,63],{},"更新時のファイルをユーザーに届けるためには、上記の様なバージョンのGETパラメーターをつけるなどして、別のURLを指定する必要があります。",[13,65,66],{},"そのため納品時には今後の修正を考えてバージョンを変化させる様にした方がいいです。マーケットプレイスならば上記の引数をリリース・修正ごとに変えていればいいです。しかし開発中や毎回バージョンを変えるのが面倒な時、Gitで管理していてバージョンの文字列をあまり変えたくない時はファイルの更新日時でバージョンを変えてあげる方法があります。",[17,68,69],{"id":69},"filemtimeを使用する",[13,71,72,73,76],{},"PHPには対象ファイルの更新日時を取得する",[25,74,75],{},"filemtime()","という関数があります。引数には以下の様にサーバー上でのファイルパスを入力します。",[49,78,81],{"className":79,"code":80,"language":54},[52],"filemtime(get_theme_file_path('\u002Fcss\u002Feditor-style.css'))\n",[25,82,80],{"__ignoreMap":57},[13,84,85],{},"返り値はUnixタイムスタンプです。更新時はその時間が変わるので、更新のたびに変化する値を取得して変更したファイルを確実に届けることができます。対象ファイルを編集するだけで自動的にバージョンを示すことができます。",[13,87,88],{},"毎回更新日時を取得するのでその分のパフォーマンスがきりなりますが、自分はよくこの方法でwordpressを構築しています。",{"title":57,"searchDepth":90,"depth":90,"links":91},3,[92,94],{"id":19,"depth":93,"text":20},2,{"id":69,"depth":93,"text":69},[96],"ministack","2022-03-20","md",null,{},true,"\u002Farticles\u002Fwordpress-asset-chache",{"title":8,"description":8},"articles\u002Fwordpress-asset-chache",[106,107],"php","wordpress","_common\u002Fwordpress.png","S6seqQRftTxMf1j4j6_e1GgS9Q_wBpOnHTPv4lrW-Hc",{"id":111,"title":112,"body":113,"category":432,"createdAt":433,"description":434,"extension":98,"index":99,"meta":435,"navigation":101,"path":436,"publish":101,"seo":437,"series":99,"seriesTitle":99,"stem":438,"tag":439,"thumbnail":99,"updatedAt":99,"__hash__":442},"articles\u002Farticles\u002Flaravel-plain-text-with-html.md","LaravelのMailableでHTMLメールとプレーンテキストメール両方を送信する方法",{"type":10,"value":114,"toc":422},[115,118,122,125,132,137,140,149,153,160,170,176,179,183,186,275,285,293,296,299,305,320,341,360,363,370,418],[13,116,117],{},"こんにちはjunです。Laravelでメール機能が伴う内容を実装していたときに、HTMLメールだけでなくプレーンテキストメールでも送付してほしいとの用件がありました。Laravelではメールを送信する時は大抵、Mailableを使用しますがその時に両方送る方法が意外と日本語でなかったので忘備録として記事を作りました。プレーンテキストとはなんぞや？というとこから解説するので、対策法をさっさと知りたい方は「Mailabeでのプレーンテキストの設定」を見てください。",[17,119,121],{"id":120},"プレーンテキストメールとhtmlメールの違い","プレーンテキストメールとHTMLメールの違い",[13,123,124],{},"HTMLメールは名の通り、HTMLの記法で作成されたメールです。生のデータにはHTMLが書かれており、メールクライアント側でHTMLをレンダリングしてメール内容を表示します。リッチなメールを送付できるというメリットがあります。デメリットとして環境やデバイスによってはメールが全く見れなくなることです。",[13,126,127,128,131],{},"HTMLメールが見れない環境や昔はプレーンテキストメールといった、メモ帳で書いた様な本当に純粋な文字だけのメールを利用します。メリットはどの端末でも必ず表示はできるので、確実に届けたいメールなどにはプレーンテキストがおすすめです。例えばGithubの二段階認証メールは",[25,129,130],{},"Content-Type: text\u002Fplain; charset=UTF-8","とプレーンテキストで必ず送られ、毎週のお知らせメールはその両方が送られています。",[133,134,136],"h3",{"id":135},"どうやって確認できるの","どうやって確認できるの？",[13,138,139],{},"気になる方は届いたメールのソースを見てみましょう。Gmailであれば「画面右側の点々」をクリックして「メッセージのソースを表示」をクリックしますと、メールのヘッダやボディを確認できます。そのとき",[13,141,142,144,145,148],{},[25,143,130],{},"があれば、プレーンテキストメール形式で送付され、",[25,146,147],{},"Content-Type: text\u002Fhtml; charset=UTF-8","があればHTMLメールです。きちんとHTMLの記述があるのを確認してみてください。",[133,150,152],{"id":151},"なぜ両方ともつけることができるの","なぜ両方ともつけることができるの？",[13,154,155,156,159],{},"ちなみにメールにはHTMLとプレーン両方ともつけることは可能です。その場合環境に合わせてHTML・プレーンのものが表示されます。その仕組みはソースの中に ",[25,157,158],{},"Content-Type: multipart\u002Falternative; boundary=","のような記述をしようすることです。これはメールの内容を複数の形式で送りますよというヘッダ要素です。HTMLの内容とプレーンテキストの内容がソースでどこで分けているかを示しています。",[13,161,162,165,166,169],{},[25,163,164],{}," boundary=\"...\""," のboundaryの中身にある文字を境界として使用します。Laravelの場合はSwiftを使用しているので ",[25,167,168],{},"_=_swift_1646631221_d7511bd8d439c84878b3339aaec563e1_=_","という文字（一部分はランダムです）が境界として使用され、",[49,171,174],{"className":172,"code":173,"language":54},[52],"Content-Type: multipart\u002Falternative; boundary=\"_=_swift_1646631221_d7511bd8d439c84878b3339aaec563e1_=_\"\n\n--_=_swift_1646631221_d7511bd8d439c84878b3339aaec563e1_=_\nContent-Type: text\u002Fplain; charset=utf-8\nContent-Transfer-Encoding: quoted-printable\n\n（１）HTMLの記述’\n\n--_=_swift_1646631221_d7511bd8d439c84878b3339aaec563e1_=_\nContent-Type: text\u002Fhtml; charset=utf-8\nContent-Transfer-Encoding: quoted-printable\n\n（２）プレーンテキストの記述\n\n--_=_swift_1646631221_d7511bd8d439c84878b3339aaec563e1_=_\n",[25,175,173],{"__ignoreMap":57},[13,177,178],{},"上記の様な記述があると思います。ここで境界の文字を用いて２つの形式の内容を記述し、メールを送付してクライアントは適宜そのソースを汲み取って表示しています。",[17,180,182],{"id":181},"mailabeでのプレーンテキストの設定","Mailabeでのプレーンテキストの設定",[13,184,185],{},"前置きがながくなりましたが、LaravelのMailableでは以下の様に指定します。",[49,187,190],{"className":188,"code":189,"language":106,"meta":57,"style":57},"language-php shiki shiki-themes material-theme-ocean","\u002F**\n    * Build the message.\n    *\n    * @return $this\n*\u002F\npublic function build()\n{\n    return $this->view('mail.registration',[\n        'applay_user_name'=>$name,\n    ])->text('mail.registration_text',[ \u002F\u002F これ！\n        'applay_user_name'=>$name,\n    ])\n    ->subject('登録を受け付けました。');\n}\n",[25,191,192,200,205,210,216,222,228,234,240,246,252,257,263,269],{"__ignoreMap":57},[193,194,197],"span",{"class":195,"line":196},"line",1,[193,198,199],{},"\u002F**\n",[193,201,202],{"class":195,"line":93},[193,203,204],{},"    * Build the message.\n",[193,206,207],{"class":195,"line":90},[193,208,209],{},"    *\n",[193,211,213],{"class":195,"line":212},4,[193,214,215],{},"    * @return $this\n",[193,217,219],{"class":195,"line":218},5,[193,220,221],{},"*\u002F\n",[193,223,225],{"class":195,"line":224},6,[193,226,227],{},"public function build()\n",[193,229,231],{"class":195,"line":230},7,[193,232,233],{},"{\n",[193,235,237],{"class":195,"line":236},8,[193,238,239],{},"    return $this->view('mail.registration',[\n",[193,241,243],{"class":195,"line":242},9,[193,244,245],{},"        'applay_user_name'=>$name,\n",[193,247,249],{"class":195,"line":248},10,[193,250,251],{},"    ])->text('mail.registration_text',[ \u002F\u002F これ！\n",[193,253,255],{"class":195,"line":254},11,[193,256,245],{},[193,258,260],{"class":195,"line":259},12,[193,261,262],{},"    ])\n",[193,264,266],{"class":195,"line":265},13,[193,267,268],{},"    ->subject('登録を受け付けました。');\n",[193,270,272],{"class":195,"line":271},14,[193,273,274],{},"}\n",[13,276,277,280,281,284],{},[25,278,279],{},"text()","メソッドを使用することで前述の解説の様にプレーンテキスト用のmultipartを入れ込んでくれます。なお、引数は",[25,282,283],{},"view()","メソッドと同じでテンプレートファイルとデータを渡すことができます。この記法はLaravel5.3から利用できます。",[13,286,287,288],{},"参考\n",[36,289,292],{"href":290,"rel":291},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fmail#plain-text-emails",[40],"Laravel9 Mail",[133,294,295],{"id":295},"テンプレートの記述とファイル構成のすすめ",[13,297,298],{},"私の場合は以下の様な構成とファイル名でメールテンプレートを管理しています。",[49,300,303],{"className":301,"code":302,"language":54},[52],"views\n│\n├── mail\n    ├── master.blade.php\n    ├── master_text.blade.php\n    ├── register.blade.php\n    └── register_text.blade.php\n",[25,304,302],{"__ignoreMap":57},[13,306,307,308,311,312,315,316,319],{},"まずviewsでmail用のテンプレートを格納するディレクトリ を作成し、そしてHプレーンテキスト用のテンプレートはTML用のものに",[25,309,310],{},"_text","をつけておきます。そして",[25,313,314],{},"master.blade.php","はレイアウトやHTMLのスタイルを定義しています。同じようにプレーン用のレイアウトファイルの",[25,317,318],{},"master_text.blade.php","を用意しておくといいです。",[49,321,324],{"className":188,"code":322,"filename":323,"language":106,"meta":57,"style":57},"{{$name}}様\n\u003Cp>いつもご利用いただきありがとうございます。\u003C\u002Fp>\n...\n","register.blade.php",[25,325,326,331,336],{"__ignoreMap":57},[193,327,328],{"class":195,"line":196},[193,329,330],{},"{{$name}}様\n",[193,332,333],{"class":195,"line":93},[193,334,335],{},"\u003Cp>いつもご利用いただきありがとうございます。\u003C\u002Fp>\n",[193,337,338],{"class":195,"line":90},[193,339,340],{},"...\n",[49,342,345],{"className":188,"code":343,"filename":344,"language":106,"meta":57,"style":57},"{{$name}}様\nいつもご利用いただきありがとうございます。\n...\n","register_text.blade.php",[25,346,347,351,356],{"__ignoreMap":57},[193,348,349],{"class":195,"line":196},[193,350,330],{},[193,352,353],{"class":195,"line":93},[193,354,355],{},"いつもご利用いただきありがとうございます。\n",[193,357,358],{"class":195,"line":90},[193,359,340],{},[17,361,362],{"id":362},"notifiableの場合",[13,364,365,366,369],{},"これはLaravel8しか確認していませんが、Notifiableで使用されるMailMessageの場合はプレーンテキストが自動的に作成されていました。以下の様に",[25,367,368],{},"toMail()","を作成しておけばHTMLもプレーンも送付されていました。",[49,371,373],{"className":188,"code":372,"language":106,"meta":57,"style":57},"public function toMail($notifiable)\n{\n    return (new MailMessage)\n                ->subject('メールアドレスが変更されました')\n                ->line(\"いつもご利用いただきありがとうございます。\")\n                ->line('連絡用メールアドレスの変更を受け付けました。')\n                ->line('※本メールは送信専用です。ご返信いただいても対応できませんのでご了承ください。')\n                ->line('※本メールにお心当たりがない場合は、恐れ入りますが破棄していただきますようお願いいたします。');\n}\n",[25,374,375,380,384,389,394,399,404,409,414],{"__ignoreMap":57},[193,376,377],{"class":195,"line":196},[193,378,379],{},"public function toMail($notifiable)\n",[193,381,382],{"class":195,"line":93},[193,383,233],{},[193,385,386],{"class":195,"line":90},[193,387,388],{},"    return (new MailMessage)\n",[193,390,391],{"class":195,"line":212},[193,392,393],{},"                ->subject('メールアドレスが変更されました')\n",[193,395,396],{"class":195,"line":218},[193,397,398],{},"                ->line(\"いつもご利用いただきありがとうございます。\")\n",[193,400,401],{"class":195,"line":224},[193,402,403],{},"                ->line('連絡用メールアドレスの変更を受け付けました。')\n",[193,405,406],{"class":195,"line":230},[193,407,408],{},"                ->line('※本メールは送信専用です。ご返信いただいても対応できませんのでご了承ください。')\n",[193,410,411],{"class":195,"line":236},[193,412,413],{},"                ->line('※本メールにお心当たりがない場合は、恐れ入りますが破棄していただきますようお願いいたします。');\n",[193,415,416],{"class":195,"line":242},[193,417,274],{},[419,420,421],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":57,"searchDepth":90,"depth":90,"links":423},[424,428,431],{"id":120,"depth":93,"text":121,"children":425},[426,427],{"id":135,"depth":90,"text":136},{"id":151,"depth":90,"text":152},{"id":181,"depth":93,"text":182,"children":429},[430],{"id":295,"depth":90,"text":295},{"id":362,"depth":93,"text":362},[96],"2022-03-07","LaravelのMilableでHTMLメールとプレーンテキストメール両方を送信する方法",{},"\u002Farticles\u002Flaravel-plain-text-with-html",{"title":112,"description":434},"articles\u002Flaravel-plain-text-with-html",[440,106,441],"laravel","network","Ru_0w8TnRhwaXPjcr0gSRvxAArbPnEm7l-VCgPS-v6w",{"id":444,"title":445,"body":446,"category":962,"createdAt":963,"description":964,"extension":98,"index":99,"meta":965,"navigation":101,"path":966,"publish":101,"seo":967,"series":99,"seriesTitle":99,"stem":968,"tag":969,"thumbnail":99,"updatedAt":99,"__hash__":970},"articles\u002Farticles\u002Fphpspredsheet-rich-text.md","Phpspreadsheetで書式があるとgetValue()で文字を取得できない",{"type":10,"value":447,"toc":960},[448,457,506,520,523,882,890,903,909,922,955,958],[13,449,450,451,456],{},"こんにちはjunです。PHPでエクセルをアップロードして、データを取得するという機能を実装する際に",[36,452,455],{"href":453,"rel":454},"https:\u002F\u002Fphpspreadsheet.readthedocs.io\u002Fen\u002Flatest\u002F",[40],"Phpspreadsheet","を使用することが多いと思います。アップロードされたエクセルを以下の様にしてセルの値を取得することができます。",[49,458,460],{"className":188,"code":459,"language":106,"meta":57,"style":57},"use \\PhpOffice\\PhpSpreadsheet\\IOFactory;\nuse \\PhpOffice\\PhpSpreadsheet\\Shared\\Date;\n\n\u002F\u002F $fileはエクセルファイル\n$spreadsheet = IOFactory::load($file);\n$worksheet = $spreadsheet->getSheetByName('Sheet1');\n\n\u002F\u002F A1のセルのデータを取得する\n$workSheet->getCell(\"A1\")->getValue();\n",[25,461,462,467,472,477,482,487,492,496,501],{"__ignoreMap":57},[193,463,464],{"class":195,"line":196},[193,465,466],{},"use \\PhpOffice\\PhpSpreadsheet\\IOFactory;\n",[193,468,469],{"class":195,"line":93},[193,470,471],{},"use \\PhpOffice\\PhpSpreadsheet\\Shared\\Date;\n",[193,473,474],{"class":195,"line":90},[193,475,476],{"emptyLinePlaceholder":101},"\n",[193,478,479],{"class":195,"line":212},[193,480,481],{},"\u002F\u002F $fileはエクセルファイル\n",[193,483,484],{"class":195,"line":218},[193,485,486],{},"$spreadsheet = IOFactory::load($file);\n",[193,488,489],{"class":195,"line":224},[193,490,491],{},"$worksheet = $spreadsheet->getSheetByName('Sheet1');\n",[193,493,494],{"class":195,"line":230},[193,495,476],{"emptyLinePlaceholder":101},[193,497,498],{"class":195,"line":236},[193,499,500],{},"\u002F\u002F A1のセルのデータを取得する\n",[193,502,503],{"class":195,"line":242},[193,504,505],{},"$workSheet->getCell(\"A1\")->getValue();\n",[13,507,508,511,512,515,516,519],{},[25,509,510],{},"getCell()","の引数を指定して再帰的に全ての列の値を取得して配列にするみたいなこともできるので、エクセルを用いてwebアプリへのデータ入力ができます。最初は",[25,513,514],{},"getValue()","を用いて問題なくセルの文字を取得できていました。しかしある日、お客さんから「このエクセルを読み取らせると変な文字が表示されます」という問い合わせをいただきました。サーバーにアップしたエクセルの内容を上記の様に取得してブラウザに表示するということをやっていたのですが、確かに",[25,517,518],{},"{}","という謎の文字がありました。",[13,521,522],{},"デバッグログを見てみると下記の様に一部の値がインスタンスとなっていました。",[49,524,526],{"className":188,"code":525,"language":106,"meta":57,"style":57},"array(\n'name' => \n  PhpOffice\\PhpSpreadsheet\\RichText\\RichText::__set_state(array(\n     'richTextElements' => \n    array (\n      0 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\TextElement::__set_state(array(\n         'text' => 'テスト',\n      )),\n      1 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n         'font' => \n        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n           'name' => '游ゴシック',\n           'size' => 12.0,\n           'bold' => false,\n           'italic' => false,\n           'superscript' => false,\n           'subscript' => false,\n           'underline' => 'none',\n           'strikethrough' => false,\n           'color' => \n          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n             'argb' => 'FF000000',\n             'hasChanged' => false,\n             'isSupervisor' => false,\n             'parent' => NULL,\n             'parentPropertyName' => NULL,\n          )),\n           'colorIndex' => NULL,\n           'isSupervisor' => false,\n           'parent' => NULL,\n           'parentPropertyName' => NULL,\n        )),\n         'text' => 'テス',\n      )),\n      2 => \n      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n         'font' => \n        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n           'name' => '游ゴシック',\n           'size' => 12.0,\n           'bold' => false,\n           'italic' => false,\n           'superscript' => false,\n           'subscript' => false,\n           'underline' => 'none',\n           'strikethrough' => false,\n           'color' => \n          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n             'argb' => 'FF000000',\n             'hasChanged' => false,\n             'isSupervisor' => false,\n             'parent' => NULL,\n             'parentPropertyName' => NULL,\n          )),\n           'colorIndex' => NULL,\n           'isSupervisor' => false,\n           'parent' => NULL,\n           'parentPropertyName' => NULL,\n        )),\n         'text' => 'テスト',\n      )),\n    ),\n  )),\n)\n",[25,527,528,533,538,543,548,553,558,563,568,573,578,583,588,593,598,604,610,616,622,628,634,640,646,652,658,664,670,676,682,688,694,700,706,712,718,724,729,735,740,745,750,755,760,765,770,775,780,785,790,795,800,805,810,815,820,825,830,835,840,845,850,855,860,864,870,876],{"__ignoreMap":57},[193,529,530],{"class":195,"line":196},[193,531,532],{},"array(\n",[193,534,535],{"class":195,"line":93},[193,536,537],{},"'name' => \n",[193,539,540],{"class":195,"line":90},[193,541,542],{},"  PhpOffice\\PhpSpreadsheet\\RichText\\RichText::__set_state(array(\n",[193,544,545],{"class":195,"line":212},[193,546,547],{},"     'richTextElements' => \n",[193,549,550],{"class":195,"line":218},[193,551,552],{},"    array (\n",[193,554,555],{"class":195,"line":224},[193,556,557],{},"      0 => \n",[193,559,560],{"class":195,"line":230},[193,561,562],{},"      PhpOffice\\PhpSpreadsheet\\RichText\\TextElement::__set_state(array(\n",[193,564,565],{"class":195,"line":236},[193,566,567],{},"         'text' => 'テスト',\n",[193,569,570],{"class":195,"line":242},[193,571,572],{},"      )),\n",[193,574,575],{"class":195,"line":248},[193,576,577],{},"      1 => \n",[193,579,580],{"class":195,"line":254},[193,581,582],{},"      PhpOffice\\PhpSpreadsheet\\RichText\\Run::__set_state(array(\n",[193,584,585],{"class":195,"line":259},[193,586,587],{},"         'font' => \n",[193,589,590],{"class":195,"line":265},[193,591,592],{},"        PhpOffice\\PhpSpreadsheet\\Style\\Font::__set_state(array(\n",[193,594,595],{"class":195,"line":271},[193,596,597],{},"           'name' => '游ゴシック',\n",[193,599,601],{"class":195,"line":600},15,[193,602,603],{},"           'size' => 12.0,\n",[193,605,607],{"class":195,"line":606},16,[193,608,609],{},"           'bold' => false,\n",[193,611,613],{"class":195,"line":612},17,[193,614,615],{},"           'italic' => false,\n",[193,617,619],{"class":195,"line":618},18,[193,620,621],{},"           'superscript' => false,\n",[193,623,625],{"class":195,"line":624},19,[193,626,627],{},"           'subscript' => false,\n",[193,629,631],{"class":195,"line":630},20,[193,632,633],{},"           'underline' => 'none',\n",[193,635,637],{"class":195,"line":636},21,[193,638,639],{},"           'strikethrough' => false,\n",[193,641,643],{"class":195,"line":642},22,[193,644,645],{},"           'color' => \n",[193,647,649],{"class":195,"line":648},23,[193,650,651],{},"          PhpOffice\\PhpSpreadsheet\\Style\\Color::__set_state(array(\n",[193,653,655],{"class":195,"line":654},24,[193,656,657],{},"             'argb' => 'FF000000',\n",[193,659,661],{"class":195,"line":660},25,[193,662,663],{},"             'hasChanged' => false,\n",[193,665,667],{"class":195,"line":666},26,[193,668,669],{},"             'isSupervisor' => false,\n",[193,671,673],{"class":195,"line":672},27,[193,674,675],{},"             'parent' => NULL,\n",[193,677,679],{"class":195,"line":678},28,[193,680,681],{},"             'parentPropertyName' => NULL,\n",[193,683,685],{"class":195,"line":684},29,[193,686,687],{},"          )),\n",[193,689,691],{"class":195,"line":690},30,[193,692,693],{},"           'colorIndex' => NULL,\n",[193,695,697],{"class":195,"line":696},31,[193,698,699],{},"           'isSupervisor' => false,\n",[193,701,703],{"class":195,"line":702},32,[193,704,705],{},"           'parent' => NULL,\n",[193,707,709],{"class":195,"line":708},33,[193,710,711],{},"           'parentPropertyName' => NULL,\n",[193,713,715],{"class":195,"line":714},34,[193,716,717],{},"        )),\n",[193,719,721],{"class":195,"line":720},35,[193,722,723],{},"         'text' => 'テス',\n",[193,725,727],{"class":195,"line":726},36,[193,728,572],{},[193,730,732],{"class":195,"line":731},37,[193,733,734],{},"      2 => \n",[193,736,738],{"class":195,"line":737},38,[193,739,582],{},[193,741,743],{"class":195,"line":742},39,[193,744,587],{},[193,746,748],{"class":195,"line":747},40,[193,749,592],{},[193,751,753],{"class":195,"line":752},41,[193,754,597],{},[193,756,758],{"class":195,"line":757},42,[193,759,603],{},[193,761,763],{"class":195,"line":762},43,[193,764,609],{},[193,766,768],{"class":195,"line":767},44,[193,769,615],{},[193,771,773],{"class":195,"line":772},45,[193,774,621],{},[193,776,778],{"class":195,"line":777},46,[193,779,627],{},[193,781,783],{"class":195,"line":782},47,[193,784,633],{},[193,786,788],{"class":195,"line":787},48,[193,789,639],{},[193,791,793],{"class":195,"line":792},49,[193,794,645],{},[193,796,798],{"class":195,"line":797},50,[193,799,651],{},[193,801,803],{"class":195,"line":802},51,[193,804,657],{},[193,806,808],{"class":195,"line":807},52,[193,809,663],{},[193,811,813],{"class":195,"line":812},53,[193,814,669],{},[193,816,818],{"class":195,"line":817},54,[193,819,675],{},[193,821,823],{"class":195,"line":822},55,[193,824,681],{},[193,826,828],{"class":195,"line":827},56,[193,829,687],{},[193,831,833],{"class":195,"line":832},57,[193,834,693],{},[193,836,838],{"class":195,"line":837},58,[193,839,699],{},[193,841,843],{"class":195,"line":842},59,[193,844,705],{},[193,846,848],{"class":195,"line":847},60,[193,849,711],{},[193,851,853],{"class":195,"line":852},61,[193,854,717],{},[193,856,858],{"class":195,"line":857},62,[193,859,567],{},[193,861,862],{"class":195,"line":4},[193,863,572],{},[193,865,867],{"class":195,"line":866},64,[193,868,869],{},"    ),\n",[193,871,873],{"class":195,"line":872},65,[193,874,875],{},"  )),\n",[193,877,879],{"class":195,"line":878},66,[193,880,881],{},")\n",[13,883,884,885],{},"対象のエクセルのセルを見てみると文字が赤色になっていたりと装飾が当てられていました。原因がわかったので対処を行います。調査の結果似た様なissueがありました。",[36,886,889],{"href":887,"rel":888},"https:\u002F\u002Fgithub.com\u002FPHPOffice\u002FPhpSpreadsheet\u002Fissues\u002F442",[40],"RichText can not get the correct value, when one part is plain text and the other part is rich text.",[13,891,892,893,895,896,899,900,902],{},"方法としては",[25,894,514],{},"に加えて",[25,897,898],{},"getPlainText()","というメソッドを通すことで装飾されたセルの値（リッチテキスト）を取得することができます。しかし",[25,901,898],{},"には問題があり、なんとリッチテキストでない値に適用すると以下の様エラーが発生します。",[49,904,907],{"className":905,"code":906,"language":54},[52],"Call to a member function getPlainText() on string.\n",[25,908,906],{"__ignoreMap":57},[13,910,911,912,914,915,917,918,921],{},"つまり、",[25,913,514],{},"した時の値がリッチテキストインスタンスであるかをチェックして",[25,916,898],{},"を適用するかを分岐させる必要があります。リッチテキストは",[25,919,920],{},"\\PhpOffice\\PhpSpreadsheet\\RichText\\RichText","というクラスなので以下の様な関数を作成すれば問題ありません。",[49,923,925],{"className":188,"code":924,"language":106,"meta":57,"style":57},"use \\PhpOffice\\PhpSpreadsheet\\RichText\\RichText;\n\nfunction getCellValue($workSheet,$cell){\n    $val = $workSheet->getCell($cell)->getValue();\n    return ($val instanceof RichText)?$val->getPlainText():$val;\n}\n",[25,926,927,932,936,941,946,951],{"__ignoreMap":57},[193,928,929],{"class":195,"line":196},[193,930,931],{},"use \\PhpOffice\\PhpSpreadsheet\\RichText\\RichText;\n",[193,933,934],{"class":195,"line":93},[193,935,476],{"emptyLinePlaceholder":101},[193,937,938],{"class":195,"line":90},[193,939,940],{},"function getCellValue($workSheet,$cell){\n",[193,942,943],{"class":195,"line":212},[193,944,945],{},"    $val = $workSheet->getCell($cell)->getValue();\n",[193,947,948],{"class":195,"line":218},[193,949,950],{},"    return ($val instanceof RichText)?$val->getPlainText():$val;\n",[193,952,953],{"class":195,"line":224},[193,954,274],{},[13,956,957],{},"リッチテキストのインスタンスかをチェックして値を取得することでリッチテキストもプレーンテキストも対応することができました。こう考えるとやっぱりエクセルインポートなんてやめてCSVインポートにしておけばよかったなーと思っています。",[419,959,421],{},{"title":57,"searchDepth":90,"depth":90,"links":961},[],[96],"2022-02-28","書式を当てたセルから文字・値を取得する方法",{},"\u002Farticles\u002Fphpspredsheet-rich-text",{"title":445,"description":964},"articles\u002Fphpspredsheet-rich-text",[106],"vZGoVH1w7p4Zs6BmYkw-9jf7nQBYtDotePnJnccXEz4",{"id":972,"title":973,"body":974,"category":2714,"createdAt":2715,"description":2716,"extension":98,"index":99,"meta":2717,"navigation":101,"path":2718,"publish":101,"seo":2719,"series":99,"seriesTitle":99,"stem":2720,"tag":2721,"thumbnail":99,"updatedAt":99,"__hash__":2724},"articles\u002Farticles\u002Fjs-deep-copy.md","jsで配列内のオブジェクトの値が連動してしまう原因と対処法",{"type":10,"value":975,"toc":2702},[976,983,1143,1156,1159,1167,1275,1282,1287,1290,1295,1298,1302,1309,1322,1324,1332,1335,1535,1558,1616,1619,1621,1624,1627,1636,1640,1651,1820,1823,1827,1838,2021,2028,2237,2240,2244,2254,2261,2451,2454,2458,2461,2516,2519,2696,2699],[13,977,978,979,982],{},"こんにちはjunです。vue.jsとかでアプリを作るととき、一覧ページや複数個のデータを出力する時はオブジェクトが内包された配列データを使用することが多いと思います。例としては以下のような「記事一覧」用の",[25,980,981],{},"posts","データです。",[49,984,988],{"className":985,"code":986,"language":987,"meta":57,"style":57},"language-javascript shiki shiki-themes material-theme-ocean","const posts = [\n    {id:1,title:\"記事タイトル１\",content:\"...\"},\n    {id:2,title:\"記事タイトル２\",content:\"...\"},\n    {id:3,title:\"記事タイトル３\",content:\"...\"},\n    \u002F\u002F ...\n]\n","javascript",[25,989,990,1007,1056,1094,1132,1138],{"__ignoreMap":57},[193,991,992,996,1000,1004],{"class":195,"line":196},[193,993,995],{"class":994},"sJ14y","const",[193,997,999],{"class":998},"s0W1g"," posts ",[193,1001,1003],{"class":1002},"sAklC","=",[193,1005,1006],{"class":998}," [\n",[193,1008,1009,1012,1016,1019,1023,1025,1028,1030,1033,1037,1039,1041,1044,1046,1048,1051,1053],{"class":195,"line":93},[193,1010,1011],{"class":1002},"    {",[193,1013,1015],{"class":1014},"s-wAU","id",[193,1017,1018],{"class":1002},":",[193,1020,1022],{"class":1021},"sx098","1",[193,1024,28],{"class":1002},[193,1026,1027],{"class":1014},"title",[193,1029,1018],{"class":1002},[193,1031,1032],{"class":1002},"\"",[193,1034,1036],{"class":1035},"sfyAc","記事タイトル１",[193,1038,1032],{"class":1002},[193,1040,28],{"class":1002},[193,1042,1043],{"class":1014},"content",[193,1045,1018],{"class":1002},[193,1047,1032],{"class":1002},[193,1049,1050],{"class":1035},"...",[193,1052,1032],{"class":1002},[193,1054,1055],{"class":1002},"},\n",[193,1057,1058,1060,1062,1064,1067,1069,1071,1073,1075,1078,1080,1082,1084,1086,1088,1090,1092],{"class":195,"line":90},[193,1059,1011],{"class":1002},[193,1061,1015],{"class":1014},[193,1063,1018],{"class":1002},[193,1065,1066],{"class":1021},"2",[193,1068,28],{"class":1002},[193,1070,1027],{"class":1014},[193,1072,1018],{"class":1002},[193,1074,1032],{"class":1002},[193,1076,1077],{"class":1035},"記事タイトル２",[193,1079,1032],{"class":1002},[193,1081,28],{"class":1002},[193,1083,1043],{"class":1014},[193,1085,1018],{"class":1002},[193,1087,1032],{"class":1002},[193,1089,1050],{"class":1035},[193,1091,1032],{"class":1002},[193,1093,1055],{"class":1002},[193,1095,1096,1098,1100,1102,1105,1107,1109,1111,1113,1116,1118,1120,1122,1124,1126,1128,1130],{"class":195,"line":212},[193,1097,1011],{"class":1002},[193,1099,1015],{"class":1014},[193,1101,1018],{"class":1002},[193,1103,1104],{"class":1021},"3",[193,1106,28],{"class":1002},[193,1108,1027],{"class":1014},[193,1110,1018],{"class":1002},[193,1112,1032],{"class":1002},[193,1114,1115],{"class":1035},"記事タイトル３",[193,1117,1032],{"class":1002},[193,1119,28],{"class":1002},[193,1121,1043],{"class":1014},[193,1123,1018],{"class":1002},[193,1125,1032],{"class":1002},[193,1127,1050],{"class":1035},[193,1129,1032],{"class":1002},[193,1131,1055],{"class":1002},[193,1133,1134],{"class":195,"line":218},[193,1135,1137],{"class":1136},"sC9rS","    \u002F\u002F ...\n",[193,1139,1140],{"class":195,"line":224},[193,1141,1142],{"class":998},"]\n",[13,1144,1145,1146,1150,1151,1155],{},"今回の記事で解説する内容は上記のような配列を別の変数に格納した時、スプレッド構文を使用して配列を生成したにもかかわらず、オブジェクト内の値が連動してしまったときの対処と原因について解説します。「どんなデータの状況だったか」という実装背景から話すので、ささっと原因からは知りたい人は「",[36,1147,1149],{"href":1148},"#%E5%8E%9F%E5%9B%A0","原因","」へ、解決方法だけ知りたい人は「",[36,1152,1154],{"href":1153},"#%E5%AF%BE%E5%87%A6%E6%B3%95","対処法","」へ移動してください。",[17,1157,1158],{"id":1158},"実装背景",[13,1160,1161,1162,1166],{},"vue.jsで編集画面を実装していた時です。編集画面は「入力された新しい値」と「登録済みの値（DBにある値）」を持たせておき、一部でその差分を確認できるようにするという",[1163,1164,1165],"del",{},"面倒な","実装がありました。内容としては「1日の予定表」みたいなもので、以下のようなデータ構造です。",[49,1168,1170],{"className":985,"code":1169,"language":987,"meta":57,"style":57},"const DATA_FROM_DB = response.data;\n\nconsole.log(DATA_FROM_DB);\n\u002F**\n{\n    date:\"2021-11-01\", \n    memo:\"...\",\n    todo:   \u002F\u002F この日の予定を入れる。\n    [\n        {id:1,content:\"AAAA\"},\n        {id:2,content:\"BBBB\"},\n        {id:3,content:\"CCCC\"},\n        ...\n    ]\n}\n**\u002F\n\n",[25,1171,1172,1193,1197,1213,1217,1221,1226,1231,1236,1241,1246,1251,1256,1261,1266,1270],{"__ignoreMap":57},[193,1173,1174,1176,1179,1181,1184,1187,1190],{"class":195,"line":196},[193,1175,995],{"class":994},[193,1177,1178],{"class":998}," DATA_FROM_DB ",[193,1180,1003],{"class":1002},[193,1182,1183],{"class":998}," response",[193,1185,1186],{"class":1002},".",[193,1188,1189],{"class":998},"data",[193,1191,1192],{"class":1002},";\n",[193,1194,1195],{"class":195,"line":93},[193,1196,476],{"emptyLinePlaceholder":101},[193,1198,1199,1202,1204,1208,1211],{"class":195,"line":90},[193,1200,1201],{"class":998},"console",[193,1203,1186],{"class":1002},[193,1205,1207],{"class":1206},"sdLwU","log",[193,1209,1210],{"class":998},"(DATA_FROM_DB)",[193,1212,1192],{"class":1002},[193,1214,1215],{"class":195,"line":212},[193,1216,199],{"class":1136},[193,1218,1219],{"class":195,"line":218},[193,1220,233],{"class":1136},[193,1222,1223],{"class":195,"line":224},[193,1224,1225],{"class":1136},"    date:\"2021-11-01\", \n",[193,1227,1228],{"class":195,"line":230},[193,1229,1230],{"class":1136},"    memo:\"...\",\n",[193,1232,1233],{"class":195,"line":236},[193,1234,1235],{"class":1136},"    todo:   \u002F\u002F この日の予定を入れる。\n",[193,1237,1238],{"class":195,"line":242},[193,1239,1240],{"class":1136},"    [\n",[193,1242,1243],{"class":195,"line":248},[193,1244,1245],{"class":1136},"        {id:1,content:\"AAAA\"},\n",[193,1247,1248],{"class":195,"line":254},[193,1249,1250],{"class":1136},"        {id:2,content:\"BBBB\"},\n",[193,1252,1253],{"class":195,"line":259},[193,1254,1255],{"class":1136},"        {id:3,content:\"CCCC\"},\n",[193,1257,1258],{"class":195,"line":265},[193,1259,1260],{"class":1136},"        ...\n",[193,1262,1263],{"class":195,"line":271},[193,1264,1265],{"class":1136},"    ]\n",[193,1267,1268],{"class":195,"line":600},[193,1269,274],{"class":1136},[193,1271,1272],{"class":195,"line":606},[193,1273,1274],{"class":1136},"**\u002F\n",[13,1276,1277,1278,1281],{},"上記データの ",[25,1279,1280],{},"DATA_FROM_DB.todo"," の変更前のデータを確認できるようにする必要があります。実装のためには別の定数なりに格納しておく必要があります。私はもちろん「参照渡し」・「値渡し」の概念は知っていたので、",[13,1283,1284],{},[25,1285,1286],{},"const OLD_TODO_DATA = DATA_FROM_DB.todo;",[13,1288,1289],{},"なんてことせず、",[13,1291,1292],{},[25,1293,1294],{},"const OLD_TODO_DATA = [...DATA_FROM_DB.todo];",[13,1296,1297],{},"とスプレッド構文を使用して新しく配列を生成しました。これで大丈夫だろと思っていましたが。。",[133,1299,1301],{"id":1300},"事件は起きた","事件は起きた。",[13,1303,1304,1305,1308],{},"新しいTODOと元のTODOを画面上に表示させて、TODO編集をテストしていた時です。新しくTODOを変更しているはずなに、古い ",[25,1306,1307],{},"OLD_TODO_DATA","から表示している内容も同じ変更した値に切り替わっていました。つまり値が連動していたのです。「WHY?」と声を出してしまいました。開発ツールで見ていても同じ値になっていることが確認できました。値が参照渡しされているとすぐに気づきましたが、「スプレッド構文を使用したのに...」と対処方法ずっと考えていました。",[1310,1311,1315,1316,1321],"div",{"className":1312},[1313,1314],"alert","alert-info","\nここでは値渡しと参照渡しの概念は解説しません。知らない方は",[36,1317,1320],{"target":1318,"href":1319},"_blank","https:\u002F\u002Fwww.google.com\u002Fsearch?q=js+%E5%80%A4%E6%B8%A1%E3%81%97+%E5%8F%82%E7%85%A7%E6%B8%A1%E3%81%97&oq=js+%E5%80%A4%E6%B8%A1%E3%81%97+%E5%8F%82%E7%85%A7%E6%B8%A1%E3%81%97&aqs=chrome..69i57.290j0j7&sourceid=chrome&ie=UTF-8","「js 値渡し 参照渡し」","でググってください。\n",[17,1323,1149],{"id":1149},[13,1325,1326,1327,1331],{},"原因は内包されたオブジェクトが参照渡しされていたからなのです。スプレッド構文は使用しましたが、これはあくまで",[1328,1329,1330],"strong",{},"別の配列","を作っただけであり、中身のオブジェクトの参照は維持されて（コピー元を参照して）いたのです。",[13,1333,1334],{},"以下のような実験をコンソールでしてみます。",[49,1336,1338],{"className":985,"code":1337,"filename":1201,"language":987,"meta":57,"style":57},"> const origin =[{id:1,content:\"1111\"},{id:2,content:\"2222\"}];\n\n> const passbyval = origin;\n\n> const spred = [...origin];\n\n> origin === passbyval;\n\u002F\u002F true\n\n> origin === spred;\n\u002F\u002F false\n\n> origin[0] === spred[0];\n\u002F\u002F true\n\u002F\u002F WHY!?\n",[25,1339,1340,1408,1412,1428,1432,1453,1457,1471,1476,1480,1493,1498,1502,1526,1530],{"__ignoreMap":57},[193,1341,1342,1345,1348,1351,1353,1356,1359,1361,1363,1365,1367,1369,1371,1373,1376,1378,1381,1383,1385,1387,1389,1391,1393,1395,1398,1400,1403,1406],{"class":195,"line":196},[193,1343,1344],{"class":1002},">",[193,1346,1347],{"class":994}," const",[193,1349,1350],{"class":998}," origin ",[193,1352,1003],{"class":1002},[193,1354,1355],{"class":998},"[",[193,1357,1358],{"class":1002},"{",[193,1360,1015],{"class":1014},[193,1362,1018],{"class":1002},[193,1364,1022],{"class":1021},[193,1366,28],{"class":1002},[193,1368,1043],{"class":1014},[193,1370,1018],{"class":1002},[193,1372,1032],{"class":1002},[193,1374,1375],{"class":1035},"1111",[193,1377,1032],{"class":1002},[193,1379,1380],{"class":1002},"},{",[193,1382,1015],{"class":1014},[193,1384,1018],{"class":1002},[193,1386,1066],{"class":1021},[193,1388,28],{"class":1002},[193,1390,1043],{"class":1014},[193,1392,1018],{"class":1002},[193,1394,1032],{"class":1002},[193,1396,1397],{"class":1035},"2222",[193,1399,1032],{"class":1002},[193,1401,1402],{"class":1002},"}",[193,1404,1405],{"class":998},"]",[193,1407,1192],{"class":1002},[193,1409,1410],{"class":195,"line":93},[193,1411,476],{"emptyLinePlaceholder":101},[193,1413,1414,1416,1418,1421,1423,1426],{"class":195,"line":90},[193,1415,1344],{"class":1002},[193,1417,1347],{"class":994},[193,1419,1420],{"class":998}," passbyval ",[193,1422,1003],{"class":1002},[193,1424,1425],{"class":998}," origin",[193,1427,1192],{"class":1002},[193,1429,1430],{"class":195,"line":212},[193,1431,476],{"emptyLinePlaceholder":101},[193,1433,1434,1436,1438,1441,1443,1446,1448,1451],{"class":195,"line":218},[193,1435,1344],{"class":1002},[193,1437,1347],{"class":994},[193,1439,1440],{"class":998}," spred ",[193,1442,1003],{"class":1002},[193,1444,1445],{"class":998}," [",[193,1447,1050],{"class":1002},[193,1449,1450],{"class":998},"origin]",[193,1452,1192],{"class":1002},[193,1454,1455],{"class":195,"line":224},[193,1456,476],{"emptyLinePlaceholder":101},[193,1458,1459,1461,1463,1466,1469],{"class":195,"line":230},[193,1460,1344],{"class":1002},[193,1462,1350],{"class":998},[193,1464,1465],{"class":1002},"===",[193,1467,1468],{"class":998}," passbyval",[193,1470,1192],{"class":1002},[193,1472,1473],{"class":195,"line":236},[193,1474,1475],{"class":1136},"\u002F\u002F true\n",[193,1477,1478],{"class":195,"line":242},[193,1479,476],{"emptyLinePlaceholder":101},[193,1481,1482,1484,1486,1488,1491],{"class":195,"line":248},[193,1483,1344],{"class":1002},[193,1485,1350],{"class":998},[193,1487,1465],{"class":1002},[193,1489,1490],{"class":998}," spred",[193,1492,1192],{"class":1002},[193,1494,1495],{"class":195,"line":254},[193,1496,1497],{"class":1136},"\u002F\u002F false\n",[193,1499,1500],{"class":195,"line":259},[193,1501,476],{"emptyLinePlaceholder":101},[193,1503,1504,1506,1509,1512,1515,1517,1520,1522,1524],{"class":195,"line":265},[193,1505,1344],{"class":1002},[193,1507,1508],{"class":998}," origin[",[193,1510,1511],{"class":1021},"0",[193,1513,1514],{"class":998},"] ",[193,1516,1465],{"class":1002},[193,1518,1519],{"class":998}," spred[",[193,1521,1511],{"class":1021},[193,1523,1405],{"class":998},[193,1525,1192],{"class":1002},[193,1527,1528],{"class":195,"line":271},[193,1529,1475],{"class":1136},[193,1531,1532],{"class":195,"line":600},[193,1533,1534],{"class":1136},"\u002F\u002F WHY!?\n",[13,1536,1537,1538,1541,1542,1545,1546,1549,1550,1553,1554,1557],{},"上記が示すとおり、スプレッド構文を使用することで配列としては別物の",[25,1539,1540],{},"origin === copy"," は",[25,1543,1544],{},"false","となり、値渡しの",[25,1547,1548],{},"origin === passbyval ","は",[25,1551,1552],{},"true","となります。ただし同じindexのオブジェクトを比較すると、なんと同じになっています。値を変えてみると",[25,1555,1556],{},"spred","も変更されているのが分かります。",[49,1559,1561],{"className":985,"code":1560,"filename":1201,"language":987,"meta":57,"style":57},"> origin[0].content = \"changed!\";\n\n> spred[0];\n\u002F\u002F {id: 1, content: 'changed!'}\n\u002F\u002F contentが変更されている\n",[25,1562,1563,1590,1594,1606,1611],{"__ignoreMap":57},[193,1564,1565,1567,1569,1571,1573,1575,1578,1580,1583,1586,1588],{"class":195,"line":196},[193,1566,1344],{"class":1002},[193,1568,1508],{"class":998},[193,1570,1511],{"class":1021},[193,1572,1405],{"class":998},[193,1574,1186],{"class":1002},[193,1576,1577],{"class":998},"content ",[193,1579,1003],{"class":1002},[193,1581,1582],{"class":1002}," \"",[193,1584,1585],{"class":1035},"changed!",[193,1587,1032],{"class":1002},[193,1589,1192],{"class":1002},[193,1591,1592],{"class":195,"line":93},[193,1593,476],{"emptyLinePlaceholder":101},[193,1595,1596,1598,1600,1602,1604],{"class":195,"line":90},[193,1597,1344],{"class":1002},[193,1599,1519],{"class":998},[193,1601,1511],{"class":1021},[193,1603,1405],{"class":998},[193,1605,1192],{"class":1002},[193,1607,1608],{"class":195,"line":212},[193,1609,1610],{"class":1136},"\u002F\u002F {id: 1, content: 'changed!'}\n",[193,1612,1613],{"class":195,"line":218},[193,1614,1615],{"class":1136},"\u002F\u002F contentが変更されている\n",[13,1617,1618],{},"これが今回起きた原因です。つまり一応スプレッド構文を使用するのは配列の値をコピーするのでは確かに正しいのですが、今回のようなオブジェクトが内包されている場合は別の手法が必要です。",[17,1620,1154],{"id":1154},[13,1622,1623],{},"さて上記のように配列にオブジェクトが内包されている場合は、オブジェクトの参照が維持されたままになるのは確認できました。ではスプレッド構文以外にどうやって中身を値渡しできるでしょうか？",[13,1625,1626],{},"この時とられる方法としては「ディープコピー」があります。今回のように配列内のオブジェクトも値渡ししたいとき、つまり配列の中の深いとこまでマルッと別物としてコピーする処理をディープコピーと言います。",[1310,1628,1631,1632,1635],{"className":1629},[1313,1630],"alert-warning","\nvanilla ES6に",[25,1633,1634],{},"Array.prototype.deepcopy()","みたいなディープコピーを一発で行う関数はありません。以下の３つテクニックを使用します。\n",[133,1637,1639],{"id":1638},"_1jsonstringifyを使う","1:JSON.stringifyを使う",[13,1641,1642,1643,1646,1647,1650],{},"手取り早いのは",[25,1644,1645],{},"JSON.stringify()","を使用してコピー元をJSONにして、すぐに",[25,1648,1649],{},"JSON.parse()","を使用して元に戻します。この際、デコードしたJSONは全く新しい値となるので参照を断ち切ることができます。",[49,1652,1654],{"className":985,"code":1653,"filename":1201,"language":987,"meta":57,"style":57},"> const origin =[{id:1,content:\"1111\"},{id:2,content:\"2222\"}];\n\n> const copyjson = JSON.prase(JSON.stringify(origin));\n\n> copyjson;\n\u002F\u002F [{id:1,content:\"1111\"},{id:2,content:\"2222\"}]\n\n> origin === copyjson;\n\u002F\u002F false\n\n> origin[0] === copyjson[0]\n\u002F\u002F false\n\u002F\u002F よし！\n",[25,1655,1656,1714,1718,1750,1754,1763,1768,1772,1784,1788,1792,1811,1815],{"__ignoreMap":57},[193,1657,1658,1660,1662,1664,1666,1668,1670,1672,1674,1676,1678,1680,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708,1710,1712],{"class":195,"line":196},[193,1659,1344],{"class":1002},[193,1661,1347],{"class":994},[193,1663,1350],{"class":998},[193,1665,1003],{"class":1002},[193,1667,1355],{"class":998},[193,1669,1358],{"class":1002},[193,1671,1015],{"class":1014},[193,1673,1018],{"class":1002},[193,1675,1022],{"class":1021},[193,1677,28],{"class":1002},[193,1679,1043],{"class":1014},[193,1681,1018],{"class":1002},[193,1683,1032],{"class":1002},[193,1685,1375],{"class":1035},[193,1687,1032],{"class":1002},[193,1689,1380],{"class":1002},[193,1691,1015],{"class":1014},[193,1693,1018],{"class":1002},[193,1695,1066],{"class":1021},[193,1697,28],{"class":1002},[193,1699,1043],{"class":1014},[193,1701,1018],{"class":1002},[193,1703,1032],{"class":1002},[193,1705,1397],{"class":1035},[193,1707,1032],{"class":1002},[193,1709,1402],{"class":1002},[193,1711,1405],{"class":998},[193,1713,1192],{"class":1002},[193,1715,1716],{"class":195,"line":93},[193,1717,476],{"emptyLinePlaceholder":101},[193,1719,1720,1722,1724,1727,1729,1732,1734,1737,1740,1742,1745,1748],{"class":195,"line":90},[193,1721,1344],{"class":1002},[193,1723,1347],{"class":994},[193,1725,1726],{"class":998}," copyjson ",[193,1728,1003],{"class":1002},[193,1730,1731],{"class":998}," JSON",[193,1733,1186],{"class":1002},[193,1735,1736],{"class":1206},"prase",[193,1738,1739],{"class":998},"(JSON",[193,1741,1186],{"class":1002},[193,1743,1744],{"class":1206},"stringify",[193,1746,1747],{"class":998},"(origin))",[193,1749,1192],{"class":1002},[193,1751,1752],{"class":195,"line":212},[193,1753,476],{"emptyLinePlaceholder":101},[193,1755,1756,1758,1761],{"class":195,"line":218},[193,1757,1344],{"class":1002},[193,1759,1760],{"class":998}," copyjson",[193,1762,1192],{"class":1002},[193,1764,1765],{"class":195,"line":224},[193,1766,1767],{"class":1136},"\u002F\u002F [{id:1,content:\"1111\"},{id:2,content:\"2222\"}]\n",[193,1769,1770],{"class":195,"line":230},[193,1771,476],{"emptyLinePlaceholder":101},[193,1773,1774,1776,1778,1780,1782],{"class":195,"line":236},[193,1775,1344],{"class":1002},[193,1777,1350],{"class":998},[193,1779,1465],{"class":1002},[193,1781,1760],{"class":998},[193,1783,1192],{"class":1002},[193,1785,1786],{"class":195,"line":242},[193,1787,1497],{"class":1136},[193,1789,1790],{"class":195,"line":248},[193,1791,476],{"emptyLinePlaceholder":101},[193,1793,1794,1796,1798,1800,1802,1804,1807,1809],{"class":195,"line":254},[193,1795,1344],{"class":1002},[193,1797,1508],{"class":998},[193,1799,1511],{"class":1021},[193,1801,1514],{"class":998},[193,1803,1465],{"class":1002},[193,1805,1806],{"class":998}," copyjson[",[193,1808,1511],{"class":1021},[193,1810,1142],{"class":998},[193,1812,1813],{"class":195,"line":259},[193,1814,1497],{"class":1136},[193,1816,1817],{"class":195,"line":265},[193,1818,1819],{"class":1136},"\u002F\u002F よし！\n",[13,1821,1822],{},"JSONエンコードしてデコードする必要はありますが、中身がなんであろうが関係なく展開できるのは良いところです。",[133,1824,1826],{"id":1825},"_2スプレッドとmapを組み合わせる使用箇所が限定的なので微妙","2:スプレッドとmap()を組み合わせる（使用箇所が限定的なので微妙）",[13,1828,1829,1830,1837],{},"スプレッド構文はオブジェクトにも使用できます。しかし今回は配列内にいるのが厄介です。そんな時は ",[36,1831,1834],{"href":1832,"rel":1833},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fja\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FArray\u002Fmap",[40],[25,1835,1836],{},"map()","を使用して各々のオブジェクトを展開して、新しい配列を生成します。",[49,1839,1841],{"className":985,"code":1840,"filename":1201,"language":987,"meta":57,"style":57},"> const origin =[{id:1,content:\"1111\"},{id:2,content:\"2222\"}];\n\n> const copymap = origin.map(obj => {return {...obj}});\n\n> copymap;\n\u002F\u002F [{id:1,content:\"1111\"},{id:2,content:\"2222\"}]\n\n> origin === copymap;\n\u002F\u002F false\n\n> origin[0] === copymap[0]\n\u002F\u002F false\n\u002F\u002F よし！\n",[25,1842,1843,1901,1905,1953,1957,1966,1970,1974,1986,1990,1994,2013,2017],{"__ignoreMap":57},[193,1844,1845,1847,1849,1851,1853,1855,1857,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1889,1891,1893,1895,1897,1899],{"class":195,"line":196},[193,1846,1344],{"class":1002},[193,1848,1347],{"class":994},[193,1850,1350],{"class":998},[193,1852,1003],{"class":1002},[193,1854,1355],{"class":998},[193,1856,1358],{"class":1002},[193,1858,1015],{"class":1014},[193,1860,1018],{"class":1002},[193,1862,1022],{"class":1021},[193,1864,28],{"class":1002},[193,1866,1043],{"class":1014},[193,1868,1018],{"class":1002},[193,1870,1032],{"class":1002},[193,1872,1375],{"class":1035},[193,1874,1032],{"class":1002},[193,1876,1380],{"class":1002},[193,1878,1015],{"class":1014},[193,1880,1018],{"class":1002},[193,1882,1066],{"class":1021},[193,1884,28],{"class":1002},[193,1886,1043],{"class":1014},[193,1888,1018],{"class":1002},[193,1890,1032],{"class":1002},[193,1892,1397],{"class":1035},[193,1894,1032],{"class":1002},[193,1896,1402],{"class":1002},[193,1898,1405],{"class":998},[193,1900,1192],{"class":1002},[193,1902,1903],{"class":195,"line":93},[193,1904,476],{"emptyLinePlaceholder":101},[193,1906,1907,1909,1911,1914,1916,1918,1920,1923,1926,1930,1933,1936,1940,1943,1945,1948,1951],{"class":195,"line":90},[193,1908,1344],{"class":1002},[193,1910,1347],{"class":994},[193,1912,1913],{"class":998}," copymap ",[193,1915,1003],{"class":1002},[193,1917,1425],{"class":998},[193,1919,1186],{"class":1002},[193,1921,1922],{"class":1206},"map",[193,1924,1925],{"class":998},"(",[193,1927,1929],{"class":1928},"s7ZW3","obj",[193,1931,1932],{"class":994}," =>",[193,1934,1935],{"class":1002}," {",[193,1937,1939],{"class":1938},"s6cf3","return",[193,1941,1942],{"class":1002}," {...",[193,1944,1929],{"class":998},[193,1946,1947],{"class":1002},"}}",[193,1949,1950],{"class":998},")",[193,1952,1192],{"class":1002},[193,1954,1955],{"class":195,"line":212},[193,1956,476],{"emptyLinePlaceholder":101},[193,1958,1959,1961,1964],{"class":195,"line":218},[193,1960,1344],{"class":1002},[193,1962,1963],{"class":998}," copymap",[193,1965,1192],{"class":1002},[193,1967,1968],{"class":195,"line":224},[193,1969,1767],{"class":1136},[193,1971,1972],{"class":195,"line":230},[193,1973,476],{"emptyLinePlaceholder":101},[193,1975,1976,1978,1980,1982,1984],{"class":195,"line":236},[193,1977,1344],{"class":1002},[193,1979,1350],{"class":998},[193,1981,1465],{"class":1002},[193,1983,1963],{"class":998},[193,1985,1192],{"class":1002},[193,1987,1988],{"class":195,"line":242},[193,1989,1497],{"class":1136},[193,1991,1992],{"class":195,"line":248},[193,1993,476],{"emptyLinePlaceholder":101},[193,1995,1996,1998,2000,2002,2004,2006,2009,2011],{"class":195,"line":254},[193,1997,1344],{"class":1002},[193,1999,1508],{"class":998},[193,2001,1511],{"class":1021},[193,2003,1514],{"class":998},[193,2005,1465],{"class":1002},[193,2007,2008],{"class":998}," copymap[",[193,2010,1511],{"class":1021},[193,2012,1142],{"class":998},[193,2014,2015],{"class":195,"line":259},[193,2016,1497],{"class":1136},[193,2018,2019],{"class":195,"line":265},[193,2020,1819],{"class":1136},[13,2022,2023,2024,2027],{},"JSONを使うよりスマートですが、配列内がオブジェクト・配列といったiterableなものでないと使えません。今使用した",[25,2025,2026],{},"origin","のような簡単な構成であればいいですが、途中で文字列があったりなど、中身が全てiterableである保証がない場合はエラーが起きる可能性があります。あと以下の様にオブジェクトの中にオブジェクトがあるネストした場合はディープコピーできません！！",[49,2029,2031],{"className":985,"code":2030,"filename":1201,"language":987,"meta":57,"style":57},"> const origin =[{id:1,content:{summery:\"detail1\",detail:\"detail1\"}},{id:2,content:{summery:\"detail2\",detail:\"detail2\"}},];\n\n> const copymap = origin.map(obj => {return {...obj}});\n\n> origin[0] === copymap[0]\n\u002F\u002F false\n\n> origin[0].content === copymap[0].content;\n\u002F\u002F true\n\u002F\u002F んっっ！？\n",[25,2032,2033,2130,2134,2170,2174,2192,2196,2200,2228,2232],{"__ignoreMap":57},[193,2034,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053,2055,2057,2060,2063,2065,2067,2070,2072,2074,2077,2079,2081,2083,2085,2088,2090,2092,2094,2096,2098,2100,2102,2104,2106,2109,2111,2113,2115,2117,2119,2121,2123,2126,2128],{"class":195,"line":196},[193,2036,1344],{"class":1002},[193,2038,1347],{"class":994},[193,2040,1350],{"class":998},[193,2042,1003],{"class":1002},[193,2044,1355],{"class":998},[193,2046,1358],{"class":1002},[193,2048,1015],{"class":1014},[193,2050,1018],{"class":1002},[193,2052,1022],{"class":1021},[193,2054,28],{"class":1002},[193,2056,1043],{"class":1014},[193,2058,2059],{"class":1002},":{",[193,2061,2062],{"class":1014},"summery",[193,2064,1018],{"class":1002},[193,2066,1032],{"class":1002},[193,2068,2069],{"class":1035},"detail1",[193,2071,1032],{"class":1002},[193,2073,28],{"class":1002},[193,2075,2076],{"class":1014},"detail",[193,2078,1018],{"class":1002},[193,2080,1032],{"class":1002},[193,2082,2069],{"class":1035},[193,2084,1032],{"class":1002},[193,2086,2087],{"class":1002},"}},{",[193,2089,1015],{"class":1014},[193,2091,1018],{"class":1002},[193,2093,1066],{"class":1021},[193,2095,28],{"class":1002},[193,2097,1043],{"class":1014},[193,2099,2059],{"class":1002},[193,2101,2062],{"class":1014},[193,2103,1018],{"class":1002},[193,2105,1032],{"class":1002},[193,2107,2108],{"class":1035},"detail2",[193,2110,1032],{"class":1002},[193,2112,28],{"class":1002},[193,2114,2076],{"class":1014},[193,2116,1018],{"class":1002},[193,2118,1032],{"class":1002},[193,2120,2108],{"class":1035},[193,2122,1032],{"class":1002},[193,2124,2125],{"class":1002},"}},",[193,2127,1405],{"class":998},[193,2129,1192],{"class":1002},[193,2131,2132],{"class":195,"line":93},[193,2133,476],{"emptyLinePlaceholder":101},[193,2135,2136,2138,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166,2168],{"class":195,"line":90},[193,2137,1344],{"class":1002},[193,2139,1347],{"class":994},[193,2141,1913],{"class":998},[193,2143,1003],{"class":1002},[193,2145,1425],{"class":998},[193,2147,1186],{"class":1002},[193,2149,1922],{"class":1206},[193,2151,1925],{"class":998},[193,2153,1929],{"class":1928},[193,2155,1932],{"class":994},[193,2157,1935],{"class":1002},[193,2159,1939],{"class":1938},[193,2161,1942],{"class":1002},[193,2163,1929],{"class":998},[193,2165,1947],{"class":1002},[193,2167,1950],{"class":998},[193,2169,1192],{"class":1002},[193,2171,2172],{"class":195,"line":212},[193,2173,476],{"emptyLinePlaceholder":101},[193,2175,2176,2178,2180,2182,2184,2186,2188,2190],{"class":195,"line":218},[193,2177,1344],{"class":1002},[193,2179,1508],{"class":998},[193,2181,1511],{"class":1021},[193,2183,1514],{"class":998},[193,2185,1465],{"class":1002},[193,2187,2008],{"class":998},[193,2189,1511],{"class":1021},[193,2191,1142],{"class":998},[193,2193,2194],{"class":195,"line":224},[193,2195,1497],{"class":1136},[193,2197,2198],{"class":195,"line":230},[193,2199,476],{"emptyLinePlaceholder":101},[193,2201,2202,2204,2206,2208,2210,2212,2214,2216,2218,2220,2222,2224,2226],{"class":195,"line":236},[193,2203,1344],{"class":1002},[193,2205,1508],{"class":998},[193,2207,1511],{"class":1021},[193,2209,1405],{"class":998},[193,2211,1186],{"class":1002},[193,2213,1577],{"class":998},[193,2215,1465],{"class":1002},[193,2217,2008],{"class":998},[193,2219,1511],{"class":1021},[193,2221,1405],{"class":998},[193,2223,1186],{"class":1002},[193,2225,1043],{"class":998},[193,2227,1192],{"class":1002},[193,2229,2230],{"class":195,"line":242},[193,2231,1475],{"class":1136},[193,2233,2234],{"class":195,"line":248},[193,2235,2236],{"class":1136},"\u002F\u002F んっっ！？\n",[13,2238,2239],{},"なのでこのmapとスプレッドは使うのは結構微妙です。",[133,2241,2243],{"id":2242},"_3lodashのclonedeepを使用する","3:lodashのcloneDeep()を使用する",[13,2245,2246,2247,2250,2251,2253],{},"テクニックではないのですがlodashなどのライブラリを用いると、",[25,2248,2249],{},"cloneDeep()","といったディープコピー を行うユーティリティー関数があります。面倒な場合はそれを使ってしまってもいいと思います。なんか方法１のJSONよりもlodashの",[25,2252,2249],{},"の方が早いみたいです。",[13,2255,2256],{},[36,2257,2260],{"href":2258,"rel":2259},"https:\u002F\u002Fqiita.com\u002Fsuin\u002Fitems\u002F80e687dd1789b9d9d2fd",[40],"参考：JavaScriptのディープコピー速さ比較 〜7つの手法\u002Fライブラリを比べてみた〜",[49,2262,2264],{"className":985,"code":2263,"filename":1201,"language":987,"meta":57,"style":57},"> const origin =[{id:1,content:{summery:\"detail1\",detail:\"detail1\"}},{id:2,content:{summery:\"detail2\",detail:\"detail2\"}},];\n\n> const copy_ =  _.cloneDeep(origin);\n\n> origin[0] === copy_[0]\n\u002F\u002F false\n\n> origin[0].content === copy_[0].content;\n\u002F\u002F false\n\u002F\u002F よし！\n",[25,2265,2266,2356,2360,2384,2388,2407,2411,2415,2443,2447],{"__ignoreMap":57},[193,2267,2268,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290,2292,2294,2296,2298,2300,2302,2304,2306,2308,2310,2312,2314,2316,2318,2320,2322,2324,2326,2328,2330,2332,2334,2336,2338,2340,2342,2344,2346,2348,2350,2352,2354],{"class":195,"line":196},[193,2269,1344],{"class":1002},[193,2271,1347],{"class":994},[193,2273,1350],{"class":998},[193,2275,1003],{"class":1002},[193,2277,1355],{"class":998},[193,2279,1358],{"class":1002},[193,2281,1015],{"class":1014},[193,2283,1018],{"class":1002},[193,2285,1022],{"class":1021},[193,2287,28],{"class":1002},[193,2289,1043],{"class":1014},[193,2291,2059],{"class":1002},[193,2293,2062],{"class":1014},[193,2295,1018],{"class":1002},[193,2297,1032],{"class":1002},[193,2299,2069],{"class":1035},[193,2301,1032],{"class":1002},[193,2303,28],{"class":1002},[193,2305,2076],{"class":1014},[193,2307,1018],{"class":1002},[193,2309,1032],{"class":1002},[193,2311,2069],{"class":1035},[193,2313,1032],{"class":1002},[193,2315,2087],{"class":1002},[193,2317,1015],{"class":1014},[193,2319,1018],{"class":1002},[193,2321,1066],{"class":1021},[193,2323,28],{"class":1002},[193,2325,1043],{"class":1014},[193,2327,2059],{"class":1002},[193,2329,2062],{"class":1014},[193,2331,1018],{"class":1002},[193,2333,1032],{"class":1002},[193,2335,2108],{"class":1035},[193,2337,1032],{"class":1002},[193,2339,28],{"class":1002},[193,2341,2076],{"class":1014},[193,2343,1018],{"class":1002},[193,2345,1032],{"class":1002},[193,2347,2108],{"class":1035},[193,2349,1032],{"class":1002},[193,2351,2125],{"class":1002},[193,2353,1405],{"class":998},[193,2355,1192],{"class":1002},[193,2357,2358],{"class":195,"line":93},[193,2359,476],{"emptyLinePlaceholder":101},[193,2361,2362,2364,2366,2369,2371,2374,2376,2379,2382],{"class":195,"line":90},[193,2363,1344],{"class":1002},[193,2365,1347],{"class":994},[193,2367,2368],{"class":998}," copy_ ",[193,2370,1003],{"class":1002},[193,2372,2373],{"class":998},"  _",[193,2375,1186],{"class":1002},[193,2377,2378],{"class":1206},"cloneDeep",[193,2380,2381],{"class":998},"(origin)",[193,2383,1192],{"class":1002},[193,2385,2386],{"class":195,"line":212},[193,2387,476],{"emptyLinePlaceholder":101},[193,2389,2390,2392,2394,2396,2398,2400,2403,2405],{"class":195,"line":218},[193,2391,1344],{"class":1002},[193,2393,1508],{"class":998},[193,2395,1511],{"class":1021},[193,2397,1514],{"class":998},[193,2399,1465],{"class":1002},[193,2401,2402],{"class":998}," copy_[",[193,2404,1511],{"class":1021},[193,2406,1142],{"class":998},[193,2408,2409],{"class":195,"line":224},[193,2410,1497],{"class":1136},[193,2412,2413],{"class":195,"line":230},[193,2414,476],{"emptyLinePlaceholder":101},[193,2416,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437,2439,2441],{"class":195,"line":236},[193,2418,1344],{"class":1002},[193,2420,1508],{"class":998},[193,2422,1511],{"class":1021},[193,2424,1405],{"class":998},[193,2426,1186],{"class":1002},[193,2428,1577],{"class":998},[193,2430,1465],{"class":1002},[193,2432,2402],{"class":998},[193,2434,1511],{"class":1021},[193,2436,1405],{"class":998},[193,2438,1186],{"class":1002},[193,2440,1043],{"class":998},[193,2442,1192],{"class":1002},[193,2444,2445],{"class":195,"line":242},[193,2446,1497],{"class":1136},[193,2448,2449],{"class":195,"line":248},[193,2450,1819],{"class":1136},[13,2452,2453],{},"ちなみに方法１のJSONもネストしたオブジェクトの参照は断ち切れます。",[17,2455,2457],{"id":2456},"ライブラリかjson変換を使うといい","ライブラリかJSON変換を使うといい",[13,2459,2460],{},"以上が配列内のオブジェクトの値が連動してしまう原因と対処法です。正確には配列内にオブジェクトを含む場合や、オブジェクト内にオブジェクトを含む値コピーする時は「ディープコピー 」を使いましょうというお話です。ネストしたオブジェクトは今回解説した様に、参照が根深く残っています。アプリによっては以下のような単純な構造でなく、",[49,2462,2464],{"className":985,"code":2463,"language":987,"meta":57,"style":57},"[{id:1,content:\"1111\"},{id:2,content:\"2222\"}];\n",[25,2465,2466],{"__ignoreMap":57},[193,2467,2468,2470,2472,2474,2476,2478,2480,2482,2484,2486,2488,2490,2492,2494,2496,2498,2500,2502,2504,2506,2508,2510,2512,2514],{"class":195,"line":196},[193,2469,1355],{"class":998},[193,2471,1358],{"class":1002},[193,2473,1015],{"class":1014},[193,2475,1018],{"class":1002},[193,2477,1022],{"class":1021},[193,2479,28],{"class":1002},[193,2481,1043],{"class":1014},[193,2483,1018],{"class":1002},[193,2485,1032],{"class":1002},[193,2487,1375],{"class":1035},[193,2489,1032],{"class":1002},[193,2491,1380],{"class":1002},[193,2493,1015],{"class":1014},[193,2495,1018],{"class":1002},[193,2497,1066],{"class":1021},[193,2499,28],{"class":1002},[193,2501,1043],{"class":1014},[193,2503,1018],{"class":1002},[193,2505,1032],{"class":1002},[193,2507,1397],{"class":1035},[193,2509,1032],{"class":1002},[193,2511,1402],{"class":1002},[193,2513,1405],{"class":998},[193,2515,1192],{"class":1002},[13,2517,2518],{},"以下のように内包する値も複雑で、さらにオブジェクトがネストしていることもあります。",[49,2520,2522],{"className":985,"code":2521,"language":987,"meta":57,"style":57},"const origin = {\n    title: \"...\", \u002F\u002F 途中にiterableでないものがある。\n    todo:[\n            {\n                id:1,\n                \u002F\u002F オブジェクトがネストしている\n                content:{\n                    summery:\"detail1\",detail:\"detail1\"\n                }\n            },\n            {\n                id:2,\n                content:{\n                    summery:\"detail2\",detail:\"detail2\"\n                }\n            }\n        ];\n    \u002F\u002F More unpredictable properties..\n}\n",[25,2523,2524,2535,2553,2563,2568,2580,2585,2593,2619,2624,2629,2633,2643,2649,2673,2677,2682,2687,2692],{"__ignoreMap":57},[193,2525,2526,2528,2530,2532],{"class":195,"line":196},[193,2527,995],{"class":994},[193,2529,1350],{"class":998},[193,2531,1003],{"class":1002},[193,2533,2534],{"class":1002}," {\n",[193,2536,2537,2540,2542,2544,2546,2548,2550],{"class":195,"line":93},[193,2538,2539],{"class":1014},"    title",[193,2541,1018],{"class":1002},[193,2543,1582],{"class":1002},[193,2545,1050],{"class":1035},[193,2547,1032],{"class":1002},[193,2549,28],{"class":1002},[193,2551,2552],{"class":1136}," \u002F\u002F 途中にiterableでないものがある。\n",[193,2554,2555,2558,2560],{"class":195,"line":90},[193,2556,2557],{"class":1014},"    todo",[193,2559,1018],{"class":1002},[193,2561,2562],{"class":998},"[\n",[193,2564,2565],{"class":195,"line":212},[193,2566,2567],{"class":1002},"            {\n",[193,2569,2570,2573,2575,2577],{"class":195,"line":218},[193,2571,2572],{"class":1014},"                id",[193,2574,1018],{"class":1002},[193,2576,1022],{"class":1021},[193,2578,2579],{"class":1002},",\n",[193,2581,2582],{"class":195,"line":224},[193,2583,2584],{"class":1136},"                \u002F\u002F オブジェクトがネストしている\n",[193,2586,2587,2590],{"class":195,"line":230},[193,2588,2589],{"class":1014},"                content",[193,2591,2592],{"class":1002},":{\n",[193,2594,2595,2598,2600,2602,2604,2606,2608,2610,2612,2614,2616],{"class":195,"line":236},[193,2596,2597],{"class":1014},"                    summery",[193,2599,1018],{"class":1002},[193,2601,1032],{"class":1002},[193,2603,2069],{"class":1035},[193,2605,1032],{"class":1002},[193,2607,28],{"class":1002},[193,2609,2076],{"class":1014},[193,2611,1018],{"class":1002},[193,2613,1032],{"class":1002},[193,2615,2069],{"class":1035},[193,2617,2618],{"class":1002},"\"\n",[193,2620,2621],{"class":195,"line":242},[193,2622,2623],{"class":1002},"                }\n",[193,2625,2626],{"class":195,"line":248},[193,2627,2628],{"class":1002},"            },\n",[193,2630,2631],{"class":195,"line":254},[193,2632,2567],{"class":1002},[193,2634,2635,2637,2639,2641],{"class":195,"line":259},[193,2636,2572],{"class":1014},[193,2638,1018],{"class":1002},[193,2640,1066],{"class":1021},[193,2642,2579],{"class":1002},[193,2644,2645,2647],{"class":195,"line":265},[193,2646,2589],{"class":1014},[193,2648,2592],{"class":1002},[193,2650,2651,2653,2655,2657,2659,2661,2663,2665,2667,2669,2671],{"class":195,"line":271},[193,2652,2597],{"class":1014},[193,2654,1018],{"class":1002},[193,2656,1032],{"class":1002},[193,2658,2108],{"class":1035},[193,2660,1032],{"class":1002},[193,2662,28],{"class":1002},[193,2664,2076],{"class":1014},[193,2666,1018],{"class":1002},[193,2668,1032],{"class":1002},[193,2670,2108],{"class":1035},[193,2672,2618],{"class":1002},[193,2674,2675],{"class":195,"line":600},[193,2676,2623],{"class":1002},[193,2678,2679],{"class":195,"line":606},[193,2680,2681],{"class":1002},"            }\n",[193,2683,2684],{"class":195,"line":612},[193,2685,2686],{"class":998},"        ];\n",[193,2688,2689],{"class":195,"line":618},[193,2690,2691],{"class":1136},"    \u002F\u002F More unpredictable properties..\n",[193,2693,2694],{"class":195,"line":624},[193,2695,274],{"class":1002},[13,2697,2698],{},"上記のような状況を踏まえると、ディープコピー はJSONを用いるか大人しくライブラリを使用する方が賢明そうです。値が連動してしまう時はまず値渡し・参照渡しを疑い、その次はディープコピーがされているか（ネストしたオブジェクトがないか）を確かめてみましょう。",[419,2700,2701],{},"html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}",{"title":57,"searchDepth":90,"depth":90,"links":2703},[2704,2707,2708,2713],{"id":1158,"depth":93,"text":1158,"children":2705},[2706],{"id":1300,"depth":90,"text":1301},{"id":1149,"depth":93,"text":1149},{"id":1154,"depth":93,"text":1154,"children":2709},[2710,2711,2712],{"id":1638,"depth":90,"text":1639},{"id":1825,"depth":90,"text":1826},{"id":2242,"depth":90,"text":2243},{"id":2456,"depth":93,"text":2457},[96],"2021-11-07","配列内のオブジェクトの値が連動するときの原因と対処法",{},"\u002Farticles\u002Fjs-deep-copy",{"title":973,"description":2716},"articles\u002Fjs-deep-copy",[2722,2723],"js","vue","TVfFMZbaj-eg5y8hB-QhEPtPjdhOPFn6vmaY0JeSo0g",{"id":2726,"title":2727,"body":2728,"category":2935,"createdAt":2936,"description":2727,"extension":98,"index":99,"meta":2937,"navigation":101,"path":2938,"publish":101,"seo":2939,"series":99,"seriesTitle":99,"stem":2940,"tag":2941,"thumbnail":99,"updatedAt":99,"__hash__":2943},"articles\u002Farticles\u002Fpreflight-redirect-cors-error.md","URL正規化によって Redirect is not allowed for a preflight request でCORSエラーが起きた",{"type":10,"value":2729,"toc":2933},[2730,2733,2739,2746,2772,2786,2789,2910,2924,2930],[13,2731,2732],{},"こんにちはjunです。LaravelとNuxt SPAでアプリを作っていたのですがCORS設定をしているのに偶に以下のようなエラーが発生していました。",[49,2734,2737],{"className":2735,"code":2736,"language":54},[52],"Access to XMLHttpRequest at 'http:\u002F\u002Flocalhost\u002Fapi\u002Fv1\u002Ftest\u002F' from origin 'http:\u002F\u002Flocalhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.\n",[25,2738,2736],{"__ignoreMap":57},[13,2740,2741,2742,2745],{},"エラー内容の通り原因はpreflightリクエストがリダイレクトされてしまっていることが原因です。開発者ツールでnetworkを見ると確かにpreflightリクエストが301となっていることが原因です。しかしなぜリダイレクト？Laravelでredirectを返すメソッドがあるのかと思いましたが、原因は",[25,2743,2744],{},".htaccess","の以下の記述でした。",[49,2747,2750],{"className":2748,"code":2749,"language":2744,"meta":57,"style":57},"language-.htaccess shiki shiki-themes material-theme-ocean","#Redirect Trailing Slashes If Not A Folder...\nRewriteCond %{REQUEST_FILENAME} !-d\nRewriteCond %{REQUEST_URI} (.+)\u002F$\nRewriteRule ^ %1 [L,R=301]\n",[25,2751,2752,2757,2762,2767],{"__ignoreMap":57},[193,2753,2754],{"class":195,"line":196},[193,2755,2756],{},"#Redirect Trailing Slashes If Not A Folder...\n",[193,2758,2759],{"class":195,"line":93},[193,2760,2761],{},"RewriteCond %{REQUEST_FILENAME} !-d\n",[193,2763,2764],{"class":195,"line":90},[193,2765,2766],{},"RewriteCond %{REQUEST_URI} (.+)\u002F$\n",[193,2768,2769],{"class":195,"line":212},[193,2770,2771],{},"RewriteRule ^ %1 [L,R=301]\n",[13,2773,2774,2775,2777,2778,2781,2782,2785],{},"上記はLaravelが使用するURLの正規化を行う",[25,2776,2744],{},"の記述です。URLの末尾にスラッシュがある場合、ないように正規化してくれます。",[25,2779,2780],{},"http:\u002F\u002Flocalhost\u002Ftest\u002F","→",[25,2783,2784],{},"http:\u002F\u002Flocalhost\u002Ftest"," のようにリダイレクトがおきます。これはAPIルートでも発生します。",[13,2787,2788],{},"私のAPIリクエストを見てみると",[49,2790,2792],{"className":985,"code":2791,"language":987,"meta":57,"style":57},"async test(){\n    this.$axios.post('\u002Fv1\u002Ftest\b\u002F')\n    .then(res=>[\n        console.log(res)\n    ])\n    .catch(err=>{\n        console.log(err)\n    })\n}\n",[25,2793,2794,2807,2832,2850,2865,2869,2885,2899,2906],{"__ignoreMap":57},[193,2795,2796,2799,2802,2805],{"class":195,"line":196},[193,2797,2798],{"class":998},"async ",[193,2800,2801],{"class":1206},"test",[193,2803,2804],{"class":998},"()",[193,2806,233],{"class":1002},[193,2808,2809,2812,2815,2817,2820,2822,2825,2828,2830],{"class":195,"line":93},[193,2810,2811],{"class":1002},"    this.",[193,2813,2814],{"class":998},"$axios",[193,2816,1186],{"class":1002},[193,2818,2819],{"class":1206},"post",[193,2821,1925],{"class":1014},[193,2823,2824],{"class":1002},"'",[193,2826,2827],{"class":1035},"\u002Fv1\u002Ftest\b\u002F",[193,2829,2824],{"class":1002},[193,2831,881],{"class":1014},[193,2833,2834,2837,2840,2842,2845,2848],{"class":195,"line":90},[193,2835,2836],{"class":1002},"    .",[193,2838,2839],{"class":1206},"then",[193,2841,1925],{"class":1014},[193,2843,2844],{"class":1928},"res",[193,2846,2847],{"class":994},"=>",[193,2849,2562],{"class":1014},[193,2851,2852,2855,2857,2859,2861,2863],{"class":195,"line":212},[193,2853,2854],{"class":998},"        console",[193,2856,1186],{"class":1002},[193,2858,1207],{"class":1206},[193,2860,1925],{"class":1014},[193,2862,2844],{"class":998},[193,2864,881],{"class":1014},[193,2866,2867],{"class":195,"line":218},[193,2868,262],{"class":1014},[193,2870,2871,2873,2876,2878,2881,2883],{"class":195,"line":224},[193,2872,2836],{"class":1002},[193,2874,2875],{"class":1206},"catch",[193,2877,1925],{"class":1014},[193,2879,2880],{"class":1928},"err",[193,2882,2847],{"class":994},[193,2884,233],{"class":1002},[193,2886,2887,2889,2891,2893,2895,2897],{"class":195,"line":230},[193,2888,2854],{"class":998},[193,2890,1186],{"class":1002},[193,2892,1207],{"class":1206},[193,2894,1925],{"class":1014},[193,2896,2880],{"class":998},[193,2898,881],{"class":1014},[193,2900,2901,2904],{"class":195,"line":236},[193,2902,2903],{"class":1002},"    }",[193,2905,881],{"class":1014},[193,2907,2908],{"class":195,"line":242},[193,2909,274],{"class":1002},[13,2911,2912,2913,2915,2916,2919,2920,2923],{},"URLをみてみると",[25,2914,2827],{},"と末尾にスケジュール があります。そしてXHRは ",[25,2917,2918],{},"POST + contetnt-type:application\u002Fjson"," のようなリクエストではpreflightリクエストが飛びますが、そのリクエストはリダイレクトをしてはいけません。そのためURLを",[25,2921,2922],{},"\u002Fv1\u002Ftest\b","と末尾をなくしてあげたらリダイレクトが起きず、問題なくCORSが起きなくなりました。",[13,2925,2926,2927,2929],{},"CORSの設定やLaravelのメソッドを調べていましたが、結構簡単な",[25,2928,2744],{},"が原因でした。",[419,2931,2932],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}",{"title":57,"searchDepth":90,"depth":90,"links":2934},[],[96],"2021-09-19",{},"\u002Farticles\u002Fpreflight-redirect-cors-error",{"title":2727,"description":2727},"articles\u002Fpreflight-redirect-cors-error",[2942,441],"infrastructure","ia4jjF7K85Ze8kJeV-fqRUKhfJsuBqIgYCJYkocy2u0",{"id":2945,"title":2946,"body":2947,"category":3161,"createdAt":3163,"description":3164,"extension":98,"index":99,"meta":3165,"navigation":101,"path":3166,"publish":101,"seo":3167,"series":99,"seriesTitle":99,"stem":3168,"tag":3169,"thumbnail":3170,"updatedAt":99,"__hash__":3171},"articles\u002Farticles\u002Fbeing-a-year-as-web-engineer.md","webエンジニアになって1年半経って感じた、採用される未経験エンジニアのwebアプリポートフォリオについて",{"type":10,"value":2948,"toc":3149},[2949,2952,2955,2958,2963,2966,2969,2972,2985,2988,2991,2994,2997,3000,3004,3007,3010,3013,3016,3019,3045,3048,3051,3054,3057,3060,3063,3066,3069,3073,3077,3080,3083,3086,3090,3093,3096,3111,3114,3117,3125,3128,3131,3134,3137,3140,3143,3146],[13,2950,2951],{},"こんにちはjunです。私はフロントエンドエンジニアとして2019年の12月にWeb系会社に入りましたが、今（2021年8月）に１年半経ちました。技術的にもいろいろわかる様になってきたり、課題ややるべきことも結構出てきました。ふと採用の時に使っていたポートフォリオやコードを見ると「よくこれで採用できなー」とか「これじゃダメに決まってるな」と反省点も多かったです。そう思う様になった理由としては技術がついてきただけでなく、フリーランスの採用に立ち会ったり、ディレクションをやってみてプロジェクト全体を考えながら「エンジニア」の立ち振る舞いをみてきた結果です。",[13,2953,2954],{},"今回の記事では１年半前の自分にアドバイスする気持ちで、webエンジニア採用・転職で必要になる効果的なポートフォリオの作成・見せ方について解説したいと思います。なお解説するポートフォリオの中身としてはwebアプリ（システム）としておきます。",[17,2956,2957],{"id":2957},"担当者の負担を減らす様にする",[2959,2960],"image-render",{":src":2961,":width":2962},"'being-a-year-as-web-engineer\u002Femployee-6038877_640.png'","'100%'",[13,2964,2965],{},"まず最初にポートフォリオを確認する採用担当者の負担を減らせる様に、ポートフォリオの見せ方や使い方を工夫しましょう。",[13,2967,2968],{},"採用担当者は短い時間で大量の応募がある中で、いかに優秀な人材か判断し、地雷人材を弾く必要があります。そのためポートフォリオを使ってアピールする場合は、採用担当者がポートフォリオのサイトを見れること、特徴や詳細をまとめたドキュメントが見れるようにして、負担を減らしておくといいです。",[13,2970,2971],{},"例えば",[2973,2974,2975,2979,2982],"ul",{},[2976,2977,2978],"li",{},"ポートフォリオのサイトは基本的にすぐ見れる様に。レンタルサーバーとかでもいいので、web上でアクセスできる様にする",[2976,2980,2981],{},"githubでソースを紹介する場合はREADME.mdを書いておく。",[2976,2983,2984],{},"ログイン機能などはメールを使用せず、ゲストログイン機能をつける。個人情報は取らない",[13,2986,2987],{},"などです。ちょっと細かく解説します。",[133,2989,2990],{"id":2990},"ちゃんとweb上で見れる様にする",[13,2992,2993],{},"これはローカル環境でなくサーバーを借りて、できたらドメインも取得してみてポートフォリオをホストすることです。",[13,2995,2996],{},"システム系のポートフォリオであれば、きちんと動く様に設定しておきましょう。バグっていると見れないだけでなく、（一番重要な）本番環境でコケているので印象がよくないです。",[13,2998,2999],{},"最近ではAWSで無料期間もありますし、レンタルサーバーやHerokuなどで安くホストできます。独自ドメインはあまり必要ありませんが、自前のサーバーでホストして必ず担当者が見れる環境を整えておきましょう。",[133,3001,3003],{"id":3002},"readmemdを書くドキュメントや特徴をまとめる","README.mdを書く。ドキュメントや特徴をまとめる",[13,3005,3006],{},"ソースを共有する際はgithubを使用することが多いですが、その際はREADME.mdを作成してソースやポートフォリオの特徴を書いておきましょう。",[13,3008,3009],{},"READMEがあることで以下の様に（githubのヘルプより）",[2959,3011],{":src":3012,":width":2962},"'being-a-year-as-web-engineer\u002Freadme.png'",[13,3014,3015],{},"自動的にmarkdowの説明書を表示してくれます。",[13,3017,3018],{},"そしてこのREADMEには細かい処理内容でなく、",[2973,3020,3021,3024,3027,3030,3033,3036,3039,3042],{},[2976,3022,3023],{},"このポートフォリオの作成背景、目的",[2976,3025,3026],{},"使用している技術スタック",[2976,3028,3029],{},"大まかな機能概要、特徴",[2976,3031,3032],{},"使い方",[2976,3034,3035],{},"オリジナリティー、工夫した点",[2976,3037,3038],{},"大変だった点、その対策",[2976,3040,3041],{},"完成までの工数",[2976,3043,3044],{},"ポートフォリオのホスト先URLなど",[13,3046,3047],{},"以上の内容を書いておきましょう。",[13,3049,3050],{},"READMEでなくとも、ポートフォリオのページに同様の内容でポートフォリオについての解説ページを作っても大丈夫です。とにかく採用担当者がポートフォリオの特徴・説明を１ページでまとめられたページを作っておくと、きちんとあなたのポートフォリオをみようとしてくれます。",[133,3052,3053],{"id":3053},"ログイン機能などはゲスト機能をつける",[13,3055,3056],{},"システムで会員機能はよいアピールポイントですが、メールアドレスなどを必要としている場合は採用担当者の負担となります。この場合、採用担当者はメールアドレスを正直よくわからない人が作ったアプリに登録しますし、登録するのが不安なんです。（製作者がセキュリティ、個人情報ポリシーを良くわかっていないかもしれないし）",[13,3058,3059],{},"他にも使用するために個人情報が必要だったり、Googleアカウントが必要だったりなどユーザー側に副作用がある機能を代替できる機能を作っておきましょう。ログインの場合は、ゲストユーザー機能を作っておいたり、こちらで担当者用のIDとダミーアドレスのユーザーを作成しておくなどです。",[17,3061,3062],{"id":3062},"最低限見た目はよくしておく",[13,3064,3065],{},"あなたが希望する会社によりますが、webシステム開発系であってもせめてbootstrapを上手く使ってレスポンシブ、基本的なデザインUIは綺麗にしておきましょう。デザイン重視しておしゃれな会社の場合は、デザインを凝ってみてもいいでしょう。正直見た目でポートフォリオの第一印象を決めていることもあるので、トップページなどの見た目は良くしておきましょう。デザインに自信がない場合は参考サイトを見つけ、そこを真似てください！またはcssライブラリを使いましょう。",[13,3067,3068],{},"そしてサクラでもいいので、ダミーの内容を入れておくと印象が全然違います。コンテンツが豊富にあり、見た目が整っていて、デザインの４原則が守られているとなぜか良さげなポートフォリオと感じられます。",[17,3070,3072],{"id":3071},"詳細な仕組み技術より特徴","詳細な仕組み、技術より特徴",[2959,3074],{":src":3075,":width":3076,":center":1552},"'being-a-year-as-web-engineer\u002Fchecklist-1622517_640.png'","'200px'",[13,3078,3079],{},"先ほどのREADMEやトップページなどでは沢山伝えたいがために細かく書いてしまうかもしれませんが、それよりシステムの特徴や自分が推したい機能などを伝えましょう。",[13,3081,3082],{},"ぶっちゃけ、、「会員機能つけました！こうでこうでこうなんです！」と言われても「ふーん。まあフレームワーク使えれば当たり前だよね」となってしまいますし、「Reactつかってます！Typescript使ってます！」と言っても「へー。じゃあそれを使ってどうだったの？」となります。",[13,3084,3085],{},"特徴点があまりにも細かく、また基本的な箇所すぎてあまり響かないんです。それらは機能一覧、技術スタック一覧など箇条書き程度に置いておき、「これらの技術を用いてどんなものを作ったのか」と言うのをアピールすると良いです。あなたの技術レベルを判定するときはその会社のエンジニアがあなたのポートフォリオをみますが、機能一覧でだいたいどんなロジックが実装できるかというのは把握できます。なので詳細な説明はむしろ必要なく、特徴や機能の概要を伝えればいいです。",[17,3087,3089],{"id":3088},"作成背景自分なりのオリジナリティーを伝える","作成背景、自分なりのオリジナリティーを伝える",[13,3091,3092],{},"ポートフォリオは一種のアプリですので何某の作成背景があると思います。私の場合は旅行が趣味だったので、旅行で撮った写真をインスタの様に共有しつつ販売できるといいなーと思って「インスタ×ピクスタ」なアプリを作ろう！という背景がありました。",[13,3094,3095],{},"作成背景があるとポートフォリオを作りやすくもなります。",[3097,3098,3099,3102,3105,3108],"ol",{},[2976,3100,3101],{},"こうゆう課題、需要、背景がある",[2976,3103,3104],{},"どんな機能、システムで解決できそうか",[2976,3106,3107],{},"そのための技術選定",[2976,3109,3110],{},"どうすればユーザーがつかってもらえそうか",[13,3112,3113],{},"これらのことを考えて作られたアプリは質が高く、内部のコードからもその配慮がみられます。「１」に関しては実際の企画部や調査部のような力は個人にはないので、正直需要がなくてもいいです。またオリジナリティーが浮かばない場合は既存のサービス・アプリのデメリットを探す、複数のサービスを掛け合わせ、ターゲットユーザーを絞るといいです。",[13,3115,3116],{},"私の例では",[2973,3118,3119,3122],{},[2976,3120,3121],{},"「インスタは写真の共有機能があるが、販売はできない。あくまでSNS」",[2976,3123,3124],{},"「ピクスタは写真の売買はできるが、SNSの様なユーザー同士の関わり合いがない」\nならばSNSの様な機能を持たせつつ、売買機能をもつ写真共有アプリにしよう！となりました。そして私は旅行が好きで、やたらと写真を撮っていたのでそれが売れるといいなーという需要を鑑みて、旅行者にターゲットを絞って考えました。",[13,3126,3127],{},"あんま深くは考えなくてもいいですが、こうすると実装したい機能も浮かんできますし、自然とオリジナリティーも出てきて求められる技術も上がります。",[13,3129,3130],{},"コピーアプリは簡単なのですが、なんか面白みにかけます。その時に自分のオリジナリティー機能や特徴があることで他の採用者に差をつけることができます。",[17,3132,3133],{"id":3133},"ポートフォリオを通じてどうなったのか",[13,3135,3136],{},"ぶっちゃけ言うと未経験者のポートフォリオは様々な視点において抜け漏れがあります。私も現場のwebアプリを構築して気にする箇所が多く、今振り返ってみると如何に自分のポートフォリオがポンコツだったのかが分かります（最初はそんなものです）。",[13,3138,3139],{},"もちろんポートフォリオを作ることで自分の技術力、企画力、構築力をアピールできますが、一番は「このポートフォリオ作成を通じて自分にどんな影響があったのか」は特に未経験採用では重要だと思います。私の場合ポートフォリを通じてwebアプリケーションの全体を構成する大変さや視点、そしてエラー・フォルトへの対処（これが一番辛く、役に立った気がする）、課題や今後の発展に関して書いた記憶があります。",[13,3141,3142],{},"ポートフォリオを単に作るだけでなく、作ってみてどう感じたのか、何を学べたのかを伝えることで採用担当者に自身の技術に対する学習意欲や課題に対しての姿勢という仕事で非常に大切な要素をアピールできます。",[17,3144,3145],{"id":3145},"以上",[13,3147,3148],{},"以上が振り返ってみて１年半前の自分にアドバイスする内容です。webアプリ開発は本当に可能性と面白さに満ちています。皆さんの就職が上手くいくことを応援しています。",{"title":57,"searchDepth":90,"depth":90,"links":3150},[3151,3156,3157,3158,3159,3160],{"id":2957,"depth":93,"text":2957,"children":3152},[3153,3154,3155],{"id":2990,"depth":90,"text":2990},{"id":3002,"depth":90,"text":3003},{"id":3053,"depth":90,"text":3053},{"id":3062,"depth":93,"text":3062},{"id":3071,"depth":93,"text":3072},{"id":3088,"depth":93,"text":3089},{"id":3133,"depth":93,"text":3133},{"id":3145,"depth":93,"text":3145},[3162],"learning","2021-08-18","そんなポートフォリオで大丈夫か？",{},"\u002Farticles\u002Fbeing-a-year-as-web-engineer",{"title":2946,"description":3164},"articles\u002Fbeing-a-year-as-web-engineer",[],"being-a-year-as-web-engineer\u002Fthumbnail.png","lRPFY6c_6dBMblLUhkWYschivmGC5D1CLX3AqBAymgs",{"id":3173,"title":3174,"body":3175,"category":4023,"createdAt":4024,"description":4025,"extension":98,"index":99,"meta":4026,"navigation":101,"path":4027,"publish":101,"seo":4028,"series":99,"seriesTitle":99,"stem":4029,"tag":4030,"thumbnail":99,"updatedAt":99,"__hash__":4031},"articles\u002Farticles\u002Fwp-batch-image-compress.md","大量の大ファイルサイズ画像をPHPでリサイズ・圧縮をする方法",{"type":10,"value":3176,"toc":4011},[3177,3180,3183,3186,3189,3192,3210,3213,3216,3219,3408,3418,3421,3425,3431,3463,3472,3521,3528,3532,3537,3546,3549,3618,3624,3627,3630,3633,3975,3982,3986,3993,3999,4002,4008],[13,3178,3179],{},"こんにちはjunです。私はこの技術ブログ以外にもブログを運営しているのですが、そちらはwebエンジニアになる前からやっていました。しかし過去の記事を見ているとやたらと重い画像、１枚あたり１MBも使っている記事が何枚もありました。当時は画像の重さなど知らずにデジカメの画像をそのままアップロードして、使用していたことが原因です。",[13,3181,3182],{},"記事の中には転送量が12MBにもなっているものもあり、原因は画像でした。それらの画像はやたらとサイズ（寸法）が大きいことが原因なので、リサイズして圧縮することで解決できます。しかし100件以上の記事を1つずつ開いて調べたり、もう一回ダウンロードして、圧縮してアップロードなんて何日かかるかわかりません。そのため今回はPHPとコマンドラインを用いて一気に画像を処理することにしました。",[13,3184,3185],{},"wordpressを使用していますが、画像処理のエッセンスや大方の処理の流れは応用できるとおもいます。では早速やっていきましょう。",[17,3187,3188],{"id":3188},"大まかな流れ",[13,3190,3191],{},"まず全体の処理の流れですが以下の通りです。",[3097,3193,3194,3201,3204,3207],{},[2976,3195,3196,3197,3200],{},"ターミナルで ",[25,3198,3199],{},"wp-content\u002Fuploads\u002F"," 配下にある大サイズ（500kb以上とする）をリストアップ。",[2976,3202,3203],{},"バックアップしておき、数ヶ月残しておく。",[2976,3205,3206],{},"PHPのGDモジュールを用いてリサイズ・圧縮を行う。",[2976,3208,3209],{},"処理した画像を上書き。",[13,3211,3212],{},"以上の通りです。今回の処理を行うにあたりwordpressがあるサーバーに対してCLI\b操作が行える必要があります。SSHができ、必要な権限を付与しておいてください。今回はこの準備はできているものとします。",[17,3214,3215],{"id":3215},"処理対象をリストアップ",[13,3217,3218],{},"それではまず対象の画像をリストアップします。アップロードディレクトリに移動してfindコマンドで簡単に見つけられます。",[49,3220,3224],{"className":3221,"code":3222,"language":3223,"meta":57,"style":57},"language-bash shiki shiki-themes material-theme-ocean","# \u002Fdocumentroot\u002Fwordpress\u002F は仮です。あなたの環境に合わせてください。\n# 画像が格納されているuploadsへ移動\ncd '\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads'\nls\n2017 2018 2019 2020 2021 aaaa bbbbb cccc\n\n# プラグイン用画像のディレクトリなどもあるので注意！\n# 自分がアップロードした画像があるディレクトリのみを指定、500kb以上のものをリストアップ。リストはテキストファイルとしてホームディレクトリにおいておく。\nfind 2017 2018 2019 2020 2021 -size +500k > ~\u002Flist.txt\n..\n2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-644x279.png\n2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-720x340.png\n2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-768x332.png\n2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83.png\n2017\u002F12\u002FDSC03961-1200x900.jpg\n2017\u002F12\u002FDSC04310-1200x900.jpg\n2017\u002F12\u002FDSC04311-1200x900.jpg\n2017\u002F12\u002FDSC04314-1200x900.jpg\n2017\u002F12\u002FDSC04315-1200x900.jpg\n2017\u002F12\u002FDSC04316-1200x900.jpg\n2017\u002F12\u002FDSC04317-1200x900.jpg\n2017\u002F12\u002FDSC04319-1200x900.jpg\n2017\u002F12\u002FDSC04320-e1512559527929-1200x1600.jpg\n2017\u002F12\u002FDSC04324-1200x900.jpg\n2017\u002F12\u002FDSC04325-1200x900.jpg\n...\n","bash",[25,3225,3226,3231,3236,3250,3256,3282,3286,3291,3296,3324,3329,3334,3339,3344,3349,3354,3359,3364,3369,3374,3379,3384,3389,3394,3399,3404],{"__ignoreMap":57},[193,3227,3228],{"class":195,"line":196},[193,3229,3230],{"class":1136},"# \u002Fdocumentroot\u002Fwordpress\u002F は仮です。あなたの環境に合わせてください。\n",[193,3232,3233],{"class":195,"line":93},[193,3234,3235],{"class":1136},"# 画像が格納されているuploadsへ移動\n",[193,3237,3238,3241,3244,3247],{"class":195,"line":90},[193,3239,3240],{"class":1206},"cd",[193,3242,3243],{"class":1002}," '",[193,3245,3246],{"class":1035},"\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads",[193,3248,3249],{"class":1002},"'\n",[193,3251,3252],{"class":195,"line":212},[193,3253,3255],{"class":3254},"s5Dmg","ls\n",[193,3257,3258,3261,3264,3267,3270,3273,3276,3279],{"class":195,"line":218},[193,3259,3260],{"class":3254},"2017",[193,3262,3263],{"class":1021}," 2018",[193,3265,3266],{"class":1021}," 2019",[193,3268,3269],{"class":1021}," 2020",[193,3271,3272],{"class":1021}," 2021",[193,3274,3275],{"class":1035}," aaaa",[193,3277,3278],{"class":1035}," bbbbb",[193,3280,3281],{"class":1035}," cccc\n",[193,3283,3284],{"class":195,"line":224},[193,3285,476],{"emptyLinePlaceholder":101},[193,3287,3288],{"class":195,"line":230},[193,3289,3290],{"class":1136},"# プラグイン用画像のディレクトリなどもあるので注意！\n",[193,3292,3293],{"class":195,"line":236},[193,3294,3295],{"class":1136},"# 自分がアップロードした画像があるディレクトリのみを指定、500kb以上のものをリストアップ。リストはテキストファイルとしてホームディレクトリにおいておく。\n",[193,3297,3298,3301,3304,3306,3308,3310,3312,3315,3318,3321],{"class":195,"line":242},[193,3299,3300],{"class":3254},"find",[193,3302,3303],{"class":1021}," 2017",[193,3305,3263],{"class":1021},[193,3307,3266],{"class":1021},[193,3309,3269],{"class":1021},[193,3311,3272],{"class":1021},[193,3313,3314],{"class":1035}," -size",[193,3316,3317],{"class":1035}," +500k",[193,3319,3320],{"class":1002}," >",[193,3322,3323],{"class":1035}," ~\u002Flist.txt\n",[193,3325,3326],{"class":195,"line":248},[193,3327,3328],{"class":1206},"..\n",[193,3330,3331],{"class":195,"line":254},[193,3332,3333],{"class":3254},"2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-644x279.png\n",[193,3335,3336],{"class":195,"line":259},[193,3337,3338],{"class":3254},"2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-720x340.png\n",[193,3340,3341],{"class":195,"line":265},[193,3342,3343],{"class":3254},"2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83-768x332.png\n",[193,3345,3346],{"class":195,"line":271},[193,3347,3348],{"class":3254},"2017\u002F12\u002Fd7d6b39a47612239ce48bf6579be7f83.png\n",[193,3350,3351],{"class":195,"line":600},[193,3352,3353],{"class":3254},"2017\u002F12\u002FDSC03961-1200x900.jpg\n",[193,3355,3356],{"class":195,"line":606},[193,3357,3358],{"class":3254},"2017\u002F12\u002FDSC04310-1200x900.jpg\n",[193,3360,3361],{"class":195,"line":612},[193,3362,3363],{"class":3254},"2017\u002F12\u002FDSC04311-1200x900.jpg\n",[193,3365,3366],{"class":195,"line":618},[193,3367,3368],{"class":3254},"2017\u002F12\u002FDSC04314-1200x900.jpg\n",[193,3370,3371],{"class":195,"line":624},[193,3372,3373],{"class":3254},"2017\u002F12\u002FDSC04315-1200x900.jpg\n",[193,3375,3376],{"class":195,"line":630},[193,3377,3378],{"class":3254},"2017\u002F12\u002FDSC04316-1200x900.jpg\n",[193,3380,3381],{"class":195,"line":636},[193,3382,3383],{"class":3254},"2017\u002F12\u002FDSC04317-1200x900.jpg\n",[193,3385,3386],{"class":195,"line":642},[193,3387,3388],{"class":3254},"2017\u002F12\u002FDSC04319-1200x900.jpg\n",[193,3390,3391],{"class":195,"line":648},[193,3392,3393],{"class":3254},"2017\u002F12\u002FDSC04320-e1512559527929-1200x1600.jpg\n",[193,3395,3396],{"class":195,"line":654},[193,3397,3398],{"class":3254},"2017\u002F12\u002FDSC04324-1200x900.jpg\n",[193,3400,3401],{"class":195,"line":660},[193,3402,3403],{"class":3254},"2017\u002F12\u002FDSC04325-1200x900.jpg\n",[193,3405,3406],{"class":195,"line":666},[193,3407,340],{"class":1206},[13,3409,3410,3413,3414,3417],{},[25,3411,3412],{},"find -size "," でファイルサイズでフィルターできます。1000件以上あったりと、コピーするのは大変なので ",[25,3415,3416],{},"list.txt"," などで出力しておきます。",[17,3419,3420],{"id":3420},"画像処理スクリプトを作成",[133,3422,3424],{"id":3423},"リストをphp-arrayにする","リストをPHP Arrayにする",[13,3426,3427,3428,3430],{},"サーバーでのリストアップが終わったので、ローカルでスクリプトを作っていきます。",[25,3429,3416],{}," はローカルに移動しておきます。",[49,3432,3434],{"className":3221,"code":3433,"language":3223,"meta":57,"style":57},".\n├── list.php\n├── image.php\n├── list.txt\n",[25,3435,3436,3441,3449,3456],{"__ignoreMap":57},[193,3437,3438],{"class":195,"line":196},[193,3439,3440],{"class":1206},".\n",[193,3442,3443,3446],{"class":195,"line":93},[193,3444,3445],{"class":3254},"├──",[193,3447,3448],{"class":1035}," list.php\n",[193,3450,3451,3453],{"class":195,"line":90},[193,3452,3445],{"class":3254},[193,3454,3455],{"class":1035}," image.php\n",[193,3457,3458,3460],{"class":195,"line":212},[193,3459,3445],{"class":3254},[193,3461,3462],{"class":1035}," list.txt\n",[13,3464,3465,3467,3468,3471],{},[25,3466,3416],{}," を",[25,3469,3470],{},"list.php"," としてコピーしておき、配列に変換しておきます。テキストエディタの置換機能などを利用してください。",[49,3473,3475],{"className":188,"code":3474,"filename":3470,"language":106,"meta":57,"style":57},"\u003C?php \n$list =[\n\"2017\u002F06\u002F23c7f697593e4a4c83e01310ee4b84ec-1200x900.jpg\",\n\"2017\u002F06\u002F23c7f697593e4a4c83e01310ee4b84ec.jpg\",\n\"2017\u002F06\u002Fcropped-DSC03989-1-1024x723.jpg\",\n\"2017\u002F06\u002Fcropped-DSC03989-1-1200x847.jpg\",\n\"2017\u002F06\u002Fcropped-DSC03989-1.jpg\",\n...\n];\n",[25,3476,3477,3482,3487,3492,3497,3502,3507,3512,3516],{"__ignoreMap":57},[193,3478,3479],{"class":195,"line":196},[193,3480,3481],{},"\u003C?php \n",[193,3483,3484],{"class":195,"line":93},[193,3485,3486],{},"$list =[\n",[193,3488,3489],{"class":195,"line":90},[193,3490,3491],{},"\"2017\u002F06\u002F23c7f697593e4a4c83e01310ee4b84ec-1200x900.jpg\",\n",[193,3493,3494],{"class":195,"line":212},[193,3495,3496],{},"\"2017\u002F06\u002F23c7f697593e4a4c83e01310ee4b84ec.jpg\",\n",[193,3498,3499],{"class":195,"line":218},[193,3500,3501],{},"\"2017\u002F06\u002Fcropped-DSC03989-1-1024x723.jpg\",\n",[193,3503,3504],{"class":195,"line":224},[193,3505,3506],{},"\"2017\u002F06\u002Fcropped-DSC03989-1-1200x847.jpg\",\n",[193,3508,3509],{"class":195,"line":230},[193,3510,3511],{},"\"2017\u002F06\u002Fcropped-DSC03989-1.jpg\",\n",[193,3513,3514],{"class":195,"line":236},[193,3515,340],{},[193,3517,3518],{"class":195,"line":242},[193,3519,3520],{},"];\n",[13,3522,3523,3524,3527],{},"これで対象画像をリストアップして、PHPが扱えるようになったので ",[25,3525,3526],{},"image.php"," にて処理の方を書いていきましょう。",[133,3529,3531],{"id":3530},"画像圧縮リサイズ処理","画像圧縮・リサイズ処理",[3533,3534,3536],"h4",{"id":3535},"そのまえに","そのまえに..",[13,3538,3539,3540,3545],{},"PHPでリサイズなどの画像処理を行う場合は",[36,3541,3544],{"href":3542,"rel":3543},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fja\u002Fintro.image.php",[40],"GDというPHPモジュール","を用います。処理を書く前にこのGDモジュールが使用しているPHP環境にあるかを確認しましょう。",[13,3547,3548],{},"phpinfoのページでも確認できますが、手っ取り早くCLIでやりましょう。以下のコマンドを打ちます。",[49,3550,3552],{"className":3221,"code":3551,"language":3223,"meta":57,"style":57},"php --info | grep GD\nGD Support => enabled\nGD headers Version => 2.3.2\nGD library Version => 2.3.2\n",[25,3553,3554,3570,3586,3603],{"__ignoreMap":57},[193,3555,3556,3558,3561,3564,3567],{"class":195,"line":196},[193,3557,106],{"class":3254},[193,3559,3560],{"class":1035}," --info",[193,3562,3563],{"class":1002}," |",[193,3565,3566],{"class":3254}," grep",[193,3568,3569],{"class":1035}," GD\n",[193,3571,3572,3575,3578,3581,3583],{"class":195,"line":93},[193,3573,3574],{"class":3254},"GD",[193,3576,3577],{"class":1035}," Support",[193,3579,3580],{"class":998}," =",[193,3582,1344],{"class":1002},[193,3584,3585],{"class":1035}," enabled\n",[193,3587,3588,3590,3593,3596,3598,3600],{"class":195,"line":90},[193,3589,3574],{"class":3254},[193,3591,3592],{"class":1035}," headers",[193,3594,3595],{"class":1035}," Version",[193,3597,3580],{"class":998},[193,3599,1344],{"class":1002},[193,3601,3602],{"class":1021}," 2.3.2\n",[193,3604,3605,3607,3610,3612,3614,3616],{"class":195,"line":212},[193,3606,3574],{"class":3254},[193,3608,3609],{"class":1035}," library",[193,3611,3595],{"class":1035},[193,3613,3580],{"class":998},[193,3615,1344],{"class":1002},[193,3617,3602],{"class":1021},[13,3619,3620,3623],{},[25,3621,3622],{},"GD Support => enabled"," が存在し、enabledとなっていれば使用可能です。ない場合などを別途インストールが必要です。まあwordpressが使用できる環境ならば大抵入っていると思います。これでGDの確認を行ったら、処理を書きます。",[3533,3625,3626],{"id":3626},"処理の記述",[13,3628,3629],{},"今回のスクリプトはCMSがるサーバー上で実行するものとします。そのためパスなどの構成も予め、サーバー上であることを想定してます。",[13,3631,3632],{},"全体は以下の通りです。",[49,3634,3636],{"className":188,"code":3635,"language":106,"meta":57,"style":57},"\u003C?php \n    require_once 'list.php';\n\n    $uploadRoot = '\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads\u002F';\n\n    foreach($list as $file){\n        \u002F** \n         * ファイル名などを分けておく。\n         * \n         * 例\n         * $file            => '2017\u002F12\u002FDSC04325-1200x900.jpg'\n         * $targetFilename  => 'DSC04325-1200x900.jpg'\n         * $fullPath        => '\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002FDSC04325-1200x900.jpg'\n        *\u002F\n        $filenames = explode('\u002F',$file);\n        $targetFilename = $filenames[count($filenames)-1];\n        $fullPath = $uploadRoot.$file;\n\n        \u002F\u002F getimagesize()を用いて寸法、拡張子の情報を取得。\n        list($w, $h,$type) = getimagesize($fullPath);\n        var_dump($fullPath);\n\n        \u002F\u002F imagecreatefromjpeg()・imagecreatefrompng()にてGDImageを取得。画像を取得しているんだなぐらいだと思ってください。\n        \u002F\u002F JPG\u002FPNGによって分ける必要あり！。\n        switch ($type) {\n            case IMAGETYPE_JPEG:\n                $original_image = imagecreatefromjpeg($fullPath);\n                break;\n            case IMAGETYPE_PNG:\n                $original_image = imagecreatefrompng($fullPath);\n                break;\n            default:\n                var_dump('対応していないファイル形式です。: '.$fullPath);\n                continue;\n        }\n\n        \u002F\u002F 寸法が大きすぎるもの(1000px以上)は600pxぐにらいするリサイズ処理を行う。\n        if($w >= 1000){\n\n            \u002F\u002F imagecreatetruecolor() で新しい画像を埋め込むための「枠」を作る。（新しいキャンバス的な？）\n            \u002F\u002F 縦横比を計算させて元画像と同じにさせること。\n            $newW = 600;\n            $newH = $newW * ($h \u002F $w);\n            $newImg = imagecreatetruecolor($newW, $newH);\n\n            \u002F\u002F リサイズ処理。\n            $success = imagecopyresampled($newImg, $original_image, 0, 0, 0, 0, $newW, $newH, $w, $h);\n\n            if($success){\n                $original_image = $newImg;\n            }else{\n                var_dump('リサイズ失敗: '.$fullPath);\n                continue;\n            }\n        }\n\n        \u002F\u002F 画像を圧縮して同じ名前、パスで上書き保存する。ここも拡張子で異なるので注意！\n        \u002F\u002F 数字は圧縮の品質。低いほど軽くなるが、粗くなる。jpgは0~100,pngは0~9なので注意。\n        switch ($type) {\n            case IMAGETYPE_JPEG:\n                imagejpeg($original_image,$fullPath,60);\n                break;\n            case IMAGETYPE_PNG:\n                imagepng($original_image,$fullPath,6);\n                break;\n            default:\n                var_dump('対応していないファイル形式です。: '.$fullPath);\n                continue;\n        }\n    }\n?>\n",[25,3637,3638,3642,3647,3651,3656,3660,3665,3670,3675,3680,3685,3690,3695,3700,3705,3710,3715,3720,3724,3729,3734,3739,3743,3748,3753,3758,3763,3768,3773,3778,3783,3787,3792,3797,3802,3807,3811,3816,3821,3825,3830,3835,3840,3845,3850,3854,3859,3864,3868,3873,3878,3883,3888,3892,3896,3900,3904,3909,3914,3918,3922,3927,3931,3935,3940,3944,3948,3953,3958,3963,3969],{"__ignoreMap":57},[193,3639,3640],{"class":195,"line":196},[193,3641,3481],{},[193,3643,3644],{"class":195,"line":93},[193,3645,3646],{},"    require_once 'list.php';\n",[193,3648,3649],{"class":195,"line":90},[193,3650,476],{"emptyLinePlaceholder":101},[193,3652,3653],{"class":195,"line":212},[193,3654,3655],{},"    $uploadRoot = '\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads\u002F';\n",[193,3657,3658],{"class":195,"line":218},[193,3659,476],{"emptyLinePlaceholder":101},[193,3661,3662],{"class":195,"line":224},[193,3663,3664],{},"    foreach($list as $file){\n",[193,3666,3667],{"class":195,"line":230},[193,3668,3669],{},"        \u002F** \n",[193,3671,3672],{"class":195,"line":236},[193,3673,3674],{},"         * ファイル名などを分けておく。\n",[193,3676,3677],{"class":195,"line":242},[193,3678,3679],{},"         * \n",[193,3681,3682],{"class":195,"line":248},[193,3683,3684],{},"         * 例\n",[193,3686,3687],{"class":195,"line":254},[193,3688,3689],{},"         * $file            => '2017\u002F12\u002FDSC04325-1200x900.jpg'\n",[193,3691,3692],{"class":195,"line":259},[193,3693,3694],{},"         * $targetFilename  => 'DSC04325-1200x900.jpg'\n",[193,3696,3697],{"class":195,"line":265},[193,3698,3699],{},"         * $fullPath        => '\u002Fdocumentroot\u002Fwordpress\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002FDSC04325-1200x900.jpg'\n",[193,3701,3702],{"class":195,"line":271},[193,3703,3704],{},"        *\u002F\n",[193,3706,3707],{"class":195,"line":600},[193,3708,3709],{},"        $filenames = explode('\u002F',$file);\n",[193,3711,3712],{"class":195,"line":606},[193,3713,3714],{},"        $targetFilename = $filenames[count($filenames)-1];\n",[193,3716,3717],{"class":195,"line":612},[193,3718,3719],{},"        $fullPath = $uploadRoot.$file;\n",[193,3721,3722],{"class":195,"line":618},[193,3723,476],{"emptyLinePlaceholder":101},[193,3725,3726],{"class":195,"line":624},[193,3727,3728],{},"        \u002F\u002F getimagesize()を用いて寸法、拡張子の情報を取得。\n",[193,3730,3731],{"class":195,"line":630},[193,3732,3733],{},"        list($w, $h,$type) = getimagesize($fullPath);\n",[193,3735,3736],{"class":195,"line":636},[193,3737,3738],{},"        var_dump($fullPath);\n",[193,3740,3741],{"class":195,"line":642},[193,3742,476],{"emptyLinePlaceholder":101},[193,3744,3745],{"class":195,"line":648},[193,3746,3747],{},"        \u002F\u002F imagecreatefromjpeg()・imagecreatefrompng()にてGDImageを取得。画像を取得しているんだなぐらいだと思ってください。\n",[193,3749,3750],{"class":195,"line":654},[193,3751,3752],{},"        \u002F\u002F JPG\u002FPNGによって分ける必要あり！。\n",[193,3754,3755],{"class":195,"line":660},[193,3756,3757],{},"        switch ($type) {\n",[193,3759,3760],{"class":195,"line":666},[193,3761,3762],{},"            case IMAGETYPE_JPEG:\n",[193,3764,3765],{"class":195,"line":672},[193,3766,3767],{},"                $original_image = imagecreatefromjpeg($fullPath);\n",[193,3769,3770],{"class":195,"line":678},[193,3771,3772],{},"                break;\n",[193,3774,3775],{"class":195,"line":684},[193,3776,3777],{},"            case IMAGETYPE_PNG:\n",[193,3779,3780],{"class":195,"line":690},[193,3781,3782],{},"                $original_image = imagecreatefrompng($fullPath);\n",[193,3784,3785],{"class":195,"line":696},[193,3786,3772],{},[193,3788,3789],{"class":195,"line":702},[193,3790,3791],{},"            default:\n",[193,3793,3794],{"class":195,"line":708},[193,3795,3796],{},"                var_dump('対応していないファイル形式です。: '.$fullPath);\n",[193,3798,3799],{"class":195,"line":714},[193,3800,3801],{},"                continue;\n",[193,3803,3804],{"class":195,"line":720},[193,3805,3806],{},"        }\n",[193,3808,3809],{"class":195,"line":726},[193,3810,476],{"emptyLinePlaceholder":101},[193,3812,3813],{"class":195,"line":731},[193,3814,3815],{},"        \u002F\u002F 寸法が大きすぎるもの(1000px以上)は600pxぐにらいするリサイズ処理を行う。\n",[193,3817,3818],{"class":195,"line":737},[193,3819,3820],{},"        if($w >= 1000){\n",[193,3822,3823],{"class":195,"line":742},[193,3824,476],{"emptyLinePlaceholder":101},[193,3826,3827],{"class":195,"line":747},[193,3828,3829],{},"            \u002F\u002F imagecreatetruecolor() で新しい画像を埋め込むための「枠」を作る。（新しいキャンバス的な？）\n",[193,3831,3832],{"class":195,"line":752},[193,3833,3834],{},"            \u002F\u002F 縦横比を計算させて元画像と同じにさせること。\n",[193,3836,3837],{"class":195,"line":757},[193,3838,3839],{},"            $newW = 600;\n",[193,3841,3842],{"class":195,"line":762},[193,3843,3844],{},"            $newH = $newW * ($h \u002F $w);\n",[193,3846,3847],{"class":195,"line":767},[193,3848,3849],{},"            $newImg = imagecreatetruecolor($newW, $newH);\n",[193,3851,3852],{"class":195,"line":772},[193,3853,476],{"emptyLinePlaceholder":101},[193,3855,3856],{"class":195,"line":777},[193,3857,3858],{},"            \u002F\u002F リサイズ処理。\n",[193,3860,3861],{"class":195,"line":782},[193,3862,3863],{},"            $success = imagecopyresampled($newImg, $original_image, 0, 0, 0, 0, $newW, $newH, $w, $h);\n",[193,3865,3866],{"class":195,"line":787},[193,3867,476],{"emptyLinePlaceholder":101},[193,3869,3870],{"class":195,"line":792},[193,3871,3872],{},"            if($success){\n",[193,3874,3875],{"class":195,"line":797},[193,3876,3877],{},"                $original_image = $newImg;\n",[193,3879,3880],{"class":195,"line":802},[193,3881,3882],{},"            }else{\n",[193,3884,3885],{"class":195,"line":807},[193,3886,3887],{},"                var_dump('リサイズ失敗: '.$fullPath);\n",[193,3889,3890],{"class":195,"line":812},[193,3891,3801],{},[193,3893,3894],{"class":195,"line":817},[193,3895,2681],{},[193,3897,3898],{"class":195,"line":822},[193,3899,3806],{},[193,3901,3902],{"class":195,"line":827},[193,3903,476],{"emptyLinePlaceholder":101},[193,3905,3906],{"class":195,"line":832},[193,3907,3908],{},"        \u002F\u002F 画像を圧縮して同じ名前、パスで上書き保存する。ここも拡張子で異なるので注意！\n",[193,3910,3911],{"class":195,"line":837},[193,3912,3913],{},"        \u002F\u002F 数字は圧縮の品質。低いほど軽くなるが、粗くなる。jpgは0~100,pngは0~9なので注意。\n",[193,3915,3916],{"class":195,"line":842},[193,3917,3757],{},[193,3919,3920],{"class":195,"line":847},[193,3921,3762],{},[193,3923,3924],{"class":195,"line":852},[193,3925,3926],{},"                imagejpeg($original_image,$fullPath,60);\n",[193,3928,3929],{"class":195,"line":857},[193,3930,3772],{},[193,3932,3933],{"class":195,"line":4},[193,3934,3777],{},[193,3936,3937],{"class":195,"line":866},[193,3938,3939],{},"                imagepng($original_image,$fullPath,6);\n",[193,3941,3942],{"class":195,"line":872},[193,3943,3772],{},[193,3945,3946],{"class":195,"line":878},[193,3947,3791],{},[193,3949,3951],{"class":195,"line":3950},67,[193,3952,3796],{},[193,3954,3956],{"class":195,"line":3955},68,[193,3957,3801],{},[193,3959,3961],{"class":195,"line":3960},69,[193,3962,3806],{},[193,3964,3966],{"class":195,"line":3965},70,[193,3967,3968],{},"    }\n",[193,3970,3972],{"class":195,"line":3971},71,[193,3973,3974],{},"?>\n",[13,3976,3977,3978,3981],{},"書いてあるコメントの通りです。ただGDは拡張子ごとに使用する関数を分ける必要があるので、そこがめんどいです。listで予めどんな拡張子が使用されているかを確かめておきましょう。ローカルでテストを行ったら、",[25,3979,3980],{},"image.php, list.php","をサーバーに転送します。",[17,3983,3985],{"id":3984},"実行前の注意","実行前の注意！",[13,3987,3988,3989,3992],{},"実行する前に必ず ",[25,3990,3991],{},"uploads"," のバックアップをしておきましょう。そうすればもしやらかしたり、予想以上に粗くなったとしてもやり直しができます。OKであれば",[49,3994,3997],{"className":3995,"code":3996,"language":54},[52],"php image.php\n",[25,3998,3996],{"__ignoreMap":57},[13,4000,4001],{},"そして実行しましょう。私の場合1500画像で5分ほどで終わった気がします。",[13,4003,4004,4007],{},[25,4005,4006],{},"ls -lh"," や上記のfindコマンドで重い画像がなくなったかを確認しましょう。また、画像のパスをブラウザで叩いて確認してもいいかもしれません。キャッシュが効いていることが多いので、シークレットモードで見ることをお勧めします。",[419,4009,4010],{},"html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}",{"title":57,"searchDepth":90,"depth":90,"links":4012},[4013,4014,4015,4022],{"id":3188,"depth":93,"text":3188},{"id":3215,"depth":93,"text":3215},{"id":3420,"depth":93,"text":3420,"children":4016},[4017,4018],{"id":3423,"depth":90,"text":3424},{"id":3530,"depth":90,"text":3531,"children":4019},[4020,4021],{"id":3535,"depth":212,"text":3536},{"id":3626,"depth":212,"text":3626},{"id":3984,"depth":93,"text":3985},[96],"2021-08-15","wordpressに保存された1〜4MBの1500件の画像を一括に処理する。",{},"\u002Farticles\u002Fwp-batch-image-compress",{"title":3174,"description":4025},"articles\u002Fwp-batch-image-compress",[107,106],"XoVocS1wgJ1s3OqIpny9hQofVYNRjvOcumKbgZx2d98",{"id":4033,"title":4034,"body":4035,"category":8352,"createdAt":8354,"description":4034,"extension":98,"index":99,"meta":8355,"navigation":101,"path":8356,"publish":101,"seo":8357,"series":99,"seriesTitle":99,"stem":8358,"tag":8359,"thumbnail":8360,"updatedAt":99,"__hash__":8361},"articles\u002Farticles\u002Fpinterest-like-style.md","ピンタレストみたいなカードスタイルで動的に要素を追加する方法",{"type":10,"value":4036,"toc":8333},[4037,4040,4043,4046,4049,4058,4061,4064,4235,4252,4255,4749,4753,4757,4760,4771,4775,4793,4797,4804,4807,4810,4813,4816,4819,5126,5133,5136,5139,5143,5146,5421,5426,5429,5436,6926,6929,6946,6949,6952,7236,7242,7245,7726,7739,7742,7789,7792,7795,8182,8195,8198,8317,8320,8323,8330],[13,4038,4039],{},"こんにちはjunです。突然ですがPinterest（ピンタレスト）ってご存知ですが、以下のような感じのスタイルで画像や動画が一覧で検索できるサービスです。",[2959,4041],{":src":4042,":width":2962},"'pinterest-like-style\u002Fpinterest.png'",[13,4044,4045],{},"よくある一覧系のレイアウトは基本的に列と高さを揃えた規則的な物が多い中、ピンタレストは高さが変則であり縦方向に詰めるレイアウトになっています。",[13,4047,4048],{},"ごちゃごちゃとした感じですが、コンテンツがいっぱいあって無駄がないスタイルが好きです。私が関わったあるプロジェクトでこのデザインをやろうとしましたがそこそこ難しかったです。バックから情報を取ってくる仕様だったため、動的に要素を追加してくことを前提として実装の解説をしていきます。コード自体の説明は「実装方法」から行います。",[13,4050,4051,4052,4057],{},"また完成したデモは",[36,4053,4056],{"href":4054,"rel":4055},"https:\u002F\u002Fapps.jun-app.com\u002Fpinterestlike\u002F",[40],"こちら","にあります。",[17,4059,4060],{"id":4060},"構造",[13,4062,4063],{},"構造は以下の通りとします。",[49,4065,4069],{"className":4066,"code":4067,"language":4068,"meta":57,"style":57},"language-html shiki shiki-themes material-theme-ocean","\u003Cdiv class=\"p-cards-render\" id=\"card-container\">\n    \u003Cdiv class=\"c-card-container u-animate\">\n        \u003Cimg src=\".\u002Fred.png\" class=\"c-card-img\">\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\">\n        \u003Cimg src=\".\u002Fred.png\" class=\"c-card-img\">\n    \u003C\u002Fdiv>\n    \u003C!-- c-card-containerが基本コンポーネント -->\n\u003C\u002Fdiv>\n","html",[25,4070,4071,4105,4125,4158,4167,4185,4213,4221,4226],{"__ignoreMap":57},[193,4072,4073,4076,4078,4081,4083,4085,4088,4090,4093,4095,4097,4100,4102],{"class":195,"line":196},[193,4074,4075],{"class":1002},"\u003C",[193,4077,1310],{"class":1014},[193,4079,4080],{"class":994}," class",[193,4082,1003],{"class":1002},[193,4084,1032],{"class":1002},[193,4086,4087],{"class":1035},"p-cards-render",[193,4089,1032],{"class":1002},[193,4091,4092],{"class":994}," id",[193,4094,1003],{"class":1002},[193,4096,1032],{"class":1002},[193,4098,4099],{"class":1035},"card-container",[193,4101,1032],{"class":1002},[193,4103,4104],{"class":1002},">\n",[193,4106,4107,4110,4112,4114,4116,4118,4121,4123],{"class":195,"line":93},[193,4108,4109],{"class":1002},"    \u003C",[193,4111,1310],{"class":1014},[193,4113,4080],{"class":994},[193,4115,1003],{"class":1002},[193,4117,1032],{"class":1002},[193,4119,4120],{"class":1035},"c-card-container u-animate",[193,4122,1032],{"class":1002},[193,4124,4104],{"class":1002},[193,4126,4127,4130,4133,4136,4138,4140,4143,4145,4147,4149,4151,4154,4156],{"class":195,"line":90},[193,4128,4129],{"class":1002},"        \u003C",[193,4131,4132],{"class":1014},"img",[193,4134,4135],{"class":994}," src",[193,4137,1003],{"class":1002},[193,4139,1032],{"class":1002},[193,4141,4142],{"class":1035},".\u002Fred.png",[193,4144,1032],{"class":1002},[193,4146,4080],{"class":994},[193,4148,1003],{"class":1002},[193,4150,1032],{"class":1002},[193,4152,4153],{"class":1035},"c-card-img",[193,4155,1032],{"class":1002},[193,4157,4104],{"class":1002},[193,4159,4160,4163,4165],{"class":195,"line":212},[193,4161,4162],{"class":1002},"    \u003C\u002F",[193,4164,1310],{"class":1014},[193,4166,4104],{"class":1002},[193,4168,4169,4171,4173,4175,4177,4179,4181,4183],{"class":195,"line":218},[193,4170,4109],{"class":1002},[193,4172,1310],{"class":1014},[193,4174,4080],{"class":994},[193,4176,1003],{"class":1002},[193,4178,1032],{"class":1002},[193,4180,4120],{"class":1035},[193,4182,1032],{"class":1002},[193,4184,4104],{"class":1002},[193,4186,4187,4189,4191,4193,4195,4197,4199,4201,4203,4205,4207,4209,4211],{"class":195,"line":224},[193,4188,4129],{"class":1002},[193,4190,4132],{"class":1014},[193,4192,4135],{"class":994},[193,4194,1003],{"class":1002},[193,4196,1032],{"class":1002},[193,4198,4142],{"class":1035},[193,4200,1032],{"class":1002},[193,4202,4080],{"class":994},[193,4204,1003],{"class":1002},[193,4206,1032],{"class":1002},[193,4208,4153],{"class":1035},[193,4210,1032],{"class":1002},[193,4212,4104],{"class":1002},[193,4214,4215,4217,4219],{"class":195,"line":230},[193,4216,4162],{"class":1002},[193,4218,1310],{"class":1014},[193,4220,4104],{"class":1002},[193,4222,4223],{"class":195,"line":236},[193,4224,4225],{"class":1136},"    \u003C!-- c-card-containerが基本コンポーネント -->\n",[193,4227,4228,4231,4233],{"class":195,"line":242},[193,4229,4230],{"class":1002},"\u003C\u002F",[193,4232,1310],{"class":1014},[193,4234,4104],{"class":1002},[13,4236,4237,4239,4240,4243,4244,4247,4248,4251],{},[25,4238,4099],{},"はカード全体の列を定義するコンテナです。",[25,4241,4242],{},"c-card-container","は１カードのコンテナーで他のカードとの隙間やレイアウトの定義をしています。そしてカードのコンテナには",[25,4245,4246],{},"\u003Cimg>","がラップされ、",[25,4249,4250],{},"width:100%; height:100%;","がかかっています。今回表示する画像は一面一色に塗り潰された画像です。（background-colorでもよかったのですが）",[13,4253,4254],{},"最終的なcssは以下の通りです。",[49,4256,4260],{"className":4257,"code":4258,"language":4259,"meta":57,"style":57},"language-css shiki shiki-themes material-theme-ocean","*{\n    margin: 0;\n    padding: 0;\n    box-sizing: border-box;\n}\n\n#card-add{\n    position: fixed;\n    left: 20px;\n    top: 50%;\n}\n\n.p-main-container{\n    max-width: 660px;\n    margin: 0 auto;\n    padding: 30px 0px;\n    min-height: 100vh;\n}\n\n.p-cards-render{\n    margin: 0 -5px;\n    display: flex;\n    flex-wrap: wrap;\n    position: relative;\n}\n\n.p-cards-render .c-card-container{\n    position: absolute;\n    top: 0px;\n    width: 33.3%;\n    display: block;\n    padding: 0 5px 10px 5px;\n}\n\n\n.c-card-container .c-card-img{\n    width: 100%;\n    box-shadow: 0px 2px 4px #ccc;\n    border-radius: 30px;\n    height: 0%;\n    display: block;\n    opacity: 0;\n    transition: all 0.4s;\n}\n.c-card-container.u-animate .c-card-img{\n    height: 100%;\n    opacity: 1;\n    transition: all 0.4s;\n}\n","css",[25,4261,4262,4269,4282,4293,4305,4309,4313,4323,4335,4347,4359,4363,4367,4376,4388,4401,4415,4427,4431,4435,4443,4456,4468,4480,4491,4495,4499,4512,4523,4533,4545,4556,4574,4578,4582,4586,4598,4609,4632,4643,4655,4665,4676,4691,4695,4712,4722,4733,4745],{"__ignoreMap":57},[193,4263,4264,4267],{"class":195,"line":196},[193,4265,4266],{"class":3254},"*",[193,4268,233],{"class":1002},[193,4270,4271,4275,4277,4280],{"class":195,"line":93},[193,4272,4274],{"class":4273},"s6YsC","    margin",[193,4276,1018],{"class":1002},[193,4278,4279],{"class":1021}," 0",[193,4281,1192],{"class":1002},[193,4283,4284,4287,4289,4291],{"class":195,"line":90},[193,4285,4286],{"class":4273},"    padding",[193,4288,1018],{"class":1002},[193,4290,4279],{"class":1021},[193,4292,1192],{"class":1002},[193,4294,4295,4298,4300,4303],{"class":195,"line":212},[193,4296,4297],{"class":4273},"    box-sizing",[193,4299,1018],{"class":1002},[193,4301,4302],{"class":998}," border-box",[193,4304,1192],{"class":1002},[193,4306,4307],{"class":195,"line":218},[193,4308,274],{"class":1002},[193,4310,4311],{"class":195,"line":224},[193,4312,476],{"emptyLinePlaceholder":101},[193,4314,4315,4318,4321],{"class":195,"line":230},[193,4316,4317],{"class":1002},"#",[193,4319,4320],{"class":1021},"card-add",[193,4322,233],{"class":1002},[193,4324,4325,4328,4330,4333],{"class":195,"line":236},[193,4326,4327],{"class":4273},"    position",[193,4329,1018],{"class":1002},[193,4331,4332],{"class":998}," fixed",[193,4334,1192],{"class":1002},[193,4336,4337,4340,4342,4345],{"class":195,"line":242},[193,4338,4339],{"class":4273},"    left",[193,4341,1018],{"class":1002},[193,4343,4344],{"class":1021}," 20px",[193,4346,1192],{"class":1002},[193,4348,4349,4352,4354,4357],{"class":195,"line":248},[193,4350,4351],{"class":4273},"    top",[193,4353,1018],{"class":1002},[193,4355,4356],{"class":1021}," 50%",[193,4358,1192],{"class":1002},[193,4360,4361],{"class":195,"line":254},[193,4362,274],{"class":1002},[193,4364,4365],{"class":195,"line":259},[193,4366,476],{"emptyLinePlaceholder":101},[193,4368,4369,4371,4374],{"class":195,"line":265},[193,4370,1186],{"class":1002},[193,4372,4373],{"class":3254},"p-main-container",[193,4375,233],{"class":1002},[193,4377,4378,4381,4383,4386],{"class":195,"line":271},[193,4379,4380],{"class":4273},"    max-width",[193,4382,1018],{"class":1002},[193,4384,4385],{"class":1021}," 660px",[193,4387,1192],{"class":1002},[193,4389,4390,4392,4394,4396,4399],{"class":195,"line":600},[193,4391,4274],{"class":4273},[193,4393,1018],{"class":1002},[193,4395,4279],{"class":1021},[193,4397,4398],{"class":998}," auto",[193,4400,1192],{"class":1002},[193,4402,4403,4405,4407,4410,4413],{"class":195,"line":606},[193,4404,4286],{"class":4273},[193,4406,1018],{"class":1002},[193,4408,4409],{"class":1021}," 30px",[193,4411,4412],{"class":1021}," 0px",[193,4414,1192],{"class":1002},[193,4416,4417,4420,4422,4425],{"class":195,"line":612},[193,4418,4419],{"class":4273},"    min-height",[193,4421,1018],{"class":1002},[193,4423,4424],{"class":1021}," 100vh",[193,4426,1192],{"class":1002},[193,4428,4429],{"class":195,"line":618},[193,4430,274],{"class":1002},[193,4432,4433],{"class":195,"line":624},[193,4434,476],{"emptyLinePlaceholder":101},[193,4436,4437,4439,4441],{"class":195,"line":630},[193,4438,1186],{"class":1002},[193,4440,4087],{"class":3254},[193,4442,233],{"class":1002},[193,4444,4445,4447,4449,4451,4454],{"class":195,"line":636},[193,4446,4274],{"class":4273},[193,4448,1018],{"class":1002},[193,4450,4279],{"class":1021},[193,4452,4453],{"class":1021}," -5px",[193,4455,1192],{"class":1002},[193,4457,4458,4461,4463,4466],{"class":195,"line":642},[193,4459,4460],{"class":4273},"    display",[193,4462,1018],{"class":1002},[193,4464,4465],{"class":998}," flex",[193,4467,1192],{"class":1002},[193,4469,4470,4473,4475,4478],{"class":195,"line":648},[193,4471,4472],{"class":4273},"    flex-wrap",[193,4474,1018],{"class":1002},[193,4476,4477],{"class":998}," wrap",[193,4479,1192],{"class":1002},[193,4481,4482,4484,4486,4489],{"class":195,"line":654},[193,4483,4327],{"class":4273},[193,4485,1018],{"class":1002},[193,4487,4488],{"class":998}," relative",[193,4490,1192],{"class":1002},[193,4492,4493],{"class":195,"line":660},[193,4494,274],{"class":1002},[193,4496,4497],{"class":195,"line":666},[193,4498,476],{"emptyLinePlaceholder":101},[193,4500,4501,4503,4505,4508,4510],{"class":195,"line":672},[193,4502,1186],{"class":1002},[193,4504,4087],{"class":3254},[193,4506,4507],{"class":1002}," .",[193,4509,4242],{"class":3254},[193,4511,233],{"class":1002},[193,4513,4514,4516,4518,4521],{"class":195,"line":678},[193,4515,4327],{"class":4273},[193,4517,1018],{"class":1002},[193,4519,4520],{"class":998}," absolute",[193,4522,1192],{"class":1002},[193,4524,4525,4527,4529,4531],{"class":195,"line":684},[193,4526,4351],{"class":4273},[193,4528,1018],{"class":1002},[193,4530,4412],{"class":1021},[193,4532,1192],{"class":1002},[193,4534,4535,4538,4540,4543],{"class":195,"line":690},[193,4536,4537],{"class":4273},"    width",[193,4539,1018],{"class":1002},[193,4541,4542],{"class":1021}," 33.3%",[193,4544,1192],{"class":1002},[193,4546,4547,4549,4551,4554],{"class":195,"line":696},[193,4548,4460],{"class":4273},[193,4550,1018],{"class":1002},[193,4552,4553],{"class":998}," block",[193,4555,1192],{"class":1002},[193,4557,4558,4560,4562,4564,4567,4570,4572],{"class":195,"line":702},[193,4559,4286],{"class":4273},[193,4561,1018],{"class":1002},[193,4563,4279],{"class":1021},[193,4565,4566],{"class":1021}," 5px",[193,4568,4569],{"class":1021}," 10px",[193,4571,4566],{"class":1021},[193,4573,1192],{"class":1002},[193,4575,4576],{"class":195,"line":708},[193,4577,274],{"class":1002},[193,4579,4580],{"class":195,"line":714},[193,4581,476],{"emptyLinePlaceholder":101},[193,4583,4584],{"class":195,"line":720},[193,4585,476],{"emptyLinePlaceholder":101},[193,4587,4588,4590,4592,4594,4596],{"class":195,"line":726},[193,4589,1186],{"class":1002},[193,4591,4242],{"class":3254},[193,4593,4507],{"class":1002},[193,4595,4153],{"class":3254},[193,4597,233],{"class":1002},[193,4599,4600,4602,4604,4607],{"class":195,"line":731},[193,4601,4537],{"class":4273},[193,4603,1018],{"class":1002},[193,4605,4606],{"class":1021}," 100%",[193,4608,1192],{"class":1002},[193,4610,4611,4614,4616,4618,4621,4624,4627,4630],{"class":195,"line":737},[193,4612,4613],{"class":4273},"    box-shadow",[193,4615,1018],{"class":1002},[193,4617,4412],{"class":1021},[193,4619,4620],{"class":1021}," 2px",[193,4622,4623],{"class":1021}," 4px",[193,4625,4626],{"class":1002}," #",[193,4628,4629],{"class":998},"ccc",[193,4631,1192],{"class":1002},[193,4633,4634,4637,4639,4641],{"class":195,"line":742},[193,4635,4636],{"class":4273},"    border-radius",[193,4638,1018],{"class":1002},[193,4640,4409],{"class":1021},[193,4642,1192],{"class":1002},[193,4644,4645,4648,4650,4653],{"class":195,"line":747},[193,4646,4647],{"class":4273},"    height",[193,4649,1018],{"class":1002},[193,4651,4652],{"class":1021}," 0%",[193,4654,1192],{"class":1002},[193,4656,4657,4659,4661,4663],{"class":195,"line":752},[193,4658,4460],{"class":4273},[193,4660,1018],{"class":1002},[193,4662,4553],{"class":998},[193,4664,1192],{"class":1002},[193,4666,4667,4670,4672,4674],{"class":195,"line":757},[193,4668,4669],{"class":4273},"    opacity",[193,4671,1018],{"class":1002},[193,4673,4279],{"class":1021},[193,4675,1192],{"class":1002},[193,4677,4678,4681,4683,4686,4689],{"class":195,"line":762},[193,4679,4680],{"class":4273},"    transition",[193,4682,1018],{"class":1002},[193,4684,4685],{"class":998}," all ",[193,4687,4688],{"class":1021},"0.4s",[193,4690,1192],{"class":1002},[193,4692,4693],{"class":195,"line":767},[193,4694,274],{"class":1002},[193,4696,4697,4699,4701,4703,4706,4708,4710],{"class":195,"line":772},[193,4698,1186],{"class":1002},[193,4700,4242],{"class":3254},[193,4702,1186],{"class":1002},[193,4704,4705],{"class":3254},"u-animate",[193,4707,4507],{"class":1002},[193,4709,4153],{"class":3254},[193,4711,233],{"class":1002},[193,4713,4714,4716,4718,4720],{"class":195,"line":777},[193,4715,4647],{"class":4273},[193,4717,1018],{"class":1002},[193,4719,4606],{"class":1021},[193,4721,1192],{"class":1002},[193,4723,4724,4726,4728,4731],{"class":195,"line":782},[193,4725,4669],{"class":4273},[193,4727,1018],{"class":1002},[193,4729,4730],{"class":1021}," 1",[193,4732,1192],{"class":1002},[193,4734,4735,4737,4739,4741,4743],{"class":195,"line":787},[193,4736,4680],{"class":4273},[193,4738,1018],{"class":1002},[193,4740,4685],{"class":998},[193,4742,4688],{"class":1021},[193,4744,1192],{"class":1002},[193,4746,4747],{"class":195,"line":792},[193,4748,274],{"class":1002},[17,4750,4752],{"id":4751},"表示数が不明な場合cssだけでは不可能だった","表示数が不明な場合CSSだけでは不可能だった",[133,4754,4756],{"id":4755},"flexでいけんじゃね","flexでいけんじゃね...？!",[13,4758,4759],{},"最初はそれぞれの要素にを縦方向に詰められればいいだけだろと思いました。",[13,4761,4762,4763,4766,4767,4770],{},"そのためカードコンテナーを ",[25,4764,4765],{},"display:inline-block;"," にして ",[25,4768,4769],{},"vertical-align:top;","を指定しましたが下図の様になっていしまいます。",[2959,4772],{":src":4773,":width":4774,":center":1552},"'pinterest-like-style\u002Fdisplay-inline.png'","'300px'",[13,4776,4777,4778,4780,4781,4784,4785,4788,4789,4792],{},"カードコンテナーを ",[25,4779,4765],{},"と",[25,4782,4783],{},"algin-self:flex-start;","を指定しても同様の結果となります。",[25,4786,4787],{},"flex","や",[25,4790,4791],{},"inline-block","の仕様上仕方ないです。",[133,4794,4796],{"id":4795},"display-gridならいけるが","display gridならいけるが...",[13,4798,4799,4800,4803],{},"flexは縦方向の制御が難しく、ピンタレストの様なスタイルをcssで実現するためには",[25,4801,4802],{},"display:grid;","というグリットレイアウトを指定する必要があります。",[13,4805,4806],{},"今回はGridの説明は省きます。グリットレイアウトは各要素の縦方向の位置を定義できるので、柔軟なレイアウトを実現できます。",[13,4808,4809],{},"しかし、グリットレイアウトは列数、行数、各要素の占有列・行を指定する必要があります。そのため動的に要素を追加する場合はJavascriptで各要素の位置スタイルを調整する必要があります。",[17,4811,4812],{"id":4812},"実装方法",[133,4814,4815],{"id":4815},"概要",[13,4817,4818],{},"それでは実装の概要について解説します。CSS（インラインスタイル）をカード要素に指定します。いろいろ方法はありますが、ピンタレスト公式でも以下の様なスタイルが要素に当てられています。",[49,4820,4822],{"className":4066,"code":4821,"language":4068,"meta":57,"style":57},"\u003Cdiv class=\"p-cards-render\" id=\"card-container\">\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"06p17111s5\" style=\"height:309px; transform:translate(0%,0px);\">\u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"l1dq533ms9g\" style=\"height:246px; transform:translate(100%,0px);\">\u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"k6n2ebd918g\" style=\"height:306px; transform:translate(200%,0px);\">\u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"2j3vvgc373g\" style=\"height:161px; transform:translate(0%,309px);\">\u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"tagrso5m40o\" style=\"height:255px; transform:translate(100%,246px);\">\u003C\u002Fdiv>\n    \u003Cdiv class=\"c-card-container u-animate\" id=\"89opa7i1eng\" style=\"height:288px; transform:translate(200%,306px);\">\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n",[25,4823,4824,4852,4898,4942,4986,5030,5074,5118],{"__ignoreMap":57},[193,4825,4826,4828,4830,4832,4834,4836,4838,4840,4842,4844,4846,4848,4850],{"class":195,"line":196},[193,4827,4075],{"class":1002},[193,4829,1310],{"class":1014},[193,4831,4080],{"class":994},[193,4833,1003],{"class":1002},[193,4835,1032],{"class":1002},[193,4837,4087],{"class":1035},[193,4839,1032],{"class":1002},[193,4841,4092],{"class":994},[193,4843,1003],{"class":1002},[193,4845,1032],{"class":1002},[193,4847,4099],{"class":1035},[193,4849,1032],{"class":1002},[193,4851,4104],{"class":1002},[193,4853,4854,4856,4858,4860,4862,4864,4866,4868,4870,4872,4874,4877,4879,4882,4884,4886,4889,4891,4894,4896],{"class":195,"line":93},[193,4855,4109],{"class":1002},[193,4857,1310],{"class":1014},[193,4859,4080],{"class":994},[193,4861,1003],{"class":1002},[193,4863,1032],{"class":1002},[193,4865,4120],{"class":1035},[193,4867,1032],{"class":1002},[193,4869,4092],{"class":994},[193,4871,1003],{"class":1002},[193,4873,1032],{"class":1002},[193,4875,4876],{"class":1035},"06p17111s5",[193,4878,1032],{"class":1002},[193,4880,4881],{"class":994}," style",[193,4883,1003],{"class":1002},[193,4885,1032],{"class":1002},[193,4887,4888],{"class":1035},"height:309px; transform:translate(0%,0px);",[193,4890,1032],{"class":1002},[193,4892,4893],{"class":1002},">\u003C\u002F",[193,4895,1310],{"class":1014},[193,4897,4104],{"class":1002},[193,4899,4900,4902,4904,4906,4908,4910,4912,4914,4916,4918,4920,4923,4925,4927,4929,4931,4934,4936,4938,4940],{"class":195,"line":90},[193,4901,4109],{"class":1002},[193,4903,1310],{"class":1014},[193,4905,4080],{"class":994},[193,4907,1003],{"class":1002},[193,4909,1032],{"class":1002},[193,4911,4120],{"class":1035},[193,4913,1032],{"class":1002},[193,4915,4092],{"class":994},[193,4917,1003],{"class":1002},[193,4919,1032],{"class":1002},[193,4921,4922],{"class":1035},"l1dq533ms9g",[193,4924,1032],{"class":1002},[193,4926,4881],{"class":994},[193,4928,1003],{"class":1002},[193,4930,1032],{"class":1002},[193,4932,4933],{"class":1035},"height:246px; transform:translate(100%,0px);",[193,4935,1032],{"class":1002},[193,4937,4893],{"class":1002},[193,4939,1310],{"class":1014},[193,4941,4104],{"class":1002},[193,4943,4944,4946,4948,4950,4952,4954,4956,4958,4960,4962,4964,4967,4969,4971,4973,4975,4978,4980,4982,4984],{"class":195,"line":212},[193,4945,4109],{"class":1002},[193,4947,1310],{"class":1014},[193,4949,4080],{"class":994},[193,4951,1003],{"class":1002},[193,4953,1032],{"class":1002},[193,4955,4120],{"class":1035},[193,4957,1032],{"class":1002},[193,4959,4092],{"class":994},[193,4961,1003],{"class":1002},[193,4963,1032],{"class":1002},[193,4965,4966],{"class":1035},"k6n2ebd918g",[193,4968,1032],{"class":1002},[193,4970,4881],{"class":994},[193,4972,1003],{"class":1002},[193,4974,1032],{"class":1002},[193,4976,4977],{"class":1035},"height:306px; transform:translate(200%,0px);",[193,4979,1032],{"class":1002},[193,4981,4893],{"class":1002},[193,4983,1310],{"class":1014},[193,4985,4104],{"class":1002},[193,4987,4988,4990,4992,4994,4996,4998,5000,5002,5004,5006,5008,5011,5013,5015,5017,5019,5022,5024,5026,5028],{"class":195,"line":218},[193,4989,4109],{"class":1002},[193,4991,1310],{"class":1014},[193,4993,4080],{"class":994},[193,4995,1003],{"class":1002},[193,4997,1032],{"class":1002},[193,4999,4120],{"class":1035},[193,5001,1032],{"class":1002},[193,5003,4092],{"class":994},[193,5005,1003],{"class":1002},[193,5007,1032],{"class":1002},[193,5009,5010],{"class":1035},"2j3vvgc373g",[193,5012,1032],{"class":1002},[193,5014,4881],{"class":994},[193,5016,1003],{"class":1002},[193,5018,1032],{"class":1002},[193,5020,5021],{"class":1035},"height:161px; transform:translate(0%,309px);",[193,5023,1032],{"class":1002},[193,5025,4893],{"class":1002},[193,5027,1310],{"class":1014},[193,5029,4104],{"class":1002},[193,5031,5032,5034,5036,5038,5040,5042,5044,5046,5048,5050,5052,5055,5057,5059,5061,5063,5066,5068,5070,5072],{"class":195,"line":224},[193,5033,4109],{"class":1002},[193,5035,1310],{"class":1014},[193,5037,4080],{"class":994},[193,5039,1003],{"class":1002},[193,5041,1032],{"class":1002},[193,5043,4120],{"class":1035},[193,5045,1032],{"class":1002},[193,5047,4092],{"class":994},[193,5049,1003],{"class":1002},[193,5051,1032],{"class":1002},[193,5053,5054],{"class":1035},"tagrso5m40o",[193,5056,1032],{"class":1002},[193,5058,4881],{"class":994},[193,5060,1003],{"class":1002},[193,5062,1032],{"class":1002},[193,5064,5065],{"class":1035},"height:255px; transform:translate(100%,246px);",[193,5067,1032],{"class":1002},[193,5069,4893],{"class":1002},[193,5071,1310],{"class":1014},[193,5073,4104],{"class":1002},[193,5075,5076,5078,5080,5082,5084,5086,5088,5090,5092,5094,5096,5099,5101,5103,5105,5107,5110,5112,5114,5116],{"class":195,"line":230},[193,5077,4109],{"class":1002},[193,5079,1310],{"class":1014},[193,5081,4080],{"class":994},[193,5083,1003],{"class":1002},[193,5085,1032],{"class":1002},[193,5087,4120],{"class":1035},[193,5089,1032],{"class":1002},[193,5091,4092],{"class":994},[193,5093,1003],{"class":1002},[193,5095,1032],{"class":1002},[193,5097,5098],{"class":1035},"89opa7i1eng",[193,5100,1032],{"class":1002},[193,5102,4881],{"class":994},[193,5104,1003],{"class":1002},[193,5106,1032],{"class":1002},[193,5108,5109],{"class":1035},"height:288px; transform:translate(200%,306px);",[193,5111,1032],{"class":1002},[193,5113,4893],{"class":1002},[193,5115,1310],{"class":1014},[193,5117,4104],{"class":1002},[193,5119,5120,5122,5124],{"class":195,"line":236},[193,5121,4230],{"class":1002},[193,5123,1310],{"class":1014},[193,5125,4104],{"class":1002},[13,5127,5128,5129,5132],{},"それぞのコンテナーに対して",[25,5130,5131],{},"height:246px; transform:translate(200%,306px);","というものあります。まず固有の高さを指定し、そしてtransformを使用して位置を変更しています。",[13,5134,5135],{},"要素が追加される度に始点（left:0;,top:0;）から移動させ、位置を指定してあげます。2021年7月時点のCSSではこの様にしないと、数不明・ここの高さが不明な要素に対してピンタレストのようなスタイルを適用することができません。",[13,5137,5138],{},"では次はそれを実装するjavascriptを書いていきます。",[133,5140,5142],{"id":5141},"htmlの前準備","HTMLの前準備",[13,5144,5145],{},"HTMLは以下の様にしておきます。",[49,5147,5149],{"className":4066,"code":5148,"language":4068,"meta":57,"style":57},"\u003C!DOCTYPE html>\n\u003Chtml>\n    \u003Chead>\n        \u003Cmeta charset=\"utf-8\"> \n        \u003Ctitle>Pinterest like Style\u003C\u002Ftitle>\n        \u003Clink rel=\"stylesheet\" href=\".\u002Fstyle.css\">\n    \u003C\u002Fhead>\n    \u003Cbody>\n        \u003Cdiv class=\"p-main-container\">\n            \u003Cdiv class=\"p-cards-render\" id=\"card-container\">\n\n            \u003C\u002Fdiv>\n            \u003Cbutton id='card-add'>ADD!\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n    \u003C\u002Fbody>\n    \u003Cscript src=\".\u002Fcard.js\" type=\"text\u002Fjavascript\">\u003C\u002Fscript>\n\u003C\u002Fhtml>\n",[25,5150,5151,5164,5172,5181,5205,5222,5255,5263,5272,5290,5319,5323,5332,5360,5369,5377,5413],{"__ignoreMap":57},[193,5152,5153,5156,5159,5162],{"class":195,"line":196},[193,5154,5155],{"class":1002},"\u003C!",[193,5157,5158],{"class":1014},"DOCTYPE",[193,5160,5161],{"class":994}," html",[193,5163,4104],{"class":1002},[193,5165,5166,5168,5170],{"class":195,"line":93},[193,5167,4075],{"class":1002},[193,5169,4068],{"class":1014},[193,5171,4104],{"class":1002},[193,5173,5174,5176,5179],{"class":195,"line":90},[193,5175,4109],{"class":1002},[193,5177,5178],{"class":1014},"head",[193,5180,4104],{"class":1002},[193,5182,5183,5185,5188,5191,5193,5195,5198,5200,5202],{"class":195,"line":212},[193,5184,4129],{"class":1002},[193,5186,5187],{"class":1014},"meta",[193,5189,5190],{"class":994}," charset",[193,5192,1003],{"class":1002},[193,5194,1032],{"class":1002},[193,5196,5197],{"class":1035},"utf-8",[193,5199,1032],{"class":1002},[193,5201,1344],{"class":1002},[193,5203,5204],{"class":998}," \n",[193,5206,5207,5209,5211,5213,5216,5218,5220],{"class":195,"line":218},[193,5208,4129],{"class":1002},[193,5210,1027],{"class":1014},[193,5212,1344],{"class":1002},[193,5214,5215],{"class":998},"Pinterest like Style",[193,5217,4230],{"class":1002},[193,5219,1027],{"class":1014},[193,5221,4104],{"class":1002},[193,5223,5224,5226,5229,5232,5234,5236,5239,5241,5244,5246,5248,5251,5253],{"class":195,"line":224},[193,5225,4129],{"class":1002},[193,5227,5228],{"class":1014},"link",[193,5230,5231],{"class":994}," rel",[193,5233,1003],{"class":1002},[193,5235,1032],{"class":1002},[193,5237,5238],{"class":1035},"stylesheet",[193,5240,1032],{"class":1002},[193,5242,5243],{"class":994}," href",[193,5245,1003],{"class":1002},[193,5247,1032],{"class":1002},[193,5249,5250],{"class":1035},".\u002Fstyle.css",[193,5252,1032],{"class":1002},[193,5254,4104],{"class":1002},[193,5256,5257,5259,5261],{"class":195,"line":230},[193,5258,4162],{"class":1002},[193,5260,5178],{"class":1014},[193,5262,4104],{"class":1002},[193,5264,5265,5267,5270],{"class":195,"line":236},[193,5266,4109],{"class":1002},[193,5268,5269],{"class":1014},"body",[193,5271,4104],{"class":1002},[193,5273,5274,5276,5278,5280,5282,5284,5286,5288],{"class":195,"line":242},[193,5275,4129],{"class":1002},[193,5277,1310],{"class":1014},[193,5279,4080],{"class":994},[193,5281,1003],{"class":1002},[193,5283,1032],{"class":1002},[193,5285,4373],{"class":1035},[193,5287,1032],{"class":1002},[193,5289,4104],{"class":1002},[193,5291,5292,5295,5297,5299,5301,5303,5305,5307,5309,5311,5313,5315,5317],{"class":195,"line":248},[193,5293,5294],{"class":1002},"            \u003C",[193,5296,1310],{"class":1014},[193,5298,4080],{"class":994},[193,5300,1003],{"class":1002},[193,5302,1032],{"class":1002},[193,5304,4087],{"class":1035},[193,5306,1032],{"class":1002},[193,5308,4092],{"class":994},[193,5310,1003],{"class":1002},[193,5312,1032],{"class":1002},[193,5314,4099],{"class":1035},[193,5316,1032],{"class":1002},[193,5318,4104],{"class":1002},[193,5320,5321],{"class":195,"line":254},[193,5322,476],{"emptyLinePlaceholder":101},[193,5324,5325,5328,5330],{"class":195,"line":259},[193,5326,5327],{"class":1002},"            \u003C\u002F",[193,5329,1310],{"class":1014},[193,5331,4104],{"class":1002},[193,5333,5334,5336,5339,5341,5343,5345,5347,5349,5351,5354,5356,5358],{"class":195,"line":265},[193,5335,5294],{"class":1002},[193,5337,5338],{"class":1014},"button",[193,5340,4092],{"class":994},[193,5342,1003],{"class":1002},[193,5344,2824],{"class":1002},[193,5346,4320],{"class":1035},[193,5348,2824],{"class":1002},[193,5350,1344],{"class":1002},[193,5352,5353],{"class":998},"ADD!",[193,5355,4230],{"class":1002},[193,5357,5338],{"class":1014},[193,5359,4104],{"class":1002},[193,5361,5362,5365,5367],{"class":195,"line":271},[193,5363,5364],{"class":1002},"        \u003C\u002F",[193,5366,1310],{"class":1014},[193,5368,4104],{"class":1002},[193,5370,5371,5373,5375],{"class":195,"line":600},[193,5372,4162],{"class":1002},[193,5374,5269],{"class":1014},[193,5376,4104],{"class":1002},[193,5378,5379,5381,5384,5386,5388,5390,5393,5395,5398,5400,5402,5405,5407,5409,5411],{"class":195,"line":606},[193,5380,4109],{"class":1002},[193,5382,5383],{"class":1014},"script",[193,5385,4135],{"class":994},[193,5387,1003],{"class":1002},[193,5389,1032],{"class":1002},[193,5391,5392],{"class":1035},".\u002Fcard.js",[193,5394,1032],{"class":1002},[193,5396,5397],{"class":994}," type",[193,5399,1003],{"class":1002},[193,5401,1032],{"class":1002},[193,5403,5404],{"class":1035},"text\u002Fjavascript",[193,5406,1032],{"class":1002},[193,5408,4893],{"class":1002},[193,5410,5383],{"class":1014},[193,5412,4104],{"class":1002},[193,5414,5415,5417,5419],{"class":195,"line":612},[193,5416,4230],{"class":1002},[193,5418,4068],{"class":1014},[193,5420,4104],{"class":1002},[13,5422,5423,5425],{},[25,5424,4099],{},"にカードが挿入されていきます。ADD！というボタンを押すことで今回はカードが追加されていくことにします。",[133,5427,5428],{"id":5428},"javascriptはこの通り",[13,5430,5431,5432,5435],{},"同じディレクトリに",[25,5433,5434],{},"card.js","をおいておきます。いきなりですが、全て見せます。完成形は以下の通りです。",[49,5437,5439],{"className":985,"code":5438,"language":987,"meta":57,"style":57},"\u002F\u002F カード情報を格納\nlet elements = [];\n\n\u002F\u002F カードの初期値\nlet elementInit = {\n    id:undefined,\n    color:undefined,\n    selfHeight:0,\n    y:0\n};\n\n\u002F\u002F 列数\nlet row = 3;\n\n\u002F\u002F 挿入先コンテナ\nconst cardsContainer = document.getElementById('card-container');\n\n\u002F\u002F 追加ボタン\nconst cardsAddBtn = document.getElementById('card-add');\n\n\u002F\u002F　カード高さの最大値と最小値\nconst heightMax = 400;\nconst heightMin = 100;\n\n\u002F\u002F 色のパターンとカード間の隙間（px）\nconst colors = ['red','yellow','green','orange','blue','purple'];\nconst cardGap = 10;\n\n\u002F\u002F 追加ボタンにイベントリスナーを付与\ncardsAddBtn.addEventListener('click',()=>{\n    return onClickAdd();\n})\n\n\u002F\u002F イベントリスナーの内容\nlet onClickAdd = ()=>{\n    let card = createCard();\n    insertCard(card.dom);\n    scanAdd(card.id);\n}\n\n\u002F\u002F カードのDOMを新規作成\nlet createCard = ()=>{\n    let info = {...elementInit};\n\n    \u002F\u002F カードの要素をdivで作成\n    let contain = document.createElement(\"DIV\");\n    contain.setAttribute('class','c-card-container');\n\n    \u002F\u002F IDをランダムに作成、記録\n    let idname = Math.random().toString(32).substring(2);\n    contain.setAttribute('id',idname);\n    info.id = idname;\n\n    \u002F\u002F カードに表示される画像（一色塗り潰し）を設定、記録\n    \u002F\u002F colorsの値と画像名が同じ。\n    let card = document.createElement(\"IMG\");\n    let color = colors[Math.floor(Math.random() * colors.length)];\n    info.color = color;\n\n    \u002F\u002F IMG要素にカラーの画像とクラス名を付与\n    card.setAttribute('src','.\u002F'+color+'.png');\n    card.setAttribute('class','c-card-img');\n\n    \u002F\u002F カードに対して不明な高さを与える\n    info.selfHeight = Math.floor(Math.random()*(heightMax+1-heightMin))+heightMin;\n    \n    \u002F\u002F カードDIVにIMGを追加\n    contain.appendChild(card);\n\n    \u002F\u002F elementsに記録。DOMとIDを返す\n    elements.push(info);\n    return {dom:contain,id:idname};\n}\n\n\u002F\u002F カードコンテナーにカードを追加する\nlet insertCard = (cardDom)=>{\n    cardsContainer.appendChild(cardDom);\n}\n\n\u002F\u002F これが大切\n\u002F\u002F IDで紐づいたDOMに対して高さと位置を決定させる。\nlet scanAdd = (id) =>{\n    \u002F\u002F elementsから対象カードのIDの番号、情報を取得\n    let index = elements.findIndex(ele=>{return ele.id===id});\n    let ele = elements[index]\n\n    \u002F\u002F DOMを取得\n    let dom = document.getElementById(ele.id);\n\n    \u002F\u002F index、つまりカードが何晩目かと列数でx,yの位置を決定する。\n    let height = ele.selfHeight\n    ele.y = (index \u003C row)?height:elements[index - row].y + height;\n    let x = (index%(row)*100) + '%';\n    let y = (index \u003C row)?0:elements[index - row].y;\n    \n    \u002F\u002F 位置をずらすスタイルを適用\n    dom.setAttribute('style',`height:${height}px; transform:translate(${x},${y}px);`)\n\n    \u002F\u002F アニメーション用のスタイルを追加\n    setTimeout(()=>{\n        dom.classList.add('u-animate')\n    },500);\n}\n",[25,5440,5441,5446,5461,5465,5470,5481,5489,5496,5507,5517,5522,5526,5531,5545,5549,5554,5583,5587,5592,5619,5623,5628,5642,5656,5660,5665,5732,5746,5750,5755,5781,5793,5799,5803,5808,5824,5841,5860,5877,5881,5885,5890,5905,5921,5925,5930,5959,5990,5994,5999,6043,6068,6083,6087,6092,6097,6124,6171,6186,6190,6195,6240,6268,6272,6277,6330,6335,6340,6357,6361,6366,6385,6409,6414,6419,6425,6447,6465,6470,6475,6481,6487,6507,6513,6559,6577,6582,6588,6616,6621,6627,6644,6702,6744,6788,6793,6799,6857,6862,6868,6882,6908,6921],{"__ignoreMap":57},[193,5442,5443],{"class":195,"line":196},[193,5444,5445],{"class":1136},"\u002F\u002F カード情報を格納\n",[193,5447,5448,5451,5454,5456,5459],{"class":195,"line":93},[193,5449,5450],{"class":994},"let",[193,5452,5453],{"class":998}," elements ",[193,5455,1003],{"class":1002},[193,5457,5458],{"class":998}," []",[193,5460,1192],{"class":1002},[193,5462,5463],{"class":195,"line":90},[193,5464,476],{"emptyLinePlaceholder":101},[193,5466,5467],{"class":195,"line":212},[193,5468,5469],{"class":1136},"\u002F\u002F カードの初期値\n",[193,5471,5472,5474,5477,5479],{"class":195,"line":218},[193,5473,5450],{"class":994},[193,5475,5476],{"class":998}," elementInit ",[193,5478,1003],{"class":1002},[193,5480,2534],{"class":1002},[193,5482,5483,5486],{"class":195,"line":224},[193,5484,5485],{"class":1014},"    id",[193,5487,5488],{"class":1002},":undefined,\n",[193,5490,5491,5494],{"class":195,"line":230},[193,5492,5493],{"class":1014},"    color",[193,5495,5488],{"class":1002},[193,5497,5498,5501,5503,5505],{"class":195,"line":236},[193,5499,5500],{"class":1014},"    selfHeight",[193,5502,1018],{"class":1002},[193,5504,1511],{"class":1021},[193,5506,2579],{"class":1002},[193,5508,5509,5512,5514],{"class":195,"line":242},[193,5510,5511],{"class":1014},"    y",[193,5513,1018],{"class":1002},[193,5515,5516],{"class":1021},"0\n",[193,5518,5519],{"class":195,"line":248},[193,5520,5521],{"class":1002},"};\n",[193,5523,5524],{"class":195,"line":254},[193,5525,476],{"emptyLinePlaceholder":101},[193,5527,5528],{"class":195,"line":259},[193,5529,5530],{"class":1136},"\u002F\u002F 列数\n",[193,5532,5533,5535,5538,5540,5543],{"class":195,"line":265},[193,5534,5450],{"class":994},[193,5536,5537],{"class":998}," row ",[193,5539,1003],{"class":1002},[193,5541,5542],{"class":1021}," 3",[193,5544,1192],{"class":1002},[193,5546,5547],{"class":195,"line":271},[193,5548,476],{"emptyLinePlaceholder":101},[193,5550,5551],{"class":195,"line":600},[193,5552,5553],{"class":1136},"\u002F\u002F 挿入先コンテナ\n",[193,5555,5556,5558,5561,5563,5566,5568,5571,5573,5575,5577,5579,5581],{"class":195,"line":606},[193,5557,995],{"class":994},[193,5559,5560],{"class":998}," cardsContainer ",[193,5562,1003],{"class":1002},[193,5564,5565],{"class":998}," document",[193,5567,1186],{"class":1002},[193,5569,5570],{"class":1206},"getElementById",[193,5572,1925],{"class":998},[193,5574,2824],{"class":1002},[193,5576,4099],{"class":1035},[193,5578,2824],{"class":1002},[193,5580,1950],{"class":998},[193,5582,1192],{"class":1002},[193,5584,5585],{"class":195,"line":612},[193,5586,476],{"emptyLinePlaceholder":101},[193,5588,5589],{"class":195,"line":618},[193,5590,5591],{"class":1136},"\u002F\u002F 追加ボタン\n",[193,5593,5594,5596,5599,5601,5603,5605,5607,5609,5611,5613,5615,5617],{"class":195,"line":624},[193,5595,995],{"class":994},[193,5597,5598],{"class":998}," cardsAddBtn ",[193,5600,1003],{"class":1002},[193,5602,5565],{"class":998},[193,5604,1186],{"class":1002},[193,5606,5570],{"class":1206},[193,5608,1925],{"class":998},[193,5610,2824],{"class":1002},[193,5612,4320],{"class":1035},[193,5614,2824],{"class":1002},[193,5616,1950],{"class":998},[193,5618,1192],{"class":1002},[193,5620,5621],{"class":195,"line":630},[193,5622,476],{"emptyLinePlaceholder":101},[193,5624,5625],{"class":195,"line":636},[193,5626,5627],{"class":1136},"\u002F\u002F　カード高さの最大値と最小値\n",[193,5629,5630,5632,5635,5637,5640],{"class":195,"line":642},[193,5631,995],{"class":994},[193,5633,5634],{"class":998}," heightMax ",[193,5636,1003],{"class":1002},[193,5638,5639],{"class":1021}," 400",[193,5641,1192],{"class":1002},[193,5643,5644,5646,5649,5651,5654],{"class":195,"line":648},[193,5645,995],{"class":994},[193,5647,5648],{"class":998}," heightMin ",[193,5650,1003],{"class":1002},[193,5652,5653],{"class":1021}," 100",[193,5655,1192],{"class":1002},[193,5657,5658],{"class":195,"line":654},[193,5659,476],{"emptyLinePlaceholder":101},[193,5661,5662],{"class":195,"line":660},[193,5663,5664],{"class":1136},"\u002F\u002F 色のパターンとカード間の隙間（px）\n",[193,5666,5667,5669,5672,5674,5676,5678,5681,5683,5685,5687,5690,5692,5694,5696,5699,5701,5703,5705,5708,5710,5712,5714,5717,5719,5721,5723,5726,5728,5730],{"class":195,"line":666},[193,5668,995],{"class":994},[193,5670,5671],{"class":998}," colors ",[193,5673,1003],{"class":1002},[193,5675,1445],{"class":998},[193,5677,2824],{"class":1002},[193,5679,5680],{"class":1035},"red",[193,5682,2824],{"class":1002},[193,5684,28],{"class":1002},[193,5686,2824],{"class":1002},[193,5688,5689],{"class":1035},"yellow",[193,5691,2824],{"class":1002},[193,5693,28],{"class":1002},[193,5695,2824],{"class":1002},[193,5697,5698],{"class":1035},"green",[193,5700,2824],{"class":1002},[193,5702,28],{"class":1002},[193,5704,2824],{"class":1002},[193,5706,5707],{"class":1035},"orange",[193,5709,2824],{"class":1002},[193,5711,28],{"class":1002},[193,5713,2824],{"class":1002},[193,5715,5716],{"class":1035},"blue",[193,5718,2824],{"class":1002},[193,5720,28],{"class":1002},[193,5722,2824],{"class":1002},[193,5724,5725],{"class":1035},"purple",[193,5727,2824],{"class":1002},[193,5729,1405],{"class":998},[193,5731,1192],{"class":1002},[193,5733,5734,5736,5739,5741,5744],{"class":195,"line":672},[193,5735,995],{"class":994},[193,5737,5738],{"class":998}," cardGap ",[193,5740,1003],{"class":1002},[193,5742,5743],{"class":1021}," 10",[193,5745,1192],{"class":1002},[193,5747,5748],{"class":195,"line":678},[193,5749,476],{"emptyLinePlaceholder":101},[193,5751,5752],{"class":195,"line":684},[193,5753,5754],{"class":1136},"\u002F\u002F 追加ボタンにイベントリスナーを付与\n",[193,5756,5757,5760,5762,5765,5767,5769,5772,5774,5777,5779],{"class":195,"line":690},[193,5758,5759],{"class":998},"cardsAddBtn",[193,5761,1186],{"class":1002},[193,5763,5764],{"class":1206},"addEventListener",[193,5766,1925],{"class":998},[193,5768,2824],{"class":1002},[193,5770,5771],{"class":1035},"click",[193,5773,2824],{"class":1002},[193,5775,5776],{"class":1002},",()",[193,5778,2847],{"class":994},[193,5780,233],{"class":1002},[193,5782,5783,5786,5789,5791],{"class":195,"line":696},[193,5784,5785],{"class":1938},"    return",[193,5787,5788],{"class":1206}," onClickAdd",[193,5790,2804],{"class":1014},[193,5792,1192],{"class":1002},[193,5794,5795,5797],{"class":195,"line":702},[193,5796,1402],{"class":1002},[193,5798,881],{"class":998},[193,5800,5801],{"class":195,"line":708},[193,5802,476],{"emptyLinePlaceholder":101},[193,5804,5805],{"class":195,"line":714},[193,5806,5807],{"class":1136},"\u002F\u002F イベントリスナーの内容\n",[193,5809,5810,5812,5815,5817,5820,5822],{"class":195,"line":720},[193,5811,5450],{"class":994},[193,5813,5814],{"class":998}," onClickAdd ",[193,5816,1003],{"class":1002},[193,5818,5819],{"class":1002}," ()",[193,5821,2847],{"class":994},[193,5823,233],{"class":1002},[193,5825,5826,5829,5832,5834,5837,5839],{"class":195,"line":726},[193,5827,5828],{"class":994},"    let",[193,5830,5831],{"class":998}," card",[193,5833,3580],{"class":1002},[193,5835,5836],{"class":1206}," createCard",[193,5838,2804],{"class":1014},[193,5840,1192],{"class":1002},[193,5842,5843,5846,5848,5851,5853,5856,5858],{"class":195,"line":731},[193,5844,5845],{"class":1206},"    insertCard",[193,5847,1925],{"class":1014},[193,5849,5850],{"class":998},"card",[193,5852,1186],{"class":1002},[193,5854,5855],{"class":998},"dom",[193,5857,1950],{"class":1014},[193,5859,1192],{"class":1002},[193,5861,5862,5865,5867,5869,5871,5873,5875],{"class":195,"line":737},[193,5863,5864],{"class":1206},"    scanAdd",[193,5866,1925],{"class":1014},[193,5868,5850],{"class":998},[193,5870,1186],{"class":1002},[193,5872,1015],{"class":998},[193,5874,1950],{"class":1014},[193,5876,1192],{"class":1002},[193,5878,5879],{"class":195,"line":742},[193,5880,274],{"class":1002},[193,5882,5883],{"class":195,"line":747},[193,5884,476],{"emptyLinePlaceholder":101},[193,5886,5887],{"class":195,"line":752},[193,5888,5889],{"class":1136},"\u002F\u002F カードのDOMを新規作成\n",[193,5891,5892,5894,5897,5899,5901,5903],{"class":195,"line":757},[193,5893,5450],{"class":994},[193,5895,5896],{"class":998}," createCard ",[193,5898,1003],{"class":1002},[193,5900,5819],{"class":1002},[193,5902,2847],{"class":994},[193,5904,233],{"class":1002},[193,5906,5907,5909,5912,5914,5916,5919],{"class":195,"line":762},[193,5908,5828],{"class":994},[193,5910,5911],{"class":998}," info",[193,5913,3580],{"class":1002},[193,5915,1942],{"class":1002},[193,5917,5918],{"class":998},"elementInit",[193,5920,5521],{"class":1002},[193,5922,5923],{"class":195,"line":767},[193,5924,476],{"emptyLinePlaceholder":101},[193,5926,5927],{"class":195,"line":772},[193,5928,5929],{"class":1136},"    \u002F\u002F カードの要素をdivで作成\n",[193,5931,5932,5934,5937,5939,5941,5943,5946,5948,5950,5953,5955,5957],{"class":195,"line":777},[193,5933,5828],{"class":994},[193,5935,5936],{"class":998}," contain",[193,5938,3580],{"class":1002},[193,5940,5565],{"class":998},[193,5942,1186],{"class":1002},[193,5944,5945],{"class":1206},"createElement",[193,5947,1925],{"class":1014},[193,5949,1032],{"class":1002},[193,5951,5952],{"class":1035},"DIV",[193,5954,1032],{"class":1002},[193,5956,1950],{"class":1014},[193,5958,1192],{"class":1002},[193,5960,5961,5964,5966,5969,5971,5973,5976,5978,5980,5982,5984,5986,5988],{"class":195,"line":782},[193,5962,5963],{"class":998},"    contain",[193,5965,1186],{"class":1002},[193,5967,5968],{"class":1206},"setAttribute",[193,5970,1925],{"class":1014},[193,5972,2824],{"class":1002},[193,5974,5975],{"class":1035},"class",[193,5977,2824],{"class":1002},[193,5979,28],{"class":1002},[193,5981,2824],{"class":1002},[193,5983,4242],{"class":1035},[193,5985,2824],{"class":1002},[193,5987,1950],{"class":1014},[193,5989,1192],{"class":1002},[193,5991,5992],{"class":195,"line":787},[193,5993,476],{"emptyLinePlaceholder":101},[193,5995,5996],{"class":195,"line":792},[193,5997,5998],{"class":1136},"    \u002F\u002F IDをランダムに作成、記録\n",[193,6000,6001,6003,6006,6008,6011,6013,6016,6018,6020,6023,6025,6028,6030,6032,6035,6037,6039,6041],{"class":195,"line":797},[193,6002,5828],{"class":994},[193,6004,6005],{"class":998}," idname",[193,6007,3580],{"class":1002},[193,6009,6010],{"class":998}," Math",[193,6012,1186],{"class":1002},[193,6014,6015],{"class":1206},"random",[193,6017,2804],{"class":1014},[193,6019,1186],{"class":1002},[193,6021,6022],{"class":1206},"toString",[193,6024,1925],{"class":1014},[193,6026,6027],{"class":1021},"32",[193,6029,1950],{"class":1014},[193,6031,1186],{"class":1002},[193,6033,6034],{"class":1206},"substring",[193,6036,1925],{"class":1014},[193,6038,1066],{"class":1021},[193,6040,1950],{"class":1014},[193,6042,1192],{"class":1002},[193,6044,6045,6047,6049,6051,6053,6055,6057,6059,6061,6064,6066],{"class":195,"line":802},[193,6046,5963],{"class":998},[193,6048,1186],{"class":1002},[193,6050,5968],{"class":1206},[193,6052,1925],{"class":1014},[193,6054,2824],{"class":1002},[193,6056,1015],{"class":1035},[193,6058,2824],{"class":1002},[193,6060,28],{"class":1002},[193,6062,6063],{"class":998},"idname",[193,6065,1950],{"class":1014},[193,6067,1192],{"class":1002},[193,6069,6070,6073,6075,6077,6079,6081],{"class":195,"line":807},[193,6071,6072],{"class":998},"    info",[193,6074,1186],{"class":1002},[193,6076,1015],{"class":998},[193,6078,3580],{"class":1002},[193,6080,6005],{"class":998},[193,6082,1192],{"class":1002},[193,6084,6085],{"class":195,"line":812},[193,6086,476],{"emptyLinePlaceholder":101},[193,6088,6089],{"class":195,"line":817},[193,6090,6091],{"class":1136},"    \u002F\u002F カードに表示される画像（一色塗り潰し）を設定、記録\n",[193,6093,6094],{"class":195,"line":822},[193,6095,6096],{"class":1136},"    \u002F\u002F colorsの値と画像名が同じ。\n",[193,6098,6099,6101,6103,6105,6107,6109,6111,6113,6115,6118,6120,6122],{"class":195,"line":827},[193,6100,5828],{"class":994},[193,6102,5831],{"class":998},[193,6104,3580],{"class":1002},[193,6106,5565],{"class":998},[193,6108,1186],{"class":1002},[193,6110,5945],{"class":1206},[193,6112,1925],{"class":1014},[193,6114,1032],{"class":1002},[193,6116,6117],{"class":1035},"IMG",[193,6119,1032],{"class":1002},[193,6121,1950],{"class":1014},[193,6123,1192],{"class":1002},[193,6125,6126,6128,6131,6133,6136,6138,6141,6143,6146,6148,6150,6152,6154,6157,6159,6161,6163,6166,6169],{"class":195,"line":832},[193,6127,5828],{"class":994},[193,6129,6130],{"class":998}," color",[193,6132,3580],{"class":1002},[193,6134,6135],{"class":998}," colors",[193,6137,1355],{"class":1014},[193,6139,6140],{"class":998},"Math",[193,6142,1186],{"class":1002},[193,6144,6145],{"class":1206},"floor",[193,6147,1925],{"class":1014},[193,6149,6140],{"class":998},[193,6151,1186],{"class":1002},[193,6153,6015],{"class":1206},[193,6155,6156],{"class":1014},"() ",[193,6158,4266],{"class":1002},[193,6160,6135],{"class":998},[193,6162,1186],{"class":1002},[193,6164,6165],{"class":998},"length",[193,6167,6168],{"class":1014},")]",[193,6170,1192],{"class":1002},[193,6172,6173,6175,6177,6180,6182,6184],{"class":195,"line":837},[193,6174,6072],{"class":998},[193,6176,1186],{"class":1002},[193,6178,6179],{"class":998},"color",[193,6181,3580],{"class":1002},[193,6183,6130],{"class":998},[193,6185,1192],{"class":1002},[193,6187,6188],{"class":195,"line":842},[193,6189,476],{"emptyLinePlaceholder":101},[193,6191,6192],{"class":195,"line":847},[193,6193,6194],{"class":1136},"    \u002F\u002F IMG要素にカラーの画像とクラス名を付与\n",[193,6196,6197,6200,6202,6204,6206,6208,6211,6213,6215,6217,6220,6222,6225,6227,6229,6231,6234,6236,6238],{"class":195,"line":852},[193,6198,6199],{"class":998},"    card",[193,6201,1186],{"class":1002},[193,6203,5968],{"class":1206},[193,6205,1925],{"class":1014},[193,6207,2824],{"class":1002},[193,6209,6210],{"class":1035},"src",[193,6212,2824],{"class":1002},[193,6214,28],{"class":1002},[193,6216,2824],{"class":1002},[193,6218,6219],{"class":1035},".\u002F",[193,6221,2824],{"class":1002},[193,6223,6224],{"class":1002},"+",[193,6226,6179],{"class":998},[193,6228,6224],{"class":1002},[193,6230,2824],{"class":1002},[193,6232,6233],{"class":1035},".png",[193,6235,2824],{"class":1002},[193,6237,1950],{"class":1014},[193,6239,1192],{"class":1002},[193,6241,6242,6244,6246,6248,6250,6252,6254,6256,6258,6260,6262,6264,6266],{"class":195,"line":857},[193,6243,6199],{"class":998},[193,6245,1186],{"class":1002},[193,6247,5968],{"class":1206},[193,6249,1925],{"class":1014},[193,6251,2824],{"class":1002},[193,6253,5975],{"class":1035},[193,6255,2824],{"class":1002},[193,6257,28],{"class":1002},[193,6259,2824],{"class":1002},[193,6261,4153],{"class":1035},[193,6263,2824],{"class":1002},[193,6265,1950],{"class":1014},[193,6267,1192],{"class":1002},[193,6269,6270],{"class":195,"line":4},[193,6271,476],{"emptyLinePlaceholder":101},[193,6273,6274],{"class":195,"line":866},[193,6275,6276],{"class":1136},"    \u002F\u002F カードに対して不明な高さを与える\n",[193,6278,6279,6281,6283,6286,6288,6290,6292,6294,6296,6298,6300,6302,6304,6306,6308,6311,6313,6315,6318,6321,6324,6326,6328],{"class":195,"line":872},[193,6280,6072],{"class":998},[193,6282,1186],{"class":1002},[193,6284,6285],{"class":998},"selfHeight",[193,6287,3580],{"class":1002},[193,6289,6010],{"class":998},[193,6291,1186],{"class":1002},[193,6293,6145],{"class":1206},[193,6295,1925],{"class":1014},[193,6297,6140],{"class":998},[193,6299,1186],{"class":1002},[193,6301,6015],{"class":1206},[193,6303,2804],{"class":1014},[193,6305,4266],{"class":1002},[193,6307,1925],{"class":1014},[193,6309,6310],{"class":998},"heightMax",[193,6312,6224],{"class":1002},[193,6314,1022],{"class":1021},[193,6316,6317],{"class":1002},"-",[193,6319,6320],{"class":998},"heightMin",[193,6322,6323],{"class":1014},"))",[193,6325,6224],{"class":1002},[193,6327,6320],{"class":998},[193,6329,1192],{"class":1002},[193,6331,6332],{"class":195,"line":878},[193,6333,6334],{"class":1014},"    \n",[193,6336,6337],{"class":195,"line":3950},[193,6338,6339],{"class":1136},"    \u002F\u002F カードDIVにIMGを追加\n",[193,6341,6342,6344,6346,6349,6351,6353,6355],{"class":195,"line":3955},[193,6343,5963],{"class":998},[193,6345,1186],{"class":1002},[193,6347,6348],{"class":1206},"appendChild",[193,6350,1925],{"class":1014},[193,6352,5850],{"class":998},[193,6354,1950],{"class":1014},[193,6356,1192],{"class":1002},[193,6358,6359],{"class":195,"line":3960},[193,6360,476],{"emptyLinePlaceholder":101},[193,6362,6363],{"class":195,"line":3965},[193,6364,6365],{"class":1136},"    \u002F\u002F elementsに記録。DOMとIDを返す\n",[193,6367,6368,6371,6373,6376,6378,6381,6383],{"class":195,"line":3971},[193,6369,6370],{"class":998},"    elements",[193,6372,1186],{"class":1002},[193,6374,6375],{"class":1206},"push",[193,6377,1925],{"class":1014},[193,6379,6380],{"class":998},"info",[193,6382,1950],{"class":1014},[193,6384,1192],{"class":1002},[193,6386,6388,6390,6392,6394,6396,6399,6401,6403,6405,6407],{"class":195,"line":6387},72,[193,6389,5785],{"class":1938},[193,6391,1935],{"class":1002},[193,6393,5855],{"class":1014},[193,6395,1018],{"class":1002},[193,6397,6398],{"class":998},"contain",[193,6400,28],{"class":1002},[193,6402,1015],{"class":1014},[193,6404,1018],{"class":1002},[193,6406,6063],{"class":998},[193,6408,5521],{"class":1002},[193,6410,6412],{"class":195,"line":6411},73,[193,6413,274],{"class":1002},[193,6415,6417],{"class":195,"line":6416},74,[193,6418,476],{"emptyLinePlaceholder":101},[193,6420,6422],{"class":195,"line":6421},75,[193,6423,6424],{"class":1136},"\u002F\u002F カードコンテナーにカードを追加する\n",[193,6426,6428,6430,6433,6435,6438,6441,6443,6445],{"class":195,"line":6427},76,[193,6429,5450],{"class":994},[193,6431,6432],{"class":998}," insertCard ",[193,6434,1003],{"class":1002},[193,6436,6437],{"class":1002}," (",[193,6439,6440],{"class":1928},"cardDom",[193,6442,1950],{"class":1002},[193,6444,2847],{"class":994},[193,6446,233],{"class":1002},[193,6448,6450,6453,6455,6457,6459,6461,6463],{"class":195,"line":6449},77,[193,6451,6452],{"class":998},"    cardsContainer",[193,6454,1186],{"class":1002},[193,6456,6348],{"class":1206},[193,6458,1925],{"class":1014},[193,6460,6440],{"class":998},[193,6462,1950],{"class":1014},[193,6464,1192],{"class":1002},[193,6466,6468],{"class":195,"line":6467},78,[193,6469,274],{"class":1002},[193,6471,6473],{"class":195,"line":6472},79,[193,6474,476],{"emptyLinePlaceholder":101},[193,6476,6478],{"class":195,"line":6477},80,[193,6479,6480],{"class":1136},"\u002F\u002F これが大切\n",[193,6482,6484],{"class":195,"line":6483},81,[193,6485,6486],{"class":1136},"\u002F\u002F IDで紐づいたDOMに対して高さと位置を決定させる。\n",[193,6488,6490,6492,6495,6497,6499,6501,6503,6505],{"class":195,"line":6489},82,[193,6491,5450],{"class":994},[193,6493,6494],{"class":998}," scanAdd ",[193,6496,1003],{"class":1002},[193,6498,6437],{"class":1002},[193,6500,1015],{"class":1928},[193,6502,1950],{"class":1002},[193,6504,1932],{"class":994},[193,6506,233],{"class":1002},[193,6508,6510],{"class":195,"line":6509},83,[193,6511,6512],{"class":1136},"    \u002F\u002F elementsから対象カードのIDの番号、情報を取得\n",[193,6514,6516,6518,6521,6523,6526,6528,6531,6533,6536,6538,6540,6542,6545,6547,6549,6551,6553,6555,6557],{"class":195,"line":6515},84,[193,6517,5828],{"class":994},[193,6519,6520],{"class":998}," index",[193,6522,3580],{"class":1002},[193,6524,6525],{"class":998}," elements",[193,6527,1186],{"class":1002},[193,6529,6530],{"class":1206},"findIndex",[193,6532,1925],{"class":1014},[193,6534,6535],{"class":1928},"ele",[193,6537,2847],{"class":994},[193,6539,1358],{"class":1002},[193,6541,1939],{"class":1938},[193,6543,6544],{"class":998}," ele",[193,6546,1186],{"class":1002},[193,6548,1015],{"class":998},[193,6550,1465],{"class":1002},[193,6552,1015],{"class":998},[193,6554,1402],{"class":1002},[193,6556,1950],{"class":1014},[193,6558,1192],{"class":1002},[193,6560,6562,6564,6566,6568,6570,6572,6575],{"class":195,"line":6561},85,[193,6563,5828],{"class":994},[193,6565,6544],{"class":998},[193,6567,3580],{"class":1002},[193,6569,6525],{"class":998},[193,6571,1355],{"class":1014},[193,6573,6574],{"class":998},"index",[193,6576,1142],{"class":1014},[193,6578,6580],{"class":195,"line":6579},86,[193,6581,476],{"emptyLinePlaceholder":101},[193,6583,6585],{"class":195,"line":6584},87,[193,6586,6587],{"class":1136},"    \u002F\u002F DOMを取得\n",[193,6589,6591,6593,6596,6598,6600,6602,6604,6606,6608,6610,6612,6614],{"class":195,"line":6590},88,[193,6592,5828],{"class":994},[193,6594,6595],{"class":998}," dom",[193,6597,3580],{"class":1002},[193,6599,5565],{"class":998},[193,6601,1186],{"class":1002},[193,6603,5570],{"class":1206},[193,6605,1925],{"class":1014},[193,6607,6535],{"class":998},[193,6609,1186],{"class":1002},[193,6611,1015],{"class":998},[193,6613,1950],{"class":1014},[193,6615,1192],{"class":1002},[193,6617,6619],{"class":195,"line":6618},89,[193,6620,476],{"emptyLinePlaceholder":101},[193,6622,6624],{"class":195,"line":6623},90,[193,6625,6626],{"class":1136},"    \u002F\u002F index、つまりカードが何晩目かと列数でx,yの位置を決定する。\n",[193,6628,6630,6632,6635,6637,6639,6641],{"class":195,"line":6629},91,[193,6631,5828],{"class":994},[193,6633,6634],{"class":998}," height",[193,6636,3580],{"class":1002},[193,6638,6544],{"class":998},[193,6640,1186],{"class":1002},[193,6642,6643],{"class":998},"selfHeight\n",[193,6645,6647,6650,6652,6655,6657,6659,6661,6664,6667,6669,6672,6675,6677,6680,6682,6684,6687,6689,6691,6693,6695,6698,6700],{"class":195,"line":6646},92,[193,6648,6649],{"class":998},"    ele",[193,6651,1186],{"class":1002},[193,6653,6654],{"class":998},"y",[193,6656,3580],{"class":1002},[193,6658,6437],{"class":1014},[193,6660,6574],{"class":998},[193,6662,6663],{"class":1002}," \u003C",[193,6665,6666],{"class":998}," row",[193,6668,1950],{"class":1014},[193,6670,6671],{"class":1002},"?",[193,6673,6674],{"class":998},"height",[193,6676,1018],{"class":1002},[193,6678,6679],{"class":998},"elements",[193,6681,1355],{"class":1014},[193,6683,6574],{"class":998},[193,6685,6686],{"class":1002}," -",[193,6688,6666],{"class":998},[193,6690,1405],{"class":1014},[193,6692,1186],{"class":1002},[193,6694,6654],{"class":998},[193,6696,6697],{"class":1002}," +",[193,6699,6634],{"class":998},[193,6701,1192],{"class":1002},[193,6703,6705,6707,6710,6712,6714,6716,6719,6721,6724,6726,6728,6731,6734,6736,6738,6740,6742],{"class":195,"line":6704},93,[193,6706,5828],{"class":994},[193,6708,6709],{"class":998}," x",[193,6711,3580],{"class":1002},[193,6713,6437],{"class":1014},[193,6715,6574],{"class":998},[193,6717,6718],{"class":1002},"%",[193,6720,1925],{"class":1014},[193,6722,6723],{"class":998},"row",[193,6725,1950],{"class":1014},[193,6727,4266],{"class":1002},[193,6729,6730],{"class":1021},"100",[193,6732,6733],{"class":1014},") ",[193,6735,6224],{"class":1002},[193,6737,3243],{"class":1002},[193,6739,6718],{"class":1035},[193,6741,2824],{"class":1002},[193,6743,1192],{"class":1002},[193,6745,6747,6749,6752,6754,6756,6758,6760,6762,6764,6766,6768,6770,6772,6774,6776,6778,6780,6782,6784,6786],{"class":195,"line":6746},94,[193,6748,5828],{"class":994},[193,6750,6751],{"class":998}," y",[193,6753,3580],{"class":1002},[193,6755,6437],{"class":1014},[193,6757,6574],{"class":998},[193,6759,6663],{"class":1002},[193,6761,6666],{"class":998},[193,6763,1950],{"class":1014},[193,6765,6671],{"class":1002},[193,6767,1511],{"class":1021},[193,6769,1018],{"class":1002},[193,6771,6679],{"class":998},[193,6773,1355],{"class":1014},[193,6775,6574],{"class":998},[193,6777,6686],{"class":1002},[193,6779,6666],{"class":998},[193,6781,1405],{"class":1014},[193,6783,1186],{"class":1002},[193,6785,6654],{"class":998},[193,6787,1192],{"class":1002},[193,6789,6791],{"class":195,"line":6790},95,[193,6792,6334],{"class":1014},[193,6794,6796],{"class":195,"line":6795},96,[193,6797,6798],{"class":1136},"    \u002F\u002F 位置をずらすスタイルを適用\n",[193,6800,6802,6805,6807,6809,6811,6813,6815,6817,6819,6822,6825,6828,6830,6832,6835,6837,6840,6842,6844,6846,6848,6850,6853,6855],{"class":195,"line":6801},97,[193,6803,6804],{"class":998},"    dom",[193,6806,1186],{"class":1002},[193,6808,5968],{"class":1206},[193,6810,1925],{"class":1014},[193,6812,2824],{"class":1002},[193,6814,419],{"class":1035},[193,6816,2824],{"class":1002},[193,6818,28],{"class":1002},[193,6820,6821],{"class":1002},"`",[193,6823,6824],{"class":1035},"height:",[193,6826,6827],{"class":1002},"${",[193,6829,6674],{"class":998},[193,6831,1402],{"class":1002},[193,6833,6834],{"class":1035},"px; transform:translate(",[193,6836,6827],{"class":1002},[193,6838,6839],{"class":998},"x",[193,6841,1402],{"class":1002},[193,6843,28],{"class":1035},[193,6845,6827],{"class":1002},[193,6847,6654],{"class":998},[193,6849,1402],{"class":1002},[193,6851,6852],{"class":1035},"px);",[193,6854,6821],{"class":1002},[193,6856,881],{"class":1014},[193,6858,6860],{"class":195,"line":6859},98,[193,6861,476],{"emptyLinePlaceholder":101},[193,6863,6865],{"class":195,"line":6864},99,[193,6866,6867],{"class":1136},"    \u002F\u002F アニメーション用のスタイルを追加\n",[193,6869,6871,6874,6876,6878,6880],{"class":195,"line":6870},100,[193,6872,6873],{"class":1206},"    setTimeout",[193,6875,1925],{"class":1014},[193,6877,2804],{"class":1002},[193,6879,2847],{"class":994},[193,6881,233],{"class":1002},[193,6883,6885,6888,6890,6893,6895,6898,6900,6902,6904,6906],{"class":195,"line":6884},101,[193,6886,6887],{"class":998},"        dom",[193,6889,1186],{"class":1002},[193,6891,6892],{"class":998},"classList",[193,6894,1186],{"class":1002},[193,6896,6897],{"class":1206},"add",[193,6899,1925],{"class":1014},[193,6901,2824],{"class":1002},[193,6903,4705],{"class":1035},[193,6905,2824],{"class":1002},[193,6907,881],{"class":1014},[193,6909,6911,6914,6917,6919],{"class":195,"line":6910},102,[193,6912,6913],{"class":1002},"    },",[193,6915,6916],{"class":1021},"500",[193,6918,1950],{"class":1014},[193,6920,1192],{"class":1002},[193,6922,6924],{"class":195,"line":6923},103,[193,6925,274],{"class":1002},[13,6927,6928],{},"大まかな流れとしては以下の通りです。",[3097,6930,6931,6934,6937,6940,6943],{},[2976,6932,6933],{},"列数、カード座標情報などの初期値と格納する配列の定義。",[2976,6935,6936],{},"ボタンに対するイベントリスナーの定義、ボタンを押したら以下を発火。",[2976,6938,6939],{},"新しいカードを作成する",[2976,6941,6942],{},"カードをコンテナに追加",[2976,6944,6945],{},"追加数、列数に応じて追加したカードの位置を決定",[13,6947,6948],{},"それでは細かく解説していきます。",[3533,6950,6951],{"id":6951},"定数などの準備",[49,6953,6955],{"className":985,"code":6954,"language":987,"meta":57,"style":57},"\u002F\u002F カード情報を格納\nlet elements = [];\n\n\u002F\u002F カードの初期値\nlet elementInit = {\n    id:undefined,\n    color:undefined,\n    selfHeight:0,\n    y:0,\n    x:0\n};\n\n\u002F\u002F 列数\nlet row = 3;\n\n\u002F\u002F 挿入先コンテナ\nconst cardsContainer = document.getElementById('card-container');\n\n\u002F\u002F 追加ボタン\nconst cardsAddBtn = document.getElementById('card-add');\n\n\u002F\u002F　カード高さの最大値と最小値\nconst heightMax = 400;\nconst heightMin = 100;\n\n\u002F\u002F 色のパターンとカード間の隙間（px）\nconst colors = ['red','yellow','green','orange','blue','purple'];\nconst cardGap = 10;\n",[25,6956,6957,6961,6973,6977,6981,6991,6997,7003,7013,7023,7032,7036,7040,7044,7056,7060,7064,7090,7094,7098,7124,7128,7132,7144,7156,7160,7164,7224],{"__ignoreMap":57},[193,6958,6959],{"class":195,"line":196},[193,6960,5445],{"class":1136},[193,6962,6963,6965,6967,6969,6971],{"class":195,"line":93},[193,6964,5450],{"class":994},[193,6966,5453],{"class":998},[193,6968,1003],{"class":1002},[193,6970,5458],{"class":998},[193,6972,1192],{"class":1002},[193,6974,6975],{"class":195,"line":90},[193,6976,476],{"emptyLinePlaceholder":101},[193,6978,6979],{"class":195,"line":212},[193,6980,5469],{"class":1136},[193,6982,6983,6985,6987,6989],{"class":195,"line":218},[193,6984,5450],{"class":994},[193,6986,5476],{"class":998},[193,6988,1003],{"class":1002},[193,6990,2534],{"class":1002},[193,6992,6993,6995],{"class":195,"line":224},[193,6994,5485],{"class":1014},[193,6996,5488],{"class":1002},[193,6998,6999,7001],{"class":195,"line":230},[193,7000,5493],{"class":1014},[193,7002,5488],{"class":1002},[193,7004,7005,7007,7009,7011],{"class":195,"line":236},[193,7006,5500],{"class":1014},[193,7008,1018],{"class":1002},[193,7010,1511],{"class":1021},[193,7012,2579],{"class":1002},[193,7014,7015,7017,7019,7021],{"class":195,"line":242},[193,7016,5511],{"class":1014},[193,7018,1018],{"class":1002},[193,7020,1511],{"class":1021},[193,7022,2579],{"class":1002},[193,7024,7025,7028,7030],{"class":195,"line":248},[193,7026,7027],{"class":1014},"    x",[193,7029,1018],{"class":1002},[193,7031,5516],{"class":1021},[193,7033,7034],{"class":195,"line":254},[193,7035,5521],{"class":1002},[193,7037,7038],{"class":195,"line":259},[193,7039,476],{"emptyLinePlaceholder":101},[193,7041,7042],{"class":195,"line":265},[193,7043,5530],{"class":1136},[193,7045,7046,7048,7050,7052,7054],{"class":195,"line":271},[193,7047,5450],{"class":994},[193,7049,5537],{"class":998},[193,7051,1003],{"class":1002},[193,7053,5542],{"class":1021},[193,7055,1192],{"class":1002},[193,7057,7058],{"class":195,"line":600},[193,7059,476],{"emptyLinePlaceholder":101},[193,7061,7062],{"class":195,"line":606},[193,7063,5553],{"class":1136},[193,7065,7066,7068,7070,7072,7074,7076,7078,7080,7082,7084,7086,7088],{"class":195,"line":612},[193,7067,995],{"class":994},[193,7069,5560],{"class":998},[193,7071,1003],{"class":1002},[193,7073,5565],{"class":998},[193,7075,1186],{"class":1002},[193,7077,5570],{"class":1206},[193,7079,1925],{"class":998},[193,7081,2824],{"class":1002},[193,7083,4099],{"class":1035},[193,7085,2824],{"class":1002},[193,7087,1950],{"class":998},[193,7089,1192],{"class":1002},[193,7091,7092],{"class":195,"line":618},[193,7093,476],{"emptyLinePlaceholder":101},[193,7095,7096],{"class":195,"line":624},[193,7097,5591],{"class":1136},[193,7099,7100,7102,7104,7106,7108,7110,7112,7114,7116,7118,7120,7122],{"class":195,"line":630},[193,7101,995],{"class":994},[193,7103,5598],{"class":998},[193,7105,1003],{"class":1002},[193,7107,5565],{"class":998},[193,7109,1186],{"class":1002},[193,7111,5570],{"class":1206},[193,7113,1925],{"class":998},[193,7115,2824],{"class":1002},[193,7117,4320],{"class":1035},[193,7119,2824],{"class":1002},[193,7121,1950],{"class":998},[193,7123,1192],{"class":1002},[193,7125,7126],{"class":195,"line":636},[193,7127,476],{"emptyLinePlaceholder":101},[193,7129,7130],{"class":195,"line":642},[193,7131,5627],{"class":1136},[193,7133,7134,7136,7138,7140,7142],{"class":195,"line":648},[193,7135,995],{"class":994},[193,7137,5634],{"class":998},[193,7139,1003],{"class":1002},[193,7141,5639],{"class":1021},[193,7143,1192],{"class":1002},[193,7145,7146,7148,7150,7152,7154],{"class":195,"line":654},[193,7147,995],{"class":994},[193,7149,5648],{"class":998},[193,7151,1003],{"class":1002},[193,7153,5653],{"class":1021},[193,7155,1192],{"class":1002},[193,7157,7158],{"class":195,"line":660},[193,7159,476],{"emptyLinePlaceholder":101},[193,7161,7162],{"class":195,"line":666},[193,7163,5664],{"class":1136},[193,7165,7166,7168,7170,7172,7174,7176,7178,7180,7182,7184,7186,7188,7190,7192,7194,7196,7198,7200,7202,7204,7206,7208,7210,7212,7214,7216,7218,7220,7222],{"class":195,"line":672},[193,7167,995],{"class":994},[193,7169,5671],{"class":998},[193,7171,1003],{"class":1002},[193,7173,1445],{"class":998},[193,7175,2824],{"class":1002},[193,7177,5680],{"class":1035},[193,7179,2824],{"class":1002},[193,7181,28],{"class":1002},[193,7183,2824],{"class":1002},[193,7185,5689],{"class":1035},[193,7187,2824],{"class":1002},[193,7189,28],{"class":1002},[193,7191,2824],{"class":1002},[193,7193,5698],{"class":1035},[193,7195,2824],{"class":1002},[193,7197,28],{"class":1002},[193,7199,2824],{"class":1002},[193,7201,5707],{"class":1035},[193,7203,2824],{"class":1002},[193,7205,28],{"class":1002},[193,7207,2824],{"class":1002},[193,7209,5716],{"class":1035},[193,7211,2824],{"class":1002},[193,7213,28],{"class":1002},[193,7215,2824],{"class":1002},[193,7217,5725],{"class":1035},[193,7219,2824],{"class":1002},[193,7221,1405],{"class":998},[193,7223,1192],{"class":1002},[193,7225,7226,7228,7230,7232,7234],{"class":195,"line":678},[193,7227,995],{"class":994},[193,7229,5738],{"class":998},[193,7231,1003],{"class":1002},[193,7233,5743],{"class":1021},[193,7235,1192],{"class":1002},[13,7237,7238,7239,7241],{},"ここでは追加する際に必要な定数やDOMを定義しておきます。\n",[25,7240,6679],{},"には作成したカードコンテンツを記録しておきます。列＋１番目以降（今回は４番目以降）の高さを調整するときなどに使用します。",[3533,7243,7244],{"id":7244},"カードの作成関数を設定",[49,7246,7248],{"className":985,"code":7247,"language":987,"meta":57,"style":57},"\u002F\u002F カードのDOMを新規作成\nlet createCard = ()=>{\n    let info = {...elementInit};\n\n    \u002F\u002F カードの要素をdivで作成\n    let contain = document.createElement(\"DIV\");\n    contain.setAttribute('class','c-card-container');\n\n    \u002F\u002F IDをランダムに作成、記録\n    let idname = Math.random().toString(32).substring(2);\n    contain.setAttribute('id',idname);\n    info.id = idname;\n\n    \u002F\u002F カードに表示される画像（一色塗り潰し）を設定、記録\n    \u002F\u002F colorsの値と画像名が同じ。\n    let card = document.createElement(\"IMG\");\n    let color = colors[Math.floor(Math.random() * colors.length)];\n    info.color = color;\n\n    \u002F\u002F IMG要素にカラーの画像とクラス名を付与\n    card.setAttribute('src','.\u002F'+color+'.png');\n    card.setAttribute('class','c-card-img');\n\n    \u002F\u002F カードに対して不明な高さを与える\n    info.selfHeight = Math.floor(Math.random()*(heightMax+1-heightMin))+heightMin;\n    \n    \u002F\u002F カードDIVにIMGを追加\n    contain.appendChild(card);\n\n    \u002F\u002F elementsに記録。DOMとIDを返す\n    elements.push(info);\n    return {dom:contain,id:idname};\n}\n",[25,7249,7250,7254,7268,7282,7286,7290,7316,7344,7348,7352,7390,7414,7428,7432,7436,7440,7466,7506,7520,7524,7528,7568,7596,7600,7604,7652,7656,7660,7676,7680,7684,7700,7722],{"__ignoreMap":57},[193,7251,7252],{"class":195,"line":196},[193,7253,5889],{"class":1136},[193,7255,7256,7258,7260,7262,7264,7266],{"class":195,"line":93},[193,7257,5450],{"class":994},[193,7259,5896],{"class":998},[193,7261,1003],{"class":1002},[193,7263,5819],{"class":1002},[193,7265,2847],{"class":994},[193,7267,233],{"class":1002},[193,7269,7270,7272,7274,7276,7278,7280],{"class":195,"line":90},[193,7271,5828],{"class":994},[193,7273,5911],{"class":998},[193,7275,3580],{"class":1002},[193,7277,1942],{"class":1002},[193,7279,5918],{"class":998},[193,7281,5521],{"class":1002},[193,7283,7284],{"class":195,"line":212},[193,7285,476],{"emptyLinePlaceholder":101},[193,7287,7288],{"class":195,"line":218},[193,7289,5929],{"class":1136},[193,7291,7292,7294,7296,7298,7300,7302,7304,7306,7308,7310,7312,7314],{"class":195,"line":224},[193,7293,5828],{"class":994},[193,7295,5936],{"class":998},[193,7297,3580],{"class":1002},[193,7299,5565],{"class":998},[193,7301,1186],{"class":1002},[193,7303,5945],{"class":1206},[193,7305,1925],{"class":1014},[193,7307,1032],{"class":1002},[193,7309,5952],{"class":1035},[193,7311,1032],{"class":1002},[193,7313,1950],{"class":1014},[193,7315,1192],{"class":1002},[193,7317,7318,7320,7322,7324,7326,7328,7330,7332,7334,7336,7338,7340,7342],{"class":195,"line":230},[193,7319,5963],{"class":998},[193,7321,1186],{"class":1002},[193,7323,5968],{"class":1206},[193,7325,1925],{"class":1014},[193,7327,2824],{"class":1002},[193,7329,5975],{"class":1035},[193,7331,2824],{"class":1002},[193,7333,28],{"class":1002},[193,7335,2824],{"class":1002},[193,7337,4242],{"class":1035},[193,7339,2824],{"class":1002},[193,7341,1950],{"class":1014},[193,7343,1192],{"class":1002},[193,7345,7346],{"class":195,"line":236},[193,7347,476],{"emptyLinePlaceholder":101},[193,7349,7350],{"class":195,"line":242},[193,7351,5998],{"class":1136},[193,7353,7354,7356,7358,7360,7362,7364,7366,7368,7370,7372,7374,7376,7378,7380,7382,7384,7386,7388],{"class":195,"line":248},[193,7355,5828],{"class":994},[193,7357,6005],{"class":998},[193,7359,3580],{"class":1002},[193,7361,6010],{"class":998},[193,7363,1186],{"class":1002},[193,7365,6015],{"class":1206},[193,7367,2804],{"class":1014},[193,7369,1186],{"class":1002},[193,7371,6022],{"class":1206},[193,7373,1925],{"class":1014},[193,7375,6027],{"class":1021},[193,7377,1950],{"class":1014},[193,7379,1186],{"class":1002},[193,7381,6034],{"class":1206},[193,7383,1925],{"class":1014},[193,7385,1066],{"class":1021},[193,7387,1950],{"class":1014},[193,7389,1192],{"class":1002},[193,7391,7392,7394,7396,7398,7400,7402,7404,7406,7408,7410,7412],{"class":195,"line":254},[193,7393,5963],{"class":998},[193,7395,1186],{"class":1002},[193,7397,5968],{"class":1206},[193,7399,1925],{"class":1014},[193,7401,2824],{"class":1002},[193,7403,1015],{"class":1035},[193,7405,2824],{"class":1002},[193,7407,28],{"class":1002},[193,7409,6063],{"class":998},[193,7411,1950],{"class":1014},[193,7413,1192],{"class":1002},[193,7415,7416,7418,7420,7422,7424,7426],{"class":195,"line":259},[193,7417,6072],{"class":998},[193,7419,1186],{"class":1002},[193,7421,1015],{"class":998},[193,7423,3580],{"class":1002},[193,7425,6005],{"class":998},[193,7427,1192],{"class":1002},[193,7429,7430],{"class":195,"line":265},[193,7431,476],{"emptyLinePlaceholder":101},[193,7433,7434],{"class":195,"line":271},[193,7435,6091],{"class":1136},[193,7437,7438],{"class":195,"line":600},[193,7439,6096],{"class":1136},[193,7441,7442,7444,7446,7448,7450,7452,7454,7456,7458,7460,7462,7464],{"class":195,"line":606},[193,7443,5828],{"class":994},[193,7445,5831],{"class":998},[193,7447,3580],{"class":1002},[193,7449,5565],{"class":998},[193,7451,1186],{"class":1002},[193,7453,5945],{"class":1206},[193,7455,1925],{"class":1014},[193,7457,1032],{"class":1002},[193,7459,6117],{"class":1035},[193,7461,1032],{"class":1002},[193,7463,1950],{"class":1014},[193,7465,1192],{"class":1002},[193,7467,7468,7470,7472,7474,7476,7478,7480,7482,7484,7486,7488,7490,7492,7494,7496,7498,7500,7502,7504],{"class":195,"line":612},[193,7469,5828],{"class":994},[193,7471,6130],{"class":998},[193,7473,3580],{"class":1002},[193,7475,6135],{"class":998},[193,7477,1355],{"class":1014},[193,7479,6140],{"class":998},[193,7481,1186],{"class":1002},[193,7483,6145],{"class":1206},[193,7485,1925],{"class":1014},[193,7487,6140],{"class":998},[193,7489,1186],{"class":1002},[193,7491,6015],{"class":1206},[193,7493,6156],{"class":1014},[193,7495,4266],{"class":1002},[193,7497,6135],{"class":998},[193,7499,1186],{"class":1002},[193,7501,6165],{"class":998},[193,7503,6168],{"class":1014},[193,7505,1192],{"class":1002},[193,7507,7508,7510,7512,7514,7516,7518],{"class":195,"line":618},[193,7509,6072],{"class":998},[193,7511,1186],{"class":1002},[193,7513,6179],{"class":998},[193,7515,3580],{"class":1002},[193,7517,6130],{"class":998},[193,7519,1192],{"class":1002},[193,7521,7522],{"class":195,"line":624},[193,7523,476],{"emptyLinePlaceholder":101},[193,7525,7526],{"class":195,"line":630},[193,7527,6194],{"class":1136},[193,7529,7530,7532,7534,7536,7538,7540,7542,7544,7546,7548,7550,7552,7554,7556,7558,7560,7562,7564,7566],{"class":195,"line":636},[193,7531,6199],{"class":998},[193,7533,1186],{"class":1002},[193,7535,5968],{"class":1206},[193,7537,1925],{"class":1014},[193,7539,2824],{"class":1002},[193,7541,6210],{"class":1035},[193,7543,2824],{"class":1002},[193,7545,28],{"class":1002},[193,7547,2824],{"class":1002},[193,7549,6219],{"class":1035},[193,7551,2824],{"class":1002},[193,7553,6224],{"class":1002},[193,7555,6179],{"class":998},[193,7557,6224],{"class":1002},[193,7559,2824],{"class":1002},[193,7561,6233],{"class":1035},[193,7563,2824],{"class":1002},[193,7565,1950],{"class":1014},[193,7567,1192],{"class":1002},[193,7569,7570,7572,7574,7576,7578,7580,7582,7584,7586,7588,7590,7592,7594],{"class":195,"line":642},[193,7571,6199],{"class":998},[193,7573,1186],{"class":1002},[193,7575,5968],{"class":1206},[193,7577,1925],{"class":1014},[193,7579,2824],{"class":1002},[193,7581,5975],{"class":1035},[193,7583,2824],{"class":1002},[193,7585,28],{"class":1002},[193,7587,2824],{"class":1002},[193,7589,4153],{"class":1035},[193,7591,2824],{"class":1002},[193,7593,1950],{"class":1014},[193,7595,1192],{"class":1002},[193,7597,7598],{"class":195,"line":648},[193,7599,476],{"emptyLinePlaceholder":101},[193,7601,7602],{"class":195,"line":654},[193,7603,6276],{"class":1136},[193,7605,7606,7608,7610,7612,7614,7616,7618,7620,7622,7624,7626,7628,7630,7632,7634,7636,7638,7640,7642,7644,7646,7648,7650],{"class":195,"line":660},[193,7607,6072],{"class":998},[193,7609,1186],{"class":1002},[193,7611,6285],{"class":998},[193,7613,3580],{"class":1002},[193,7615,6010],{"class":998},[193,7617,1186],{"class":1002},[193,7619,6145],{"class":1206},[193,7621,1925],{"class":1014},[193,7623,6140],{"class":998},[193,7625,1186],{"class":1002},[193,7627,6015],{"class":1206},[193,7629,2804],{"class":1014},[193,7631,4266],{"class":1002},[193,7633,1925],{"class":1014},[193,7635,6310],{"class":998},[193,7637,6224],{"class":1002},[193,7639,1022],{"class":1021},[193,7641,6317],{"class":1002},[193,7643,6320],{"class":998},[193,7645,6323],{"class":1014},[193,7647,6224],{"class":1002},[193,7649,6320],{"class":998},[193,7651,1192],{"class":1002},[193,7653,7654],{"class":195,"line":666},[193,7655,6334],{"class":1014},[193,7657,7658],{"class":195,"line":672},[193,7659,6339],{"class":1136},[193,7661,7662,7664,7666,7668,7670,7672,7674],{"class":195,"line":678},[193,7663,5963],{"class":998},[193,7665,1186],{"class":1002},[193,7667,6348],{"class":1206},[193,7669,1925],{"class":1014},[193,7671,5850],{"class":998},[193,7673,1950],{"class":1014},[193,7675,1192],{"class":1002},[193,7677,7678],{"class":195,"line":684},[193,7679,476],{"emptyLinePlaceholder":101},[193,7681,7682],{"class":195,"line":690},[193,7683,6365],{"class":1136},[193,7685,7686,7688,7690,7692,7694,7696,7698],{"class":195,"line":696},[193,7687,6370],{"class":998},[193,7689,1186],{"class":1002},[193,7691,6375],{"class":1206},[193,7693,1925],{"class":1014},[193,7695,6380],{"class":998},[193,7697,1950],{"class":1014},[193,7699,1192],{"class":1002},[193,7701,7702,7704,7706,7708,7710,7712,7714,7716,7718,7720],{"class":195,"line":702},[193,7703,5785],{"class":1938},[193,7705,1935],{"class":1002},[193,7707,5855],{"class":1014},[193,7709,1018],{"class":1002},[193,7711,6398],{"class":998},[193,7713,28],{"class":1002},[193,7715,1015],{"class":1014},[193,7717,1018],{"class":1002},[193,7719,6063],{"class":998},[193,7721,5521],{"class":1002},[193,7723,7724],{"class":195,"line":708},[193,7725,274],{"class":1002},[13,7727,7728,7729,7732,7733,7735,7736,7738],{},"カードの作成関数",[25,7730,7731],{},"createCard()","を作ります。ここはカードの要素を作成して、ランダムなIDを付与します。変数",[25,7734,6380],{},"にはカードの高さ、IDを記録して",[25,7737,6679],{},"に入れておきます。",[3533,7740,7741],{"id":7741},"要素の挿入関数を作成",[49,7743,7745],{"className":985,"code":7744,"language":987,"meta":57,"style":57},"\u002F\u002F カードコンテナーにカードを追加する\nlet insertCard = (cardDom)=>{\n    cardsContainer.appendChild(cardDom);\n}\n",[25,7746,7747,7751,7769,7785],{"__ignoreMap":57},[193,7748,7749],{"class":195,"line":196},[193,7750,6424],{"class":1136},[193,7752,7753,7755,7757,7759,7761,7763,7765,7767],{"class":195,"line":93},[193,7754,5450],{"class":994},[193,7756,6432],{"class":998},[193,7758,1003],{"class":1002},[193,7760,6437],{"class":1002},[193,7762,6440],{"class":1928},[193,7764,1950],{"class":1002},[193,7766,2847],{"class":994},[193,7768,233],{"class":1002},[193,7770,7771,7773,7775,7777,7779,7781,7783],{"class":195,"line":90},[193,7772,6452],{"class":998},[193,7774,1186],{"class":1002},[193,7776,6348],{"class":1206},[193,7778,1925],{"class":1014},[193,7780,6440],{"class":998},[193,7782,1950],{"class":1014},[193,7784,1192],{"class":1002},[193,7786,7787],{"class":195,"line":212},[193,7788,274],{"class":1002},[13,7790,7791],{},"ここは作成したカードのDOMをカードコンテナに挿入します。",[3533,7793,7794],{"id":7794},"挿入されたカードの高さと位置を決定",[49,7796,7798],{"className":985,"code":7797,"language":987,"meta":57,"style":57},"\u002F\u002F これが大切\n\u002F\u002F IDで紐づいたDOMに対して高さと位置を決定させる。\nlet scanAdd = (id) =>{\n    \u002F\u002F elementsから対象カードのIDの番号、情報を取得\n    let index = elements.findIndex(ele=>{return ele.id===id});\n    let ele = elements[index]\n\n    \u002F\u002F DOMを取得\n    let dom = document.getElementById(ele.id);\n\n    \u002F\u002F index、つまりカードが何晩目かと列数でx,yの位置を決定する。\n    let height = ele.selfHeight\n    ele.y = (index \u003C row)?height:elements[index - row].y + height;\n    let x = (index%(row)*100) + '%';\n    let y = (index \u003C row)?0:elements[index - row].y;\n    \n    \u002F\u002F 位置をずらすスタイルを適用\n    dom.setAttribute('style',`height:${height}px; transform:translate(${x},${y}px);`)\n\n    \u002F\u002F アニメーション用のスタイルを追加\n    setTimeout(()=>{\n        dom.classList.add('u-animate')\n    },500);\n}\n",[25,7799,7800,7804,7808,7826,7830,7870,7886,7890,7894,7920,7924,7928,7942,7990,8026,8068,8072,8076,8126,8130,8134,8146,8168,8178],{"__ignoreMap":57},[193,7801,7802],{"class":195,"line":196},[193,7803,6480],{"class":1136},[193,7805,7806],{"class":195,"line":93},[193,7807,6486],{"class":1136},[193,7809,7810,7812,7814,7816,7818,7820,7822,7824],{"class":195,"line":90},[193,7811,5450],{"class":994},[193,7813,6494],{"class":998},[193,7815,1003],{"class":1002},[193,7817,6437],{"class":1002},[193,7819,1015],{"class":1928},[193,7821,1950],{"class":1002},[193,7823,1932],{"class":994},[193,7825,233],{"class":1002},[193,7827,7828],{"class":195,"line":212},[193,7829,6512],{"class":1136},[193,7831,7832,7834,7836,7838,7840,7842,7844,7846,7848,7850,7852,7854,7856,7858,7860,7862,7864,7866,7868],{"class":195,"line":218},[193,7833,5828],{"class":994},[193,7835,6520],{"class":998},[193,7837,3580],{"class":1002},[193,7839,6525],{"class":998},[193,7841,1186],{"class":1002},[193,7843,6530],{"class":1206},[193,7845,1925],{"class":1014},[193,7847,6535],{"class":1928},[193,7849,2847],{"class":994},[193,7851,1358],{"class":1002},[193,7853,1939],{"class":1938},[193,7855,6544],{"class":998},[193,7857,1186],{"class":1002},[193,7859,1015],{"class":998},[193,7861,1465],{"class":1002},[193,7863,1015],{"class":998},[193,7865,1402],{"class":1002},[193,7867,1950],{"class":1014},[193,7869,1192],{"class":1002},[193,7871,7872,7874,7876,7878,7880,7882,7884],{"class":195,"line":224},[193,7873,5828],{"class":994},[193,7875,6544],{"class":998},[193,7877,3580],{"class":1002},[193,7879,6525],{"class":998},[193,7881,1355],{"class":1014},[193,7883,6574],{"class":998},[193,7885,1142],{"class":1014},[193,7887,7888],{"class":195,"line":230},[193,7889,476],{"emptyLinePlaceholder":101},[193,7891,7892],{"class":195,"line":236},[193,7893,6587],{"class":1136},[193,7895,7896,7898,7900,7902,7904,7906,7908,7910,7912,7914,7916,7918],{"class":195,"line":242},[193,7897,5828],{"class":994},[193,7899,6595],{"class":998},[193,7901,3580],{"class":1002},[193,7903,5565],{"class":998},[193,7905,1186],{"class":1002},[193,7907,5570],{"class":1206},[193,7909,1925],{"class":1014},[193,7911,6535],{"class":998},[193,7913,1186],{"class":1002},[193,7915,1015],{"class":998},[193,7917,1950],{"class":1014},[193,7919,1192],{"class":1002},[193,7921,7922],{"class":195,"line":248},[193,7923,476],{"emptyLinePlaceholder":101},[193,7925,7926],{"class":195,"line":254},[193,7927,6626],{"class":1136},[193,7929,7930,7932,7934,7936,7938,7940],{"class":195,"line":259},[193,7931,5828],{"class":994},[193,7933,6634],{"class":998},[193,7935,3580],{"class":1002},[193,7937,6544],{"class":998},[193,7939,1186],{"class":1002},[193,7941,6643],{"class":998},[193,7943,7944,7946,7948,7950,7952,7954,7956,7958,7960,7962,7964,7966,7968,7970,7972,7974,7976,7978,7980,7982,7984,7986,7988],{"class":195,"line":265},[193,7945,6649],{"class":998},[193,7947,1186],{"class":1002},[193,7949,6654],{"class":998},[193,7951,3580],{"class":1002},[193,7953,6437],{"class":1014},[193,7955,6574],{"class":998},[193,7957,6663],{"class":1002},[193,7959,6666],{"class":998},[193,7961,1950],{"class":1014},[193,7963,6671],{"class":1002},[193,7965,6674],{"class":998},[193,7967,1018],{"class":1002},[193,7969,6679],{"class":998},[193,7971,1355],{"class":1014},[193,7973,6574],{"class":998},[193,7975,6686],{"class":1002},[193,7977,6666],{"class":998},[193,7979,1405],{"class":1014},[193,7981,1186],{"class":1002},[193,7983,6654],{"class":998},[193,7985,6697],{"class":1002},[193,7987,6634],{"class":998},[193,7989,1192],{"class":1002},[193,7991,7992,7994,7996,7998,8000,8002,8004,8006,8008,8010,8012,8014,8016,8018,8020,8022,8024],{"class":195,"line":271},[193,7993,5828],{"class":994},[193,7995,6709],{"class":998},[193,7997,3580],{"class":1002},[193,7999,6437],{"class":1014},[193,8001,6574],{"class":998},[193,8003,6718],{"class":1002},[193,8005,1925],{"class":1014},[193,8007,6723],{"class":998},[193,8009,1950],{"class":1014},[193,8011,4266],{"class":1002},[193,8013,6730],{"class":1021},[193,8015,6733],{"class":1014},[193,8017,6224],{"class":1002},[193,8019,3243],{"class":1002},[193,8021,6718],{"class":1035},[193,8023,2824],{"class":1002},[193,8025,1192],{"class":1002},[193,8027,8028,8030,8032,8034,8036,8038,8040,8042,8044,8046,8048,8050,8052,8054,8056,8058,8060,8062,8064,8066],{"class":195,"line":600},[193,8029,5828],{"class":994},[193,8031,6751],{"class":998},[193,8033,3580],{"class":1002},[193,8035,6437],{"class":1014},[193,8037,6574],{"class":998},[193,8039,6663],{"class":1002},[193,8041,6666],{"class":998},[193,8043,1950],{"class":1014},[193,8045,6671],{"class":1002},[193,8047,1511],{"class":1021},[193,8049,1018],{"class":1002},[193,8051,6679],{"class":998},[193,8053,1355],{"class":1014},[193,8055,6574],{"class":998},[193,8057,6686],{"class":1002},[193,8059,6666],{"class":998},[193,8061,1405],{"class":1014},[193,8063,1186],{"class":1002},[193,8065,6654],{"class":998},[193,8067,1192],{"class":1002},[193,8069,8070],{"class":195,"line":606},[193,8071,6334],{"class":1014},[193,8073,8074],{"class":195,"line":612},[193,8075,6798],{"class":1136},[193,8077,8078,8080,8082,8084,8086,8088,8090,8092,8094,8096,8098,8100,8102,8104,8106,8108,8110,8112,8114,8116,8118,8120,8122,8124],{"class":195,"line":618},[193,8079,6804],{"class":998},[193,8081,1186],{"class":1002},[193,8083,5968],{"class":1206},[193,8085,1925],{"class":1014},[193,8087,2824],{"class":1002},[193,8089,419],{"class":1035},[193,8091,2824],{"class":1002},[193,8093,28],{"class":1002},[193,8095,6821],{"class":1002},[193,8097,6824],{"class":1035},[193,8099,6827],{"class":1002},[193,8101,6674],{"class":998},[193,8103,1402],{"class":1002},[193,8105,6834],{"class":1035},[193,8107,6827],{"class":1002},[193,8109,6839],{"class":998},[193,8111,1402],{"class":1002},[193,8113,28],{"class":1035},[193,8115,6827],{"class":1002},[193,8117,6654],{"class":998},[193,8119,1402],{"class":1002},[193,8121,6852],{"class":1035},[193,8123,6821],{"class":1002},[193,8125,881],{"class":1014},[193,8127,8128],{"class":195,"line":624},[193,8129,476],{"emptyLinePlaceholder":101},[193,8131,8132],{"class":195,"line":630},[193,8133,6867],{"class":1136},[193,8135,8136,8138,8140,8142,8144],{"class":195,"line":636},[193,8137,6873],{"class":1206},[193,8139,1925],{"class":1014},[193,8141,2804],{"class":1002},[193,8143,2847],{"class":994},[193,8145,233],{"class":1002},[193,8147,8148,8150,8152,8154,8156,8158,8160,8162,8164,8166],{"class":195,"line":642},[193,8149,6887],{"class":998},[193,8151,1186],{"class":1002},[193,8153,6892],{"class":998},[193,8155,1186],{"class":1002},[193,8157,6897],{"class":1206},[193,8159,1925],{"class":1014},[193,8161,2824],{"class":1002},[193,8163,4705],{"class":1035},[193,8165,2824],{"class":1002},[193,8167,881],{"class":1014},[193,8169,8170,8172,8174,8176],{"class":195,"line":648},[193,8171,6913],{"class":1002},[193,8173,6916],{"class":1021},[193,8175,1950],{"class":1014},[193,8177,1192],{"class":1002},[193,8179,8180],{"class":195,"line":654},[193,8181,274],{"class":1002},[13,8183,8184,8187,8188,8190,8191,8194],{},[25,8185,8186],{},"scanAdd()","では対象のID（DOMのID）に基づいて",[25,8189,6679],{},"から高さを設定する対象のカードと、そのカードの１行上のカードの情報を取得します。例えば５番目のカードの場合、２番目のカードの高さを用いてY座標を決定します。この関数ではその情報を元にしてカードに高さを与え、また表示する位置のx,y座標を決定して",[25,8192,8193],{},"translate","の値を決定します。",[3533,8196,8197],{"id":8197},"関数の連結とイベントリスナー",[49,8199,8201],{"className":985,"code":8200,"language":987,"meta":57,"style":57},"\u002F\u002F 追加ボタンにイベントリスナーを付与\ncardsAddBtn.addEventListener('click',()=>{\n    return onClickAdd();\n})\n\n\u002F\u002F イベントリスナーの内容\nlet onClickAdd = ()=>{\n    let card = createCard();\n    insertCard(card.dom);\n    scanAdd(card.id);\n}\n",[25,8202,8203,8207,8229,8239,8245,8249,8253,8267,8281,8297,8313],{"__ignoreMap":57},[193,8204,8205],{"class":195,"line":196},[193,8206,5754],{"class":1136},[193,8208,8209,8211,8213,8215,8217,8219,8221,8223,8225,8227],{"class":195,"line":93},[193,8210,5759],{"class":998},[193,8212,1186],{"class":1002},[193,8214,5764],{"class":1206},[193,8216,1925],{"class":998},[193,8218,2824],{"class":1002},[193,8220,5771],{"class":1035},[193,8222,2824],{"class":1002},[193,8224,5776],{"class":1002},[193,8226,2847],{"class":994},[193,8228,233],{"class":1002},[193,8230,8231,8233,8235,8237],{"class":195,"line":90},[193,8232,5785],{"class":1938},[193,8234,5788],{"class":1206},[193,8236,2804],{"class":1014},[193,8238,1192],{"class":1002},[193,8240,8241,8243],{"class":195,"line":212},[193,8242,1402],{"class":1002},[193,8244,881],{"class":998},[193,8246,8247],{"class":195,"line":218},[193,8248,476],{"emptyLinePlaceholder":101},[193,8250,8251],{"class":195,"line":224},[193,8252,5807],{"class":1136},[193,8254,8255,8257,8259,8261,8263,8265],{"class":195,"line":230},[193,8256,5450],{"class":994},[193,8258,5814],{"class":998},[193,8260,1003],{"class":1002},[193,8262,5819],{"class":1002},[193,8264,2847],{"class":994},[193,8266,233],{"class":1002},[193,8268,8269,8271,8273,8275,8277,8279],{"class":195,"line":236},[193,8270,5828],{"class":994},[193,8272,5831],{"class":998},[193,8274,3580],{"class":1002},[193,8276,5836],{"class":1206},[193,8278,2804],{"class":1014},[193,8280,1192],{"class":1002},[193,8282,8283,8285,8287,8289,8291,8293,8295],{"class":195,"line":242},[193,8284,5845],{"class":1206},[193,8286,1925],{"class":1014},[193,8288,5850],{"class":998},[193,8290,1186],{"class":1002},[193,8292,5855],{"class":998},[193,8294,1950],{"class":1014},[193,8296,1192],{"class":1002},[193,8298,8299,8301,8303,8305,8307,8309,8311],{"class":195,"line":248},[193,8300,5864],{"class":1206},[193,8302,1925],{"class":1014},[193,8304,5850],{"class":998},[193,8306,1186],{"class":1002},[193,8308,1015],{"class":998},[193,8310,1950],{"class":1014},[193,8312,1192],{"class":1002},[193,8314,8315],{"class":195,"line":254},[193,8316,274],{"class":1002},[13,8318,8319],{},"最後に上記の関数を連結し、イベントリスナーのコールバックに設定します。イベントリスナーはカードの追加ボタンに付与されています。",[133,8321,8322],{"id":8322},"実装後の動き",[13,8324,8325,8326,8329],{},"完成したデモは",[36,8327,4056],{"href":4054,"rel":8328},[40],"にあります。「ADD!」というボタンをクリックするとアニメーションつきでカードが追加されていきます。",[419,8331,8332],{},"html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .s6YsC, html code.shiki .s6YsC{--shiki-default:#B2CCD6}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}",{"title":57,"searchDepth":90,"depth":90,"links":8334},[8335,8336,8340],{"id":4060,"depth":93,"text":4060},{"id":4751,"depth":93,"text":4752,"children":8337},[8338,8339],{"id":4755,"depth":90,"text":4756},{"id":4795,"depth":90,"text":4796},{"id":4812,"depth":93,"text":4812,"children":8341},[8342,8343,8344,8351],{"id":4815,"depth":90,"text":4815},{"id":5141,"depth":90,"text":5142},{"id":5428,"depth":90,"text":5428,"children":8345},[8346,8347,8348,8349,8350],{"id":6951,"depth":212,"text":6951},{"id":7244,"depth":212,"text":7244},{"id":7741,"depth":212,"text":7741},{"id":7794,"depth":212,"text":7794},{"id":8197,"depth":212,"text":8197},{"id":8322,"depth":90,"text":8322},[8353],"devstack","2021-07-14",{},"\u002Farticles\u002Fpinterest-like-style",{"title":4034,"description":4034},"articles\u002Fpinterest-like-style",[4068,4259,2722],"pinterest-like-style\u002Fthumbnail.png","Kk6is-f7e7A8CgIICoPK0ixaA9U5aJL-fp-oIvtU9PM",{"id":8363,"title":8364,"body":8365,"category":9572,"createdAt":9573,"description":9574,"extension":98,"index":99,"meta":9575,"navigation":101,"path":9576,"publish":101,"seo":9577,"series":99,"seriesTitle":99,"stem":9578,"tag":9579,"thumbnail":9581,"updatedAt":99,"__hash__":9582},"articles\u002Farticles\u002Fstatic-site-search.md","AWS Cloud Searchを使用して静的コンテンツに検索機能をつける",{"type":10,"value":8366,"toc":9557},[8367,8370,8373,8376,8379,8382,8385,8402,8405,8408,8411,8420,8423,8426,8429,8432,8435,8438,8451,8454,8665,8671,8674,8682,8685,8688,8844,8851,8854,8857,8860,8863,8866,8870,8879,8882,8885,8893,8896,8903,8906,8913,9041,9044,9048,9051,9272,9282,9285,9288,9291,9294,9305,9308,9317,9321,9324,9327,9379,9382,9385,9388,9391,9394,9397,9400,9539,9542,9545,9548,9551,9554],[13,8368,8369],{},"こんにちはjunです。静的書き出しブログを作って数ヶ月後、ようやくこのブログにも「検索機能」を実装しました。静的ファイルの場合は検索といった動的な機能をつける際には工夫が必要です。",[13,8371,8372],{},"wordpressなどでは自身のプログラムとデータベースを用いて検索を行いますが、静的ブログではその２つがないので別途で準備する必要があります。つまり検索プログラムと検索対象のファイルをどこかに置き、さらにサイトからAjaxを用いてアクセスできるようにします。",[13,8374,8375],{},"私のサイトでは検索エンジンに「AWS Cloudsearch」というものを用いて実装しています。今回の記事でも同じようにCloudsearchを用いての解説を行います。",[17,8377,8378],{"id":8378},"全体の概要",[2959,8380],{":src":8381,":width":2962},"'static-site-search\u002Fcloudsearch_build.jpg'",[13,8383,8384],{},"概要は上図のような感じです。検索機能自体はcloudsearchに任せ、cloudsearchを叩くAPI gatewayを通じてブラウザからアクセスします。これらの構成を実現するために以下の手順の実装が必要となります。",[3097,8386,8387,8390,8393,8396,8399],{},[2976,8388,8389],{},"cloudsearchのインスタンス作成",[2976,8391,8392],{},"検索対象のドキュメント（JSON）をcloudsearchにアップロード",[2976,8394,8395],{},"API gateqwayからcloudsearchを叩くように連携",[2976,8397,8398],{},"ウェブサイトから検索クエリを持たせたリクエストでAPIを叩く",[2976,8400,8401],{},"結果をサイトに表示",[13,8403,8404],{},"それぞれの手順通りに説明していきます。",[17,8406,8407],{"id":8407},"cloudsearchのセットアップ",[133,8409,8410],{"id":8410},"cloudsearchのインスタンスを作成",[13,8412,8413,8414,8419],{},"AWSのアカウント作成などは省略します。AWSのメニューから",[36,8415,8418],{"href":8416,"rel":8417},"https:\u002F\u002Fap-northeast-1.console.aws.amazon.com\u002Fcloudsearch",[40],"cloudsearch","に移動します。リージョンを確認して、「Create a new search domain」をクリックして検索インスタンスを作成します。ここでいうドメインはURLのドメインという意味でなく、「Domain」は検索の区分みたいなものです。",[2959,8421],{":src":8422,":width":2962},"'static-site-search\u002Fcloudsearch_start.png'",[13,8424,8425],{},"インスタンスの大きさなどを選択できますが、今回は一番小さいものにしておきます。Desired Instance Typeをsearch.small、Desired Replication Countを１にしました。",[133,8427,8428],{"id":8428},"インデックスフィールドの登録",[13,8430,8431],{},"次に検索対象のインデックスフィールドを登録します。",[2959,8433],{":src":8434,":width":2962},"'static-site-search\u002Fset_document_key_config.png'",[13,8436,8437],{},"ここでいうインデックスフィールドとはタイトル、内容、カテゴリー、作成日時といった各ドキュメントの属性のことをいいます。インデックスフィールドを設定することでタイトルで検索、内容で検索、特定日時からの検索といった複雑な検索ができます。RDBでいうところのカラムみたいなものです。",[13,8439,8440,8441,8444,8445,8450],{},"もしドキュメントがある場合は",[25,8442,8443],{},"Analyze sample file(s) from my local machine","を選択しファイルをアップロードします。使用できるファイルは",[36,8446,8449],{"href":8447,"rel":8448},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fja_jp\u002Fcloudsearch\u002Flatest\u002Fdeveloperguide\u002Fpreparing-data.html",[40],"XML,JSON,CSVがサポートされています。（詳細はこちら）","アップロードされたファイルから共通のインデックスフィールドを自動で設定してくれます。",[13,8452,8453],{},"私の場合は以下のようなcloudsearchの使用に従った構成でサンプルJSONを予め作成しておきました。",[49,8455,8459],{"className":8456,"code":8457,"language":8458,"meta":57,"style":57},"language-JSON shiki shiki-themes material-theme-ocean","[\n    {\n        \"type\":\"add\",\n        \"id\":\"bag-html-break-tag\",\n        \"fields\":{\n            \"description\":\"white-space： pre;で要素内で生じる、文章の隙間、インテンドの原因。\",\n            \"title\":\"white-space： pre;で要素内で生じる文章の隙間、インテンドの原因。\",\n            \"category\":[\"ministack\"],\n            \"tag\":[\"html\",\"css\",\"vue\"],\n            \"path\":\"https:\u002F\u002Fjun-app.com\u002Farticles\u002Fbag-html-break-tag\",\n            \"content\":\"~~~~~~~~~\"\n        }\n    }\n]\n","JSON",[25,8460,8461,8465,8470,8490,8509,8520,8541,8560,8581,8616,8636,8653,8657,8661],{"__ignoreMap":57},[193,8462,8463],{"class":195,"line":196},[193,8464,2562],{"class":1002},[193,8466,8467],{"class":195,"line":93},[193,8468,8469],{"class":1002},"    {\n",[193,8471,8472,8475,8478,8480,8482,8484,8486,8488],{"class":195,"line":90},[193,8473,8474],{"class":1002},"        \"",[193,8476,8477],{"class":994},"type",[193,8479,1032],{"class":1002},[193,8481,1018],{"class":1002},[193,8483,1032],{"class":1002},[193,8485,6897],{"class":1035},[193,8487,1032],{"class":1002},[193,8489,2579],{"class":1002},[193,8491,8492,8494,8496,8498,8500,8502,8505,8507],{"class":195,"line":212},[193,8493,8474],{"class":1002},[193,8495,1015],{"class":994},[193,8497,1032],{"class":1002},[193,8499,1018],{"class":1002},[193,8501,1032],{"class":1002},[193,8503,8504],{"class":1035},"bag-html-break-tag",[193,8506,1032],{"class":1002},[193,8508,2579],{"class":1002},[193,8510,8511,8513,8516,8518],{"class":195,"line":218},[193,8512,8474],{"class":1002},[193,8514,8515],{"class":994},"fields",[193,8517,1032],{"class":1002},[193,8519,2592],{"class":1002},[193,8521,8522,8525,8528,8530,8532,8534,8537,8539],{"class":195,"line":224},[193,8523,8524],{"class":1002},"            \"",[193,8526,8527],{"class":3254},"description",[193,8529,1032],{"class":1002},[193,8531,1018],{"class":1002},[193,8533,1032],{"class":1002},[193,8535,8536],{"class":1035},"white-space： pre;で要素内で生じる、文章の隙間、インテンドの原因。",[193,8538,1032],{"class":1002},[193,8540,2579],{"class":1002},[193,8542,8543,8545,8547,8549,8551,8553,8556,8558],{"class":195,"line":230},[193,8544,8524],{"class":1002},[193,8546,1027],{"class":3254},[193,8548,1032],{"class":1002},[193,8550,1018],{"class":1002},[193,8552,1032],{"class":1002},[193,8554,8555],{"class":1035},"white-space： pre;で要素内で生じる文章の隙間、インテンドの原因。",[193,8557,1032],{"class":1002},[193,8559,2579],{"class":1002},[193,8561,8562,8564,8567,8569,8572,8574,8576,8578],{"class":195,"line":236},[193,8563,8524],{"class":1002},[193,8565,8566],{"class":3254},"category",[193,8568,1032],{"class":1002},[193,8570,8571],{"class":1002},":[",[193,8573,1032],{"class":1002},[193,8575,96],{"class":1035},[193,8577,1032],{"class":1002},[193,8579,8580],{"class":1002},"],\n",[193,8582,8583,8585,8588,8590,8592,8594,8596,8598,8600,8602,8604,8606,8608,8610,8612,8614],{"class":195,"line":242},[193,8584,8524],{"class":1002},[193,8586,8587],{"class":3254},"tag",[193,8589,1032],{"class":1002},[193,8591,8571],{"class":1002},[193,8593,1032],{"class":1002},[193,8595,4068],{"class":1035},[193,8597,1032],{"class":1002},[193,8599,28],{"class":1002},[193,8601,1032],{"class":1002},[193,8603,4259],{"class":1035},[193,8605,1032],{"class":1002},[193,8607,28],{"class":1002},[193,8609,1032],{"class":1002},[193,8611,2723],{"class":1035},[193,8613,1032],{"class":1002},[193,8615,8580],{"class":1002},[193,8617,8618,8620,8623,8625,8627,8629,8632,8634],{"class":195,"line":248},[193,8619,8524],{"class":1002},[193,8621,8622],{"class":3254},"path",[193,8624,1032],{"class":1002},[193,8626,1018],{"class":1002},[193,8628,1032],{"class":1002},[193,8630,8631],{"class":1035},"https:\u002F\u002Fjun-app.com\u002Farticles\u002Fbag-html-break-tag",[193,8633,1032],{"class":1002},[193,8635,2579],{"class":1002},[193,8637,8638,8640,8642,8644,8646,8648,8651],{"class":195,"line":254},[193,8639,8524],{"class":1002},[193,8641,1043],{"class":3254},[193,8643,1032],{"class":1002},[193,8645,1018],{"class":1002},[193,8647,1032],{"class":1002},[193,8649,8650],{"class":1035},"~~~~~~~~~",[193,8652,2618],{"class":1002},[193,8654,8655],{"class":195,"line":259},[193,8656,3806],{"class":1002},[193,8658,8659],{"class":195,"line":265},[193,8660,3968],{"class":1002},[193,8662,8663],{"class":195,"line":271},[193,8664,1142],{"class":1002},[13,8666,8667,8668,8670],{},"この場合、",[25,8669,8515],{},"にある項目が自動に読みとれ、以下のように設定されます。",[2959,8672],{":src":8673,":width":2962},"'static-site-search\u002Fconf_key.png'",[13,8675,8676,8677,8681],{},"インデックスフィールドの設定詳細は",[36,8678,4056],{"href":8679,"rel":8680},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fja_jp\u002Fcloudsearch\u002Flatest\u002Fdeveloperguide\u002Fconfiguring-index-fields.html",[40],"を参考にしてください。",[133,8683,8684],{"id":8684},"アクセスポリシーの追加",[13,8686,8687],{},"次にこのcloudsearchインスタンスに対するアクセスポリシーを設定します。",[49,8689,8693],{"className":8690,"code":8691,"language":8692,"meta":57,"style":57},"language-json shiki shiki-themes material-theme-ocean","{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"AWS\": \"*\"\n      },\n      \"Action\": [\n        \"cloudsearch:search\",\n        \"cloudsearch:suggest\"\n      ]\n    }\n  ]\n}\n","json",[25,8694,8695,8699,8720,8733,8737,8758,8771,8788,8793,8806,8817,8826,8831,8835,8840],{"__ignoreMap":57},[193,8696,8697],{"class":195,"line":196},[193,8698,233],{"class":1002},[193,8700,8701,8704,8707,8709,8711,8713,8716,8718],{"class":195,"line":93},[193,8702,8703],{"class":1002},"  \"",[193,8705,8706],{"class":994},"Version",[193,8708,1032],{"class":1002},[193,8710,1018],{"class":1002},[193,8712,1582],{"class":1002},[193,8714,8715],{"class":1035},"2012-10-17",[193,8717,1032],{"class":1002},[193,8719,2579],{"class":1002},[193,8721,8722,8724,8727,8729,8731],{"class":195,"line":90},[193,8723,8703],{"class":1002},[193,8725,8726],{"class":994},"Statement",[193,8728,1032],{"class":1002},[193,8730,1018],{"class":1002},[193,8732,1006],{"class":1002},[193,8734,8735],{"class":195,"line":212},[193,8736,8469],{"class":1002},[193,8738,8739,8742,8745,8747,8749,8751,8754,8756],{"class":195,"line":218},[193,8740,8741],{"class":1002},"      \"",[193,8743,8744],{"class":3254},"Effect",[193,8746,1032],{"class":1002},[193,8748,1018],{"class":1002},[193,8750,1582],{"class":1002},[193,8752,8753],{"class":1035},"Allow",[193,8755,1032],{"class":1002},[193,8757,2579],{"class":1002},[193,8759,8760,8762,8765,8767,8769],{"class":195,"line":224},[193,8761,8741],{"class":1002},[193,8763,8764],{"class":3254},"Principal",[193,8766,1032],{"class":1002},[193,8768,1018],{"class":1002},[193,8770,2534],{"class":1002},[193,8772,8773,8775,8778,8780,8782,8784,8786],{"class":195,"line":230},[193,8774,8474],{"class":1002},[193,8776,8777],{"class":1021},"AWS",[193,8779,1032],{"class":1002},[193,8781,1018],{"class":1002},[193,8783,1582],{"class":1002},[193,8785,4266],{"class":1035},[193,8787,2618],{"class":1002},[193,8789,8790],{"class":195,"line":236},[193,8791,8792],{"class":1002},"      },\n",[193,8794,8795,8797,8800,8802,8804],{"class":195,"line":242},[193,8796,8741],{"class":1002},[193,8798,8799],{"class":3254},"Action",[193,8801,1032],{"class":1002},[193,8803,1018],{"class":1002},[193,8805,1006],{"class":1002},[193,8807,8808,8810,8813,8815],{"class":195,"line":248},[193,8809,8474],{"class":1002},[193,8811,8812],{"class":1035},"cloudsearch:search",[193,8814,1032],{"class":1002},[193,8816,2579],{"class":1002},[193,8818,8819,8821,8824],{"class":195,"line":254},[193,8820,8474],{"class":1002},[193,8822,8823],{"class":1035},"cloudsearch:suggest",[193,8825,2618],{"class":1002},[193,8827,8828],{"class":195,"line":259},[193,8829,8830],{"class":1002},"      ]\n",[193,8832,8833],{"class":195,"line":265},[193,8834,3968],{"class":1002},[193,8836,8837],{"class":195,"line":271},[193,8838,8839],{"class":1002},"  ]\n",[193,8841,8842],{"class":195,"line":600},[193,8843,274],{"class":1002},[13,8845,8846,8847,8850],{},"もう少し厳密にしたい人は ",[25,8848,8849],{},"\"AWS\": \"*\"","をロールベースにするなどします。これでAWSのサービス、すなわちAPI gatewayがこのcloudsearchの検索機能を使用できるようになりました。",[133,8852,8853],{"id":8853},"セットアップ完了",[13,8855,8856],{},"最後に確認をして適用します。設定の適用には10分ぐらい時間がかかるので気長に待ちます。この時は他の文書をアップロードするなどもできなくなります。",[2959,8858],{":src":8859,":width":2962},"'static-site-search\u002Ffirst_setuop_complete.png'",[13,8861,8862],{},"このLOADINGという文字がACTIVEに変われば他の操作ができるようになります。",[2959,8864],{":src":8865,":width":2962},"'static-site-search\u002Floading.png'",[17,8867,8869],{"id":8868},"api-gatewayの準備","API gatewayの準備",[13,8871,8872,8873,8878],{},"cloudsearchの処理が完了する間、API gatewayも実装しましょう。公式では",[36,8874,8877],{"href":8875,"rel":8876},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fja_jp\u002Fcloudsearch\u002Flatest\u002Fdeveloperguide\u002Fapi-gateway.html",[40],"「Amazon CloudSearch と API Gateway の統合」"," こちらの記事が大変参考になります。",[13,8880,8881],{},"新しいAPIの作成まで行ったら、GETメソッドのAPIを選択します。そして「統合リクエスト」を選択します。ここでリクエストをAWSのサービスに連絡させます。",[2959,8883],{":src":8884,":width":4774,":center":1552},"'static-site-search\u002Fapi_setting.png'",[13,8886,8887,8888,8892],{},"上記の黒塗りにした箇所はcloudsearchのダッシュボードにある値を入れます。「AWSサブドメイン」は「Search Endpoint」、「実行ロール」はAPI gatewayがcloudsearchを叩くためのロールのARNを入れます。そのロールの作成は",[36,8889,4056],{"href":8890,"rel":8891},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fja_jp\u002Fcloudsearch\u002Flatest\u002Fdeveloperguide\u002Fapi-gateway.html#api-gateway-pre",[40]," を確認してください。",[2959,8894],{":src":8895,":width":4774,":center":1552},"'static-site-search\u002Fdashboard.png'",[13,8897,8898,8899,8902],{},"最後に「URL クエリ文字列パラメータ」に「q」という名前でAPI gatewaryに含まれる ",[25,8900,8901],{},"method.request.querystring.q","をマッピングします。こうすることでクライアントからきたcloudsearchのクエリが、API gatewayを通じて実際のcloudsearchに渡されるようになりました。",[13,8904,8905],{},"次に「統合リクエスト」から一つ前の画面に戻って「メソッドリクエスト」の画面を開き、「リクエストの検証」の項目で「クエリ文字列パラメーターおよびヘッダーの検証」を選択します。そして先ほど設定したクエリパラメータ「q」を必須にするため、「URL クエリ文字列パラメータ」を開いて名前に「q」として必須にして確定します。こうすることで必ずリクエストにはcloudsearchで検索を行うためのクエリ文が含まれるようになりました。",[13,8907,8908,8909,8912],{},"テストを行い、クエリ文字列に",[25,8910,8911],{},"q=test","みたいに入れて送ってみましょう。ステータスが200で以下のようなレスポンスボディがあればcloudsearchが検索結果を返しています。",[49,8914,8916],{"className":8690,"code":8915,"language":8692,"meta":57,"style":57},"{\n  \"status\": {\n    \"rid\": \"~~~~~~\",\n    \"time-ms\": 1\n  },\n  \"hits\": {\n    \"found\": 0,\n    \"start\": 0,\n    \"hit\": []\n  }\n}\n",[25,8917,8918,8922,8935,8956,8970,8975,8988,9003,9018,9032,9037],{"__ignoreMap":57},[193,8919,8920],{"class":195,"line":196},[193,8921,233],{"class":1002},[193,8923,8924,8926,8929,8931,8933],{"class":195,"line":93},[193,8925,8703],{"class":1002},[193,8927,8928],{"class":994},"status",[193,8930,1032],{"class":1002},[193,8932,1018],{"class":1002},[193,8934,2534],{"class":1002},[193,8936,8937,8940,8943,8945,8947,8949,8952,8954],{"class":195,"line":90},[193,8938,8939],{"class":1002},"    \"",[193,8941,8942],{"class":3254},"rid",[193,8944,1032],{"class":1002},[193,8946,1018],{"class":1002},[193,8948,1582],{"class":1002},[193,8950,8951],{"class":1035},"~~~~~~",[193,8953,1032],{"class":1002},[193,8955,2579],{"class":1002},[193,8957,8958,8960,8963,8965,8967],{"class":195,"line":212},[193,8959,8939],{"class":1002},[193,8961,8962],{"class":3254},"time-ms",[193,8964,1032],{"class":1002},[193,8966,1018],{"class":1002},[193,8968,8969],{"class":1021}," 1\n",[193,8971,8972],{"class":195,"line":218},[193,8973,8974],{"class":1002},"  },\n",[193,8976,8977,8979,8982,8984,8986],{"class":195,"line":224},[193,8978,8703],{"class":1002},[193,8980,8981],{"class":994},"hits",[193,8983,1032],{"class":1002},[193,8985,1018],{"class":1002},[193,8987,2534],{"class":1002},[193,8989,8990,8992,8995,8997,8999,9001],{"class":195,"line":230},[193,8991,8939],{"class":1002},[193,8993,8994],{"class":3254},"found",[193,8996,1032],{"class":1002},[193,8998,1018],{"class":1002},[193,9000,4279],{"class":1021},[193,9002,2579],{"class":1002},[193,9004,9005,9007,9010,9012,9014,9016],{"class":195,"line":236},[193,9006,8939],{"class":1002},[193,9008,9009],{"class":3254},"start",[193,9011,1032],{"class":1002},[193,9013,1018],{"class":1002},[193,9015,4279],{"class":1021},[193,9017,2579],{"class":1002},[193,9019,9020,9022,9025,9027,9029],{"class":195,"line":242},[193,9021,8939],{"class":1002},[193,9023,9024],{"class":3254},"hit",[193,9026,1032],{"class":1002},[193,9028,1018],{"class":1002},[193,9030,9031],{"class":1002}," []\n",[193,9033,9034],{"class":195,"line":248},[193,9035,9036],{"class":1002},"  }\n",[193,9038,9039],{"class":195,"line":254},[193,9040,274],{"class":1002},[13,9042,9043],{},"何も文書をアップロードしていなければhitしませんし、そしてCloudsearchがLOADINGだと返してくれないことがあります。テストが完了したらAPIをデプロイしてAPI gatewayの設定は完了です。あとはクライアントから適当に叩いてください。",[17,9045,9047],{"id":9046},"文書ページをアップロードする","文書（ページ）をアップロードする",[13,9049,9050],{},"それでは検索させる文書、静的ページの内容をアップロードしましょう。先述の通り以下のような形式のJSONにまとめます。",[49,9052,9054],{"className":8456,"code":9053,"language":8458,"meta":57,"style":57},"[\n    \u002F\u002F ここから\n    {\n        \"type\":\"add\",\n        \"id\":\"bag-html-break-tag\",\n        \"fields\":{\n            \"description\":\"white-space： pre;で要素内で生じる、文章の隙間、インテンドの原因。\",\n            \"title\":\"white-space： pre;で要素内で生じる文章の隙間、インテンドの原因。\",\n            \"category\":[\"ministack\"],\n            \"tag\":[\"html\",\"css\",\"vue\"],\n            \"path\":\"https:\u002F\u002Fjun-app.com\u002Farticles\u002Fbag-html-break-tag\",\n            \"content\":\"~~~~~~~~~\"\n        }\n    },\n    \u002F\u002F　これで１件の文書を追加するという意味。\n    {\n        ...\n    },\n    ...\n]\n",[25,9055,9056,9060,9065,9069,9087,9105,9115,9133,9151,9169,9203,9221,9237,9241,9246,9251,9255,9259,9263,9268],{"__ignoreMap":57},[193,9057,9058],{"class":195,"line":196},[193,9059,2562],{"class":1002},[193,9061,9062],{"class":195,"line":93},[193,9063,9064],{"class":1136},"    \u002F\u002F ここから\n",[193,9066,9067],{"class":195,"line":90},[193,9068,8469],{"class":1002},[193,9070,9071,9073,9075,9077,9079,9081,9083,9085],{"class":195,"line":212},[193,9072,8474],{"class":1002},[193,9074,8477],{"class":994},[193,9076,1032],{"class":1002},[193,9078,1018],{"class":1002},[193,9080,1032],{"class":1002},[193,9082,6897],{"class":1035},[193,9084,1032],{"class":1002},[193,9086,2579],{"class":1002},[193,9088,9089,9091,9093,9095,9097,9099,9101,9103],{"class":195,"line":218},[193,9090,8474],{"class":1002},[193,9092,1015],{"class":994},[193,9094,1032],{"class":1002},[193,9096,1018],{"class":1002},[193,9098,1032],{"class":1002},[193,9100,8504],{"class":1035},[193,9102,1032],{"class":1002},[193,9104,2579],{"class":1002},[193,9106,9107,9109,9111,9113],{"class":195,"line":224},[193,9108,8474],{"class":1002},[193,9110,8515],{"class":994},[193,9112,1032],{"class":1002},[193,9114,2592],{"class":1002},[193,9116,9117,9119,9121,9123,9125,9127,9129,9131],{"class":195,"line":230},[193,9118,8524],{"class":1002},[193,9120,8527],{"class":3254},[193,9122,1032],{"class":1002},[193,9124,1018],{"class":1002},[193,9126,1032],{"class":1002},[193,9128,8536],{"class":1035},[193,9130,1032],{"class":1002},[193,9132,2579],{"class":1002},[193,9134,9135,9137,9139,9141,9143,9145,9147,9149],{"class":195,"line":236},[193,9136,8524],{"class":1002},[193,9138,1027],{"class":3254},[193,9140,1032],{"class":1002},[193,9142,1018],{"class":1002},[193,9144,1032],{"class":1002},[193,9146,8555],{"class":1035},[193,9148,1032],{"class":1002},[193,9150,2579],{"class":1002},[193,9152,9153,9155,9157,9159,9161,9163,9165,9167],{"class":195,"line":242},[193,9154,8524],{"class":1002},[193,9156,8566],{"class":3254},[193,9158,1032],{"class":1002},[193,9160,8571],{"class":1002},[193,9162,1032],{"class":1002},[193,9164,96],{"class":1035},[193,9166,1032],{"class":1002},[193,9168,8580],{"class":1002},[193,9170,9171,9173,9175,9177,9179,9181,9183,9185,9187,9189,9191,9193,9195,9197,9199,9201],{"class":195,"line":248},[193,9172,8524],{"class":1002},[193,9174,8587],{"class":3254},[193,9176,1032],{"class":1002},[193,9178,8571],{"class":1002},[193,9180,1032],{"class":1002},[193,9182,4068],{"class":1035},[193,9184,1032],{"class":1002},[193,9186,28],{"class":1002},[193,9188,1032],{"class":1002},[193,9190,4259],{"class":1035},[193,9192,1032],{"class":1002},[193,9194,28],{"class":1002},[193,9196,1032],{"class":1002},[193,9198,2723],{"class":1035},[193,9200,1032],{"class":1002},[193,9202,8580],{"class":1002},[193,9204,9205,9207,9209,9211,9213,9215,9217,9219],{"class":195,"line":254},[193,9206,8524],{"class":1002},[193,9208,8622],{"class":3254},[193,9210,1032],{"class":1002},[193,9212,1018],{"class":1002},[193,9214,1032],{"class":1002},[193,9216,8631],{"class":1035},[193,9218,1032],{"class":1002},[193,9220,2579],{"class":1002},[193,9222,9223,9225,9227,9229,9231,9233,9235],{"class":195,"line":259},[193,9224,8524],{"class":1002},[193,9226,1043],{"class":3254},[193,9228,1032],{"class":1002},[193,9230,1018],{"class":1002},[193,9232,1032],{"class":1002},[193,9234,8650],{"class":1035},[193,9236,2618],{"class":1002},[193,9238,9239],{"class":195,"line":265},[193,9240,3806],{"class":1002},[193,9242,9243],{"class":195,"line":271},[193,9244,9245],{"class":1002},"    },\n",[193,9247,9248],{"class":195,"line":600},[193,9249,9250],{"class":1136},"    \u002F\u002F　これで１件の文書を追加するという意味。\n",[193,9252,9253],{"class":195,"line":606},[193,9254,8469],{"class":1002},[193,9256,9257],{"class":195,"line":612},[193,9258,1260],{"class":998},[193,9260,9261],{"class":195,"line":618},[193,9262,9245],{"class":1002},[193,9264,9265],{"class":195,"line":624},[193,9266,9267],{"class":998},"    ...\n",[193,9269,9270],{"class":195,"line":630},[193,9271,1142],{"class":1002},[13,9273,9274,9275,28,9277,28,9279,9281],{},"ここでアップロードの際には上記のような",[25,9276,8477],{},[25,9278,1015],{},[25,9280,8515],{}," の3つのプロパティーを持つ必要があります。idは重複すると上書きされてしまうので、必ず異なるようにします。また後からわかるように何らかの規則があると、削除や上書きが簡単になります。私の場合は記事のマークダウンファイルの名前から取っています。私のブログはnuxt contentを使用しているのでnode.jsをいじってうんちゃらしています。頑張って文書分のjsonを用意してください。",[133,9283,9284],{"id":9284},"json化する際の注意点",[13,9286,9287],{},"文書のアップロードを行う時に失敗すると以下のような画面が表示されます。",[2959,9289],{":src":9290,":width":2962,":center":1552},"'static-site-search\u002Ffailed.png'",[13,9292,9293],{},"アップロードが失敗する原因と対策としてこの英文の通り",[3097,9295,9296,9299,9302],{},[2976,9297,9298],{},"cloudsearchがACTIVEでなくLOADINGやNEED INDEX状態であるので、ACTIVEになるまで待つこと。（またはindex optionsでインデックスを走らせる）",[2976,9300,9301],{},"single valueとして定義されたフィールドになっているのに、文書に複数の値が入っている。（自分もよくわからん）",[2976,9303,9304],{},"cloudserachで定義されていないフィールドが文書にある。またはその逆。フィールドの設定をもう一度見直すか、文書のフィールドを設定し直す。",[13,9306,9307],{},"となります。",[13,9309,9310,9311,9316],{},"ただしフィールドなどを正しくしても何度も治らず、いろいろ検索しました。すると",[36,9312,9315],{"href":9313,"rel":9314},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fja_jp\u002Fcloudsearch\u002Flatest\u002Fdeveloperguide\u002Fpreparing-data.html#:~:text=JSON%20%E3%83%90%E3%83%83%E3%83%81%E3%81%A8%20XML%20%E3%83%90%E3%83%83%E3%83%81%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%A1%E3%82%89%E3%82%82%E3%80%81XML%20%E3%81%A7%E6%9C%89%E5%8A%B9%E3%81%AA%20UTF-8%20%E6%96%87%E5%AD%97%E3%81%AE%E3%81%BF%E3%82%92%E5%90%AB%E3%82%81%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82",[40],"公式ドキュメントのこの箇所","に解決策と思われる内容がありました。",[1310,9318,9320],{"className":9319},[1313,1314],"\nJSON バッチと XML バッチにはどちらも、XML で有効な UTF-8 文字のみを含めることができます。有効な文字は、制御文字のタブ（0009）、復帰（000D）、改行（000A）、および Unicode と ISO\u002FIEC 10646 での有効な文字です。FFFE、FFFF、サロゲートブロックの D800–DBFF と DC00–DFFF は無効で、エラーが発生します （詳細については、『Extensible Markup Language (XML) 1.0 (Fifth Edition)』 を参照してください)。無効な文字に一致する次の正規表現を使用して、無効な文字を削除することができます。\u002F[^\\u0009\\u000a\\u000d\\u0020-\\uD7FF\\uE000-\\uFFFD]\u002F 。\n",[13,9322,9323],{},"つまり作成したJSONに無効なURF-8文字列が含まれており、エラーが起きていたのです。アップロードエラーには表示されないのでかなり詰まりました。",[13,9325,9326],{},"今回のjsonの場合、titleとcontentに対して上記の正規表現を使って無効な文字列を削除してます。node.jsの場合は以下の通りです。",[49,9328,9330],{"className":985,"code":9329,"language":987,"meta":57,"style":57},"data = data.replace(\n    \u002F[^\\u0009\\u000a\\u000d\\u0020-\\uD7FF\\uE000-\\uFFFD]\u002Fg, \n    ''\n);\n",[25,9331,9332,9350,9368,9373],{"__ignoreMap":57},[193,9333,9334,9337,9339,9342,9344,9347],{"class":195,"line":196},[193,9335,9336],{"class":998},"data ",[193,9338,1003],{"class":1002},[193,9340,9341],{"class":998}," data",[193,9343,1186],{"class":1002},[193,9345,9346],{"class":1206},"replace",[193,9348,9349],{"class":998},"(\n",[193,9351,9352,9355,9358,9361,9364,9366],{"class":195,"line":93},[193,9353,9354],{"class":1002},"    \u002F[^",[193,9356,9357],{"class":1035},"\\u0009\\u000a\\u000d\\u0020-\\uD7FF\\uE000-\\uFFFD",[193,9359,9360],{"class":1002},"]\u002F",[193,9362,9363],{"class":1021},"g",[193,9365,28],{"class":1002},[193,9367,5204],{"class":998},[193,9369,9370],{"class":195,"line":90},[193,9371,9372],{"class":1002},"    ''\n",[193,9374,9375,9377],{"class":195,"line":212},[193,9376,1950],{"class":998},[193,9378,1192],{"class":1002},[13,9380,9381],{},"こうして直したjsonは無事、なんとかアップロードできました。どうやって見つけたかというと、１文書だけをいくつかのパターンに分けてアップロードすると、できるものとできないものがあって「使用される文字列が原因か？」となったのが決定打でした。",[133,9383,9384],{"id":9384},"テスト",[13,9386,9387],{},"Run a Test Searchにてクエリをテストして、文章がきちんと検索されているか、アップロードされているかをチェックしましょう。",[17,9389,9390],{"id":9390},"クライアント側の実装",[13,9392,9393],{},"これで検索機能の準備ができたので、API gatewayから必要なエンドポイントなどを取得してアクセスしてみましょう。",[2959,9395],{":src":9396,":width":2962,":center":1552},"'static-site-search\u002Fpage_sample.png'",[13,9398,9399],{},"ページ上ではこのようなUIとして、入力したキーワードで検索できるようにします。cloudsearchは複雑なクエリを組むこともできるのですが、今回は単純なものにします。",[49,9401,9403],{"className":985,"code":9402,"language":987,"meta":57,"style":57},"await fetch('https:\u002F\u002Fsample.sa-sample-1.amazonaws.com\u002Fv1?q='+this.query,{\n        method:'GET',\n        headers: {\n        'Content-Type': 'application\u002Fjson'\n        },\n    })\n.then(response => response.json())\n.then(jsondata => {\n    this.result = jsondata\n)\n",[25,9404,9405,9431,9447,9456,9475,9480,9486,9508,9523,9535],{"__ignoreMap":57},[193,9406,9407,9410,9413,9415,9417,9420,9422,9425,9428],{"class":195,"line":196},[193,9408,9409],{"class":1938},"await",[193,9411,9412],{"class":1206}," fetch",[193,9414,1925],{"class":998},[193,9416,2824],{"class":1002},[193,9418,9419],{"class":1035},"https:\u002F\u002Fsample.sa-sample-1.amazonaws.com\u002Fv1?q=",[193,9421,2824],{"class":1002},[193,9423,9424],{"class":1002},"+this.",[193,9426,9427],{"class":998},"query",[193,9429,9430],{"class":1002},",{\n",[193,9432,9433,9436,9438,9440,9443,9445],{"class":195,"line":93},[193,9434,9435],{"class":1014},"        method",[193,9437,1018],{"class":1002},[193,9439,2824],{"class":1002},[193,9441,9442],{"class":1035},"GET",[193,9444,2824],{"class":1002},[193,9446,2579],{"class":1002},[193,9448,9449,9452,9454],{"class":195,"line":90},[193,9450,9451],{"class":1014},"        headers",[193,9453,1018],{"class":1002},[193,9455,2534],{"class":1002},[193,9457,9458,9461,9464,9466,9468,9470,9473],{"class":195,"line":212},[193,9459,9460],{"class":1002},"        '",[193,9462,9463],{"class":1014},"Content-Type",[193,9465,2824],{"class":1002},[193,9467,1018],{"class":1002},[193,9469,3243],{"class":1002},[193,9471,9472],{"class":1035},"application\u002Fjson",[193,9474,3249],{"class":1002},[193,9476,9477],{"class":195,"line":218},[193,9478,9479],{"class":1002},"        },\n",[193,9481,9482,9484],{"class":195,"line":224},[193,9483,2903],{"class":1002},[193,9485,881],{"class":998},[193,9487,9488,9490,9492,9494,9497,9499,9501,9503,9505],{"class":195,"line":230},[193,9489,1186],{"class":1002},[193,9491,2839],{"class":1206},[193,9493,1925],{"class":998},[193,9495,9496],{"class":1928},"response",[193,9498,1932],{"class":994},[193,9500,1183],{"class":998},[193,9502,1186],{"class":1002},[193,9504,8692],{"class":1206},[193,9506,9507],{"class":998},"())\n",[193,9509,9510,9512,9514,9516,9519,9521],{"class":195,"line":236},[193,9511,1186],{"class":1002},[193,9513,2839],{"class":1206},[193,9515,1925],{"class":998},[193,9517,9518],{"class":1928},"jsondata",[193,9520,1932],{"class":994},[193,9522,2534],{"class":1002},[193,9524,9525,9527,9530,9532],{"class":195,"line":242},[193,9526,2811],{"class":1002},[193,9528,9529],{"class":998},"result",[193,9531,3580],{"class":1002},[193,9533,9534],{"class":998}," jsondata\n",[193,9536,9537],{"class":195,"line":248},[193,9538,881],{"class":1014},[13,9540,9541],{},"方法は単純でバリデーションを行った後に、API gatewayのエンドポイントにクエリ付きでアクセスします。",[2959,9543],{":src":9544,":width":2962,":center":1552},"'static-site-search\u002Fresult.png'",[13,9546,9547],{},"ページのURLなどもフィールドを含まれており、レスポンスで返すようにしています。それを用いてこのように一覧のリンクを作れば検索機能は実装完了です。",[13,9549,9550],{},"今回は検索エンジンにAWS cloudsearchを使用しましたが、他にも文書検索サービスはたくさんあります。商用で利用する場合は検索文書を自動的にアップロードしたりする機能や、より複雑なクエリの構築、キャッシュの利用が必要となります。",[13,9552,9553],{},"以上が静的ページに検索機能を持たせる方法です。最後見てくださりありがとうございました。",[419,9555,9556],{},"html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}",{"title":57,"searchDepth":90,"depth":90,"links":9558},[9559,9560,9566,9567,9571],{"id":8378,"depth":93,"text":8378},{"id":8407,"depth":93,"text":8407,"children":9561},[9562,9563,9564,9565],{"id":8410,"depth":90,"text":8410},{"id":8428,"depth":90,"text":8428},{"id":8684,"depth":90,"text":8684},{"id":8853,"depth":90,"text":8853},{"id":8868,"depth":93,"text":8869},{"id":9046,"depth":93,"text":9047,"children":9568},[9569,9570],{"id":9284,"depth":90,"text":9284},{"id":9384,"depth":90,"text":9384},{"id":9390,"depth":93,"text":9390},[8353],"2021-06-28","Google Search以外にも方法があります！AWS Cloud Searchを使って静的サイトに検索機能をつける。",{},"\u002Farticles\u002Fstatic-site-search",{"title":8364,"description":9574},"articles\u002Fstatic-site-search",[9580,2722],"aws","static-site-search\u002Fthumbnail.png","CvPv7DEIqq4ZRH1_F9I9qcalQq9c5xGj_OltNaXdZ3k",{"id":9584,"title":9585,"body":9586,"category":11219,"createdAt":9573,"description":11220,"extension":98,"index":99,"meta":11221,"navigation":101,"path":11222,"publish":101,"seo":11223,"series":99,"seriesTitle":99,"stem":11224,"tag":11225,"thumbnail":11226,"updatedAt":99,"__hash__":11227},"articles\u002Farticles\u002Fuseful-sass-mixins.md","Sassをプロジェクトで使うときに役に立つメディアクエリmixinとカラーパターン",{"type":10,"value":9587,"toc":11215},[9588,9591,9602,9605,9608,9611,9614,9692,9695,10438,10441,10546,10561,10564,10579,10725,10728,10892,10895,11203,11206,11209,11212],[13,9589,9590],{},"こんにちはjunです。最近のプロジェクトではsassばかり使っていてもうcssを書くことがなくなっているせいか、sassの記法でcssを書いてしまいエラーを起こすことも何回かありました笑。sassはフロントエンドで開発するならば絶対に使えておきたいツールです。その中でプロジェクトに関係なく、同じユーティリティーなライブラリ的なmixinを使うことがあります。",[13,9592,9593,9594,9597,9598,9601],{},"例えば引数を指定するだけでプロジェクトで定義したメディアクエリを出すmixin、bootstrapのように",[25,9595,9596],{},"component-primary","とすれば",[25,9599,9600],{},"primary","色にしてくれるクラスを出力するmixinなどです。mixin意外にもmargin,paddingのユーティリティなどもよく使います。",[13,9603,9604],{},"いつも忘れてサイトを探して時間を潰しているのでここにメモしたいと思います。",[13,9606,9607],{},"※sassの解説ですがscssの記述をします！sass=scssと思ってみてください。",[17,9609,9610],{"id":9610},"引数を使用して特定のメディアクエリを利かすmixin",[13,9612,9613],{},"sassを使用する場合、あるクラスに対するメディアクエリは以下のように付与できます。",[49,9615,9619],{"className":9616,"code":9617,"language":9618,"meta":57,"style":57},"language-scss shiki shiki-themes material-theme-ocean",".p-project{\n    font-size:20px;\n\n    @media screen and (max-width: 399px){\n        font-size:10px;\n    } \n}\n","scss",[25,9620,9621,9630,9642,9646,9670,9682,9688],{"__ignoreMap":57},[193,9622,9623,9625,9628],{"class":195,"line":196},[193,9624,1186],{"class":1002},[193,9626,9627],{"class":3254},"p-project",[193,9629,233],{"class":1002},[193,9631,9632,9635,9637,9640],{"class":195,"line":93},[193,9633,9634],{"class":4273},"    font-size",[193,9636,1018],{"class":1002},[193,9638,9639],{"class":1021},"20px",[193,9641,1192],{"class":1002},[193,9643,9644],{"class":195,"line":90},[193,9645,476],{"emptyLinePlaceholder":101},[193,9647,9648,9651,9654,9657,9659,9662,9664,9667],{"class":195,"line":212},[193,9649,9650],{"class":1938},"    @media",[193,9652,9653],{"class":998}," screen ",[193,9655,9656],{"class":1002},"and",[193,9658,6437],{"class":1002},[193,9660,9661],{"class":3254},"max-width",[193,9663,1018],{"class":1002},[193,9665,9666],{"class":1021}," 399px",[193,9668,9669],{"class":1002},"){\n",[193,9671,9672,9675,9677,9680],{"class":195,"line":218},[193,9673,9674],{"class":4273},"        font-size",[193,9676,1018],{"class":1002},[193,9678,9679],{"class":1021},"10px",[193,9681,1192],{"class":1002},[193,9683,9684,9686],{"class":195,"line":224},[193,9685,2903],{"class":1002},[193,9687,5204],{"class":998},[193,9689,9690],{"class":195,"line":230},[193,9691,274],{"class":1002},[13,9693,9694],{},"cssの場合はメディアクエリでクラスを囲む必要ありますが、sassは対象のクラスでラップするだけで有効なのでかなり便利です。ただしメディアクエリの記述が長いこと、ブレークポイントの数値・変数を入れるのが面倒なので以下のようなmixinを作成します。",[49,9696,9698],{"className":9616,"code":9697,"language":9618,"meta":57,"style":57},"$sm-point:400;\n$md-point:600;\n$lg-point:1000;\n$xl-point:1300;\n\n$breakpoint-up: (\n  'sm': 'screen and (min-width: #{$sm-point}px)',\n  'md': 'screen and (min-width: #{$md-point}px)',\n  'lg': 'screen and (min-width: #{$lg-point}px)',\n  'xl': 'screen and (min-width: #{$xl-point}px)',\n) !default;\n\n$breakpoint-down: (\n  'sm': 'screen and (max-width: #{$sm-point - 1}px)',\n  'md': 'screen and (max-width: #{$md-point - 1}px)',\n  'lg': 'screen and (max-width: #{$lg-point - 1}px)',\n  'xl': 'screen and (max-width: #{$xl-point - 1}px)',\n) !default;\n\n$breakpoint-only: (\n  'sm': 'screen and (max-width: #{$sm-point - 1}px)',\n  'md-sm': 'screen and (max-width: #{$md-point - 1}px) and (min-width: #{$sm-point}px)',\n  'lg-md': 'screen and (max-width: #{$lg-point - 1}px) and (min-width: #{$md-point}px)',\n  'xl-lg': 'screen and (max-width: #{$xl-point - 1}px) and (min-width: #{$lg-point}px)',\n  'xl': 'screen and (min-width: #{$xl-point}px)',\n) !default;\n\n\u002F*\nsm  =>  スマホ\nmd  =>  タブレット\nlg  =>  PC\nxl  =>  でかいPC\n*\u002F\n\n@mixin mq-up($breakpoint: md) {\n  @media #{map-get($breakpoint-up, $breakpoint)} {\n    @content;\n  }\n}\n\n@mixin mq-down($breakpoint: md) {\n  @media #{map-get($breakpoint-down, $breakpoint)} {\n    @content;\n  }\n}\n\n@mixin mq-only($breakpoint: md-sm) {\n  @media #{map-get($breakpoint-only, $breakpoint)} {\n    @content;\n  }\n}\n",[25,9699,9700,9712,9724,9736,9748,9752,9762,9794,9820,9847,9874,9883,9887,9896,9928,9959,9990,10021,10029,10033,10042,10072,10112,10151,10190,10216,10224,10228,10233,10238,10243,10248,10253,10257,10261,10283,10308,10315,10319,10323,10327,10346,10366,10372,10376,10380,10384,10404,10424,10430,10434],{"__ignoreMap":57},[193,9701,9702,9705,9707,9710],{"class":195,"line":196},[193,9703,9704],{"class":998},"$sm-point",[193,9706,1018],{"class":1002},[193,9708,9709],{"class":1021},"400",[193,9711,1192],{"class":1002},[193,9713,9714,9717,9719,9722],{"class":195,"line":93},[193,9715,9716],{"class":998},"$md-point",[193,9718,1018],{"class":1002},[193,9720,9721],{"class":1021},"600",[193,9723,1192],{"class":1002},[193,9725,9726,9729,9731,9734],{"class":195,"line":90},[193,9727,9728],{"class":998},"$lg-point",[193,9730,1018],{"class":1002},[193,9732,9733],{"class":1021},"1000",[193,9735,1192],{"class":1002},[193,9737,9738,9741,9743,9746],{"class":195,"line":212},[193,9739,9740],{"class":998},"$xl-point",[193,9742,1018],{"class":1002},[193,9744,9745],{"class":1021},"1300",[193,9747,1192],{"class":1002},[193,9749,9750],{"class":195,"line":218},[193,9751,476],{"emptyLinePlaceholder":101},[193,9753,9754,9757,9759],{"class":195,"line":224},[193,9755,9756],{"class":998},"$breakpoint-up",[193,9758,1018],{"class":1002},[193,9760,9761],{"class":1002}," (\n",[193,9763,9764,9767,9770,9772,9775,9777,9780,9783,9785,9787,9790,9792],{"class":195,"line":230},[193,9765,9766],{"class":1002},"  '",[193,9768,9769],{"class":1035},"sm",[193,9771,2824],{"class":1002},[193,9773,9774],{"class":998},": ",[193,9776,2824],{"class":1002},[193,9778,9779],{"class":1035},"screen and (min-width: ",[193,9781,9782],{"class":1002},"#{",[193,9784,9704],{"class":998},[193,9786,1402],{"class":1002},[193,9788,9789],{"class":1035},"px)",[193,9791,2824],{"class":1002},[193,9793,2579],{"class":1002},[193,9795,9796,9798,9800,9802,9804,9806,9808,9810,9812,9814,9816,9818],{"class":195,"line":236},[193,9797,9766],{"class":1002},[193,9799,98],{"class":1035},[193,9801,2824],{"class":1002},[193,9803,9774],{"class":998},[193,9805,2824],{"class":1002},[193,9807,9779],{"class":1035},[193,9809,9782],{"class":1002},[193,9811,9716],{"class":998},[193,9813,1402],{"class":1002},[193,9815,9789],{"class":1035},[193,9817,2824],{"class":1002},[193,9819,2579],{"class":1002},[193,9821,9822,9824,9827,9829,9831,9833,9835,9837,9839,9841,9843,9845],{"class":195,"line":242},[193,9823,9766],{"class":1002},[193,9825,9826],{"class":1035},"lg",[193,9828,2824],{"class":1002},[193,9830,9774],{"class":998},[193,9832,2824],{"class":1002},[193,9834,9779],{"class":1035},[193,9836,9782],{"class":1002},[193,9838,9728],{"class":998},[193,9840,1402],{"class":1002},[193,9842,9789],{"class":1035},[193,9844,2824],{"class":1002},[193,9846,2579],{"class":1002},[193,9848,9849,9851,9854,9856,9858,9860,9862,9864,9866,9868,9870,9872],{"class":195,"line":248},[193,9850,9766],{"class":1002},[193,9852,9853],{"class":1035},"xl",[193,9855,2824],{"class":1002},[193,9857,9774],{"class":998},[193,9859,2824],{"class":1002},[193,9861,9779],{"class":1035},[193,9863,9782],{"class":1002},[193,9865,9740],{"class":998},[193,9867,1402],{"class":1002},[193,9869,9789],{"class":1035},[193,9871,2824],{"class":1002},[193,9873,2579],{"class":1002},[193,9875,9876,9878,9881],{"class":195,"line":254},[193,9877,1950],{"class":1002},[193,9879,9880],{"class":1021}," !default",[193,9882,1192],{"class":1002},[193,9884,9885],{"class":195,"line":259},[193,9886,476],{"emptyLinePlaceholder":101},[193,9888,9889,9892,9894],{"class":195,"line":265},[193,9890,9891],{"class":998},"$breakpoint-down",[193,9893,1018],{"class":1002},[193,9895,9761],{"class":1002},[193,9897,9898,9900,9902,9904,9906,9908,9911,9913,9916,9918,9920,9922,9924,9926],{"class":195,"line":271},[193,9899,9766],{"class":1002},[193,9901,9769],{"class":1035},[193,9903,2824],{"class":1002},[193,9905,9774],{"class":998},[193,9907,2824],{"class":1002},[193,9909,9910],{"class":1035},"screen and (max-width: ",[193,9912,9782],{"class":1002},[193,9914,9915],{"class":998},"$sm-point ",[193,9917,6317],{"class":1002},[193,9919,4730],{"class":1021},[193,9921,1402],{"class":1002},[193,9923,9789],{"class":1035},[193,9925,2824],{"class":1002},[193,9927,2579],{"class":1002},[193,9929,9930,9932,9934,9936,9938,9940,9942,9944,9947,9949,9951,9953,9955,9957],{"class":195,"line":600},[193,9931,9766],{"class":1002},[193,9933,98],{"class":1035},[193,9935,2824],{"class":1002},[193,9937,9774],{"class":998},[193,9939,2824],{"class":1002},[193,9941,9910],{"class":1035},[193,9943,9782],{"class":1002},[193,9945,9946],{"class":998},"$md-point ",[193,9948,6317],{"class":1002},[193,9950,4730],{"class":1021},[193,9952,1402],{"class":1002},[193,9954,9789],{"class":1035},[193,9956,2824],{"class":1002},[193,9958,2579],{"class":1002},[193,9960,9961,9963,9965,9967,9969,9971,9973,9975,9978,9980,9982,9984,9986,9988],{"class":195,"line":606},[193,9962,9766],{"class":1002},[193,9964,9826],{"class":1035},[193,9966,2824],{"class":1002},[193,9968,9774],{"class":998},[193,9970,2824],{"class":1002},[193,9972,9910],{"class":1035},[193,9974,9782],{"class":1002},[193,9976,9977],{"class":998},"$lg-point ",[193,9979,6317],{"class":1002},[193,9981,4730],{"class":1021},[193,9983,1402],{"class":1002},[193,9985,9789],{"class":1035},[193,9987,2824],{"class":1002},[193,9989,2579],{"class":1002},[193,9991,9992,9994,9996,9998,10000,10002,10004,10006,10009,10011,10013,10015,10017,10019],{"class":195,"line":612},[193,9993,9766],{"class":1002},[193,9995,9853],{"class":1035},[193,9997,2824],{"class":1002},[193,9999,9774],{"class":998},[193,10001,2824],{"class":1002},[193,10003,9910],{"class":1035},[193,10005,9782],{"class":1002},[193,10007,10008],{"class":998},"$xl-point ",[193,10010,6317],{"class":1002},[193,10012,4730],{"class":1021},[193,10014,1402],{"class":1002},[193,10016,9789],{"class":1035},[193,10018,2824],{"class":1002},[193,10020,2579],{"class":1002},[193,10022,10023,10025,10027],{"class":195,"line":618},[193,10024,1950],{"class":1002},[193,10026,9880],{"class":1021},[193,10028,1192],{"class":1002},[193,10030,10031],{"class":195,"line":624},[193,10032,476],{"emptyLinePlaceholder":101},[193,10034,10035,10038,10040],{"class":195,"line":630},[193,10036,10037],{"class":998},"$breakpoint-only",[193,10039,1018],{"class":1002},[193,10041,9761],{"class":1002},[193,10043,10044,10046,10048,10050,10052,10054,10056,10058,10060,10062,10064,10066,10068,10070],{"class":195,"line":636},[193,10045,9766],{"class":1002},[193,10047,9769],{"class":1035},[193,10049,2824],{"class":1002},[193,10051,9774],{"class":998},[193,10053,2824],{"class":1002},[193,10055,9910],{"class":1035},[193,10057,9782],{"class":1002},[193,10059,9915],{"class":998},[193,10061,6317],{"class":1002},[193,10063,4730],{"class":1021},[193,10065,1402],{"class":1002},[193,10067,9789],{"class":1035},[193,10069,2824],{"class":1002},[193,10071,2579],{"class":1002},[193,10073,10074,10076,10079,10081,10083,10085,10087,10089,10091,10093,10095,10097,10100,10102,10104,10106,10108,10110],{"class":195,"line":642},[193,10075,9766],{"class":1002},[193,10077,10078],{"class":1035},"md-sm",[193,10080,2824],{"class":1002},[193,10082,9774],{"class":998},[193,10084,2824],{"class":1002},[193,10086,9910],{"class":1035},[193,10088,9782],{"class":1002},[193,10090,9946],{"class":998},[193,10092,6317],{"class":1002},[193,10094,4730],{"class":1021},[193,10096,1402],{"class":1002},[193,10098,10099],{"class":1035},"px) and (min-width: ",[193,10101,9782],{"class":1002},[193,10103,9704],{"class":998},[193,10105,1402],{"class":1002},[193,10107,9789],{"class":1035},[193,10109,2824],{"class":1002},[193,10111,2579],{"class":1002},[193,10113,10114,10116,10119,10121,10123,10125,10127,10129,10131,10133,10135,10137,10139,10141,10143,10145,10147,10149],{"class":195,"line":648},[193,10115,9766],{"class":1002},[193,10117,10118],{"class":1035},"lg-md",[193,10120,2824],{"class":1002},[193,10122,9774],{"class":998},[193,10124,2824],{"class":1002},[193,10126,9910],{"class":1035},[193,10128,9782],{"class":1002},[193,10130,9977],{"class":998},[193,10132,6317],{"class":1002},[193,10134,4730],{"class":1021},[193,10136,1402],{"class":1002},[193,10138,10099],{"class":1035},[193,10140,9782],{"class":1002},[193,10142,9716],{"class":998},[193,10144,1402],{"class":1002},[193,10146,9789],{"class":1035},[193,10148,2824],{"class":1002},[193,10150,2579],{"class":1002},[193,10152,10153,10155,10158,10160,10162,10164,10166,10168,10170,10172,10174,10176,10178,10180,10182,10184,10186,10188],{"class":195,"line":654},[193,10154,9766],{"class":1002},[193,10156,10157],{"class":1035},"xl-lg",[193,10159,2824],{"class":1002},[193,10161,9774],{"class":998},[193,10163,2824],{"class":1002},[193,10165,9910],{"class":1035},[193,10167,9782],{"class":1002},[193,10169,10008],{"class":998},[193,10171,6317],{"class":1002},[193,10173,4730],{"class":1021},[193,10175,1402],{"class":1002},[193,10177,10099],{"class":1035},[193,10179,9782],{"class":1002},[193,10181,9728],{"class":998},[193,10183,1402],{"class":1002},[193,10185,9789],{"class":1035},[193,10187,2824],{"class":1002},[193,10189,2579],{"class":1002},[193,10191,10192,10194,10196,10198,10200,10202,10204,10206,10208,10210,10212,10214],{"class":195,"line":660},[193,10193,9766],{"class":1002},[193,10195,9853],{"class":1035},[193,10197,2824],{"class":1002},[193,10199,9774],{"class":998},[193,10201,2824],{"class":1002},[193,10203,9779],{"class":1035},[193,10205,9782],{"class":1002},[193,10207,9740],{"class":998},[193,10209,1402],{"class":1002},[193,10211,9789],{"class":1035},[193,10213,2824],{"class":1002},[193,10215,2579],{"class":1002},[193,10217,10218,10220,10222],{"class":195,"line":666},[193,10219,1950],{"class":1002},[193,10221,9880],{"class":1021},[193,10223,1192],{"class":1002},[193,10225,10226],{"class":195,"line":672},[193,10227,476],{"emptyLinePlaceholder":101},[193,10229,10230],{"class":195,"line":678},[193,10231,10232],{"class":1136},"\u002F*\n",[193,10234,10235],{"class":195,"line":684},[193,10236,10237],{"class":1136},"sm  =>  スマホ\n",[193,10239,10240],{"class":195,"line":690},[193,10241,10242],{"class":1136},"md  =>  タブレット\n",[193,10244,10245],{"class":195,"line":696},[193,10246,10247],{"class":1136},"lg  =>  PC\n",[193,10249,10250],{"class":195,"line":702},[193,10251,10252],{"class":1136},"xl  =>  でかいPC\n",[193,10254,10255],{"class":195,"line":708},[193,10256,221],{"class":1136},[193,10258,10259],{"class":195,"line":714},[193,10260,476],{"emptyLinePlaceholder":101},[193,10262,10263,10266,10269,10271,10274,10276,10279,10281],{"class":195,"line":720},[193,10264,10265],{"class":1938},"@mixin",[193,10267,10268],{"class":1206}," mq-up",[193,10270,1925],{"class":1002},[193,10272,10273],{"class":998},"$breakpoint",[193,10275,1018],{"class":1002},[193,10277,10278],{"class":998}," md",[193,10280,1950],{"class":1002},[193,10282,2534],{"class":1002},[193,10284,10285,10288,10291,10294,10296,10298,10300,10303,10306],{"class":195,"line":726},[193,10286,10287],{"class":1938},"  @media",[193,10289,10290],{"class":1002}," #{",[193,10292,10293],{"class":1206},"map-get",[193,10295,1925],{"class":1002},[193,10297,9756],{"class":998},[193,10299,28],{"class":1002},[193,10301,10302],{"class":998}," $breakpoint",[193,10304,10305],{"class":1002},")}",[193,10307,2534],{"class":1002},[193,10309,10310,10313],{"class":195,"line":731},[193,10311,10312],{"class":1938},"    @content",[193,10314,1192],{"class":1002},[193,10316,10317],{"class":195,"line":737},[193,10318,9036],{"class":1002},[193,10320,10321],{"class":195,"line":742},[193,10322,274],{"class":1002},[193,10324,10325],{"class":195,"line":747},[193,10326,476],{"emptyLinePlaceholder":101},[193,10328,10329,10331,10334,10336,10338,10340,10342,10344],{"class":195,"line":752},[193,10330,10265],{"class":1938},[193,10332,10333],{"class":1206}," mq-down",[193,10335,1925],{"class":1002},[193,10337,10273],{"class":998},[193,10339,1018],{"class":1002},[193,10341,10278],{"class":998},[193,10343,1950],{"class":1002},[193,10345,2534],{"class":1002},[193,10347,10348,10350,10352,10354,10356,10358,10360,10362,10364],{"class":195,"line":757},[193,10349,10287],{"class":1938},[193,10351,10290],{"class":1002},[193,10353,10293],{"class":1206},[193,10355,1925],{"class":1002},[193,10357,9891],{"class":998},[193,10359,28],{"class":1002},[193,10361,10302],{"class":998},[193,10363,10305],{"class":1002},[193,10365,2534],{"class":1002},[193,10367,10368,10370],{"class":195,"line":762},[193,10369,10312],{"class":1938},[193,10371,1192],{"class":1002},[193,10373,10374],{"class":195,"line":767},[193,10375,9036],{"class":1002},[193,10377,10378],{"class":195,"line":772},[193,10379,274],{"class":1002},[193,10381,10382],{"class":195,"line":777},[193,10383,476],{"emptyLinePlaceholder":101},[193,10385,10386,10388,10391,10393,10395,10397,10400,10402],{"class":195,"line":782},[193,10387,10265],{"class":1938},[193,10389,10390],{"class":1206}," mq-only",[193,10392,1925],{"class":1002},[193,10394,10273],{"class":998},[193,10396,1018],{"class":1002},[193,10398,10399],{"class":998}," md-sm",[193,10401,1950],{"class":1002},[193,10403,2534],{"class":1002},[193,10405,10406,10408,10410,10412,10414,10416,10418,10420,10422],{"class":195,"line":787},[193,10407,10287],{"class":1938},[193,10409,10290],{"class":1002},[193,10411,10293],{"class":1206},[193,10413,1925],{"class":1002},[193,10415,10037],{"class":998},[193,10417,28],{"class":1002},[193,10419,10302],{"class":998},[193,10421,10305],{"class":1002},[193,10423,2534],{"class":1002},[193,10425,10426,10428],{"class":195,"line":792},[193,10427,10312],{"class":1938},[193,10429,1192],{"class":1002},[193,10431,10432],{"class":195,"line":797},[193,10433,9036],{"class":1002},[193,10435,10436],{"class":195,"line":802},[193,10437,274],{"class":1002},[13,10439,10440],{},"実際に使用する際は以下のようにします。",[49,10442,10444],{"className":9616,"code":10443,"language":9618,"meta":57,"style":57},".test{\n    @include mq-up(xl){\n        \u002F\u002F 1300px以上で有効\n        background-color:blue;\n    }\n\n    @include mq-only(md-sm){\n        \u002F\u002F 599px〜400pxで有効\n        background-color:yellow;\n    }\n\n    \u002F\u002F 1299px ~ 600px, 399px~ で有効\n    background-color:red;\n}\n",[25,10445,10446,10454,10467,10472,10483,10487,10491,10503,10508,10518,10522,10526,10531,10542],{"__ignoreMap":57},[193,10447,10448,10450,10452],{"class":195,"line":196},[193,10449,1186],{"class":1002},[193,10451,2801],{"class":3254},[193,10453,233],{"class":1002},[193,10455,10456,10459,10461,10463,10465],{"class":195,"line":93},[193,10457,10458],{"class":1938},"    @include",[193,10460,10268],{"class":1206},[193,10462,1925],{"class":1002},[193,10464,9853],{"class":998},[193,10466,9669],{"class":1002},[193,10468,10469],{"class":195,"line":90},[193,10470,10471],{"class":1136},"        \u002F\u002F 1300px以上で有効\n",[193,10473,10474,10477,10479,10481],{"class":195,"line":212},[193,10475,10476],{"class":4273},"        background-color",[193,10478,1018],{"class":1002},[193,10480,5716],{"class":998},[193,10482,1192],{"class":1002},[193,10484,10485],{"class":195,"line":218},[193,10486,3968],{"class":1002},[193,10488,10489],{"class":195,"line":224},[193,10490,476],{"emptyLinePlaceholder":101},[193,10492,10493,10495,10497,10499,10501],{"class":195,"line":230},[193,10494,10458],{"class":1938},[193,10496,10390],{"class":1206},[193,10498,1925],{"class":1002},[193,10500,10078],{"class":998},[193,10502,9669],{"class":1002},[193,10504,10505],{"class":195,"line":236},[193,10506,10507],{"class":1136},"        \u002F\u002F 599px〜400pxで有効\n",[193,10509,10510,10512,10514,10516],{"class":195,"line":242},[193,10511,10476],{"class":4273},[193,10513,1018],{"class":1002},[193,10515,5689],{"class":998},[193,10517,1192],{"class":1002},[193,10519,10520],{"class":195,"line":248},[193,10521,3968],{"class":1002},[193,10523,10524],{"class":195,"line":254},[193,10525,476],{"emptyLinePlaceholder":101},[193,10527,10528],{"class":195,"line":259},[193,10529,10530],{"class":1136},"    \u002F\u002F 1299px ~ 600px, 399px~ で有効\n",[193,10532,10533,10536,10538,10540],{"class":195,"line":265},[193,10534,10535],{"class":4273},"    background-color",[193,10537,1018],{"class":1002},[193,10539,5680],{"class":998},[193,10541,1192],{"class":1002},[193,10543,10544],{"class":195,"line":271},[193,10545,274],{"class":1002},[13,10547,10548,10549,10552,10553,10556,10557,10560],{},"このようにメディアクエリをかなり短く記述できます。引数を指定するだけなので直感的ですし、変数でサイズを定義しているので変更もしやすいです。",[25,10550,10551],{},"mq-up","、",[25,10554,10555],{},"mq-down","はあるブレークポイント以上・以下で働くメディアクエリですが、",[25,10558,10559],{},"mq-only","は指定したメディアクエリ間のみ作用します。このメディアクエリmixinはかなり役に立ち、プロジェクトセットアップ時に毎回やっています。",[17,10562,10563],{"id":10563},"カラーパターンクラス",[13,10565,10566,10567,10570,10571,10574,10575,10578],{},"Bootstrapのボタンクラスで",[25,10568,10569],{},"btn btn-danger","とすると赤い色のボタンになります。",[25,10572,10573],{},"warning","なら黄色、",[25,10576,10577],{},"danger","なら赤色といった具合に色の設定をして、その色のクラスがあればその色にするクラスを作成するmixinです。まずは色をmapで定義します。",[49,10580,10582],{"className":9616,"code":10581,"language":9618,"meta":57,"style":57},"$colors:(\n    \"red\"   :#E60012,\n    \"orange\":#F39800,\n    \"yellow\":#FFF100,\n    \"green\" :#009944,\n    \"blue\"  :#0068B7,\n    \"purple\":#920783,\n);\n$default-color:map-get($colors,\"red\");\n",[25,10583,10584,10592,10610,10627,10644,10662,10680,10697,10702],{"__ignoreMap":57},[193,10585,10586,10589],{"class":195,"line":196},[193,10587,10588],{"class":998},"$colors",[193,10590,10591],{"class":1002},":(\n",[193,10593,10594,10596,10598,10600,10603,10605,10608],{"class":195,"line":93},[193,10595,8939],{"class":1002},[193,10597,5680],{"class":1035},[193,10599,1032],{"class":1002},[193,10601,10602],{"class":998},"   :",[193,10604,4317],{"class":1002},[193,10606,10607],{"class":998},"E60012",[193,10609,2579],{"class":1002},[193,10611,10612,10614,10616,10618,10620,10622,10625],{"class":195,"line":90},[193,10613,8939],{"class":1002},[193,10615,5707],{"class":1035},[193,10617,1032],{"class":1002},[193,10619,1018],{"class":998},[193,10621,4317],{"class":1002},[193,10623,10624],{"class":998},"F39800",[193,10626,2579],{"class":1002},[193,10628,10629,10631,10633,10635,10637,10639,10642],{"class":195,"line":212},[193,10630,8939],{"class":1002},[193,10632,5689],{"class":1035},[193,10634,1032],{"class":1002},[193,10636,1018],{"class":998},[193,10638,4317],{"class":1002},[193,10640,10641],{"class":998},"FFF100",[193,10643,2579],{"class":1002},[193,10645,10646,10648,10650,10652,10655,10657,10660],{"class":195,"line":218},[193,10647,8939],{"class":1002},[193,10649,5698],{"class":1035},[193,10651,1032],{"class":1002},[193,10653,10654],{"class":998}," :",[193,10656,4317],{"class":1002},[193,10658,10659],{"class":998},"009944",[193,10661,2579],{"class":1002},[193,10663,10664,10666,10668,10670,10673,10675,10678],{"class":195,"line":224},[193,10665,8939],{"class":1002},[193,10667,5716],{"class":1035},[193,10669,1032],{"class":1002},[193,10671,10672],{"class":998},"  :",[193,10674,4317],{"class":1002},[193,10676,10677],{"class":998},"0068B7",[193,10679,2579],{"class":1002},[193,10681,10682,10684,10686,10688,10690,10692,10695],{"class":195,"line":230},[193,10683,8939],{"class":1002},[193,10685,5725],{"class":1035},[193,10687,1032],{"class":1002},[193,10689,1018],{"class":998},[193,10691,4317],{"class":1002},[193,10693,10694],{"class":998},"920783",[193,10696,2579],{"class":1002},[193,10698,10699],{"class":195,"line":236},[193,10700,10701],{"class":1002},");\n",[193,10703,10704,10707,10709,10711,10713,10715,10717,10719,10721,10723],{"class":195,"line":242},[193,10705,10706],{"class":998},"$default-color",[193,10708,1018],{"class":1002},[193,10710,10293],{"class":1206},[193,10712,1925],{"class":1002},[193,10714,10588],{"class":998},[193,10716,28],{"class":1002},[193,10718,1032],{"class":1002},[193,10720,5680],{"class":1035},[193,10722,1032],{"class":1002},[193,10724,10701],{"class":1002},[13,10726,10727],{},"そしてボタンのクラスがあるとします。",[49,10729,10731],{"className":9616,"code":10730,"language":9618,"meta":57,"style":57},".btn{\n    background-color:$default-color;\n    border:1px solid;\n    border-color:darken($default-color,15%);\n    border-radius:5px;\n    padding:10px;\n    text-align:center;\n\n    @each $key, $color in $colors {\n        &-#{$key}{\n            background-color:$color;\n            border-color:darken($color,15%);\n        }\n    }\n}\n",[25,10732,10733,10742,10752,10767,10788,10799,10809,10821,10825,10841,10849,10861,10880,10884,10888],{"__ignoreMap":57},[193,10734,10735,10737,10740],{"class":195,"line":196},[193,10736,1186],{"class":1002},[193,10738,10739],{"class":3254},"btn",[193,10741,233],{"class":1002},[193,10743,10744,10746,10748,10750],{"class":195,"line":93},[193,10745,10535],{"class":4273},[193,10747,1018],{"class":1002},[193,10749,10706],{"class":998},[193,10751,1192],{"class":1002},[193,10753,10754,10757,10759,10762,10765],{"class":195,"line":90},[193,10755,10756],{"class":4273},"    border",[193,10758,1018],{"class":1002},[193,10760,10761],{"class":1021},"1px",[193,10763,10764],{"class":998}," solid",[193,10766,1192],{"class":1002},[193,10768,10769,10772,10774,10777,10779,10781,10783,10786],{"class":195,"line":212},[193,10770,10771],{"class":4273},"    border-color",[193,10773,1018],{"class":1002},[193,10775,10776],{"class":1206},"darken",[193,10778,1925],{"class":1002},[193,10780,10706],{"class":998},[193,10782,28],{"class":1002},[193,10784,10785],{"class":1021},"15%",[193,10787,10701],{"class":1002},[193,10789,10790,10792,10794,10797],{"class":195,"line":218},[193,10791,4636],{"class":4273},[193,10793,1018],{"class":1002},[193,10795,10796],{"class":1021},"5px",[193,10798,1192],{"class":1002},[193,10800,10801,10803,10805,10807],{"class":195,"line":224},[193,10802,4286],{"class":4273},[193,10804,1018],{"class":1002},[193,10806,9679],{"class":1021},[193,10808,1192],{"class":1002},[193,10810,10811,10814,10816,10819],{"class":195,"line":230},[193,10812,10813],{"class":4273},"    text-align",[193,10815,1018],{"class":1002},[193,10817,10818],{"class":998},"center",[193,10820,1192],{"class":1002},[193,10822,10823],{"class":195,"line":236},[193,10824,476],{"emptyLinePlaceholder":101},[193,10826,10827,10830,10833,10836,10839],{"class":195,"line":242},[193,10828,10829],{"class":1938},"    @each",[193,10831,10832],{"class":998}," $key, $color ",[193,10834,10835],{"class":1938},"in",[193,10837,10838],{"class":998}," $colors ",[193,10840,233],{"class":1002},[193,10842,10843,10846],{"class":195,"line":248},[193,10844,10845],{"class":3254},"        &",[193,10847,10848],{"class":1002},"-#{$key}{\n",[193,10850,10851,10854,10856,10859],{"class":195,"line":254},[193,10852,10853],{"class":4273},"            background-color",[193,10855,1018],{"class":1002},[193,10857,10858],{"class":998},"$color",[193,10860,1192],{"class":1002},[193,10862,10863,10866,10868,10870,10872,10874,10876,10878],{"class":195,"line":259},[193,10864,10865],{"class":4273},"            border-color",[193,10867,1018],{"class":1002},[193,10869,10776],{"class":1206},[193,10871,1925],{"class":1002},[193,10873,10858],{"class":998},[193,10875,28],{"class":1002},[193,10877,10785],{"class":1021},[193,10879,10701],{"class":1002},[193,10881,10882],{"class":195,"line":265},[193,10883,3806],{"class":1002},[193,10885,10886],{"class":195,"line":271},[193,10887,3968],{"class":1002},[193,10889,10890],{"class":195,"line":600},[193,10891,274],{"class":1002},[13,10893,10894],{},"こうすると",[49,10896,10898],{"className":4257,"code":10897,"language":4259,"meta":57,"style":57},".btn {\n  background-color: #E60012;\n  border: 1px solid;\n  border-color: #9a000c;\n  border-radius: 5px;\n  padding: 10px;\n  text-align: center; }\n  .btn-red {\n    background-color: #E60012;\n    border-color: #9a000c; }\n  .btn-orange {\n    background-color: #F39800;\n    border-color: #a76800; }\n  .btn-yellow {\n    background-color: #FFF100;\n    border-color: #b3a900; }\n  .btn-green {\n    background-color: #009944;\n    border-color: #004d22; }\n  .btn-blue {\n    background-color: #0068B7;\n    border-color: #003d6b; }\n  .btn-purple {\n    background-color: #920783;\n    border-color: #490442; }\n",[25,10899,10900,10908,10921,10935,10949,10960,10971,10987,10997,11009,11023,11032,11044,11059,11068,11080,11095,11104,11116,11131,11140,11152,11167,11176,11188],{"__ignoreMap":57},[193,10901,10902,10904,10906],{"class":195,"line":196},[193,10903,1186],{"class":1002},[193,10905,10739],{"class":3254},[193,10907,2534],{"class":1002},[193,10909,10910,10913,10915,10917,10919],{"class":195,"line":93},[193,10911,10912],{"class":4273},"  background-color",[193,10914,1018],{"class":1002},[193,10916,4626],{"class":1002},[193,10918,10607],{"class":998},[193,10920,1192],{"class":1002},[193,10922,10923,10926,10928,10931,10933],{"class":195,"line":90},[193,10924,10925],{"class":4273},"  border",[193,10927,1018],{"class":1002},[193,10929,10930],{"class":1021}," 1px",[193,10932,10764],{"class":998},[193,10934,1192],{"class":1002},[193,10936,10937,10940,10942,10944,10947],{"class":195,"line":212},[193,10938,10939],{"class":4273},"  border-color",[193,10941,1018],{"class":1002},[193,10943,4626],{"class":1002},[193,10945,10946],{"class":998},"9a000c",[193,10948,1192],{"class":1002},[193,10950,10951,10954,10956,10958],{"class":195,"line":218},[193,10952,10953],{"class":4273},"  border-radius",[193,10955,1018],{"class":1002},[193,10957,4566],{"class":1021},[193,10959,1192],{"class":1002},[193,10961,10962,10965,10967,10969],{"class":195,"line":224},[193,10963,10964],{"class":4273},"  padding",[193,10966,1018],{"class":1002},[193,10968,4569],{"class":1021},[193,10970,1192],{"class":1002},[193,10972,10973,10976,10978,10981,10984],{"class":195,"line":230},[193,10974,10975],{"class":4273},"  text-align",[193,10977,1018],{"class":1002},[193,10979,10980],{"class":998}," center",[193,10982,10983],{"class":1002},";",[193,10985,10986],{"class":1002}," }\n",[193,10988,10989,10992,10995],{"class":195,"line":236},[193,10990,10991],{"class":1002},"  .",[193,10993,10994],{"class":3254},"btn-red",[193,10996,2534],{"class":1002},[193,10998,10999,11001,11003,11005,11007],{"class":195,"line":242},[193,11000,10535],{"class":4273},[193,11002,1018],{"class":1002},[193,11004,4626],{"class":1002},[193,11006,10607],{"class":998},[193,11008,1192],{"class":1002},[193,11010,11011,11013,11015,11017,11019,11021],{"class":195,"line":248},[193,11012,10771],{"class":4273},[193,11014,1018],{"class":1002},[193,11016,4626],{"class":1002},[193,11018,10946],{"class":998},[193,11020,10983],{"class":1002},[193,11022,10986],{"class":1002},[193,11024,11025,11027,11030],{"class":195,"line":254},[193,11026,10991],{"class":1002},[193,11028,11029],{"class":3254},"btn-orange",[193,11031,2534],{"class":1002},[193,11033,11034,11036,11038,11040,11042],{"class":195,"line":259},[193,11035,10535],{"class":4273},[193,11037,1018],{"class":1002},[193,11039,4626],{"class":1002},[193,11041,10624],{"class":998},[193,11043,1192],{"class":1002},[193,11045,11046,11048,11050,11052,11055,11057],{"class":195,"line":265},[193,11047,10771],{"class":4273},[193,11049,1018],{"class":1002},[193,11051,4626],{"class":1002},[193,11053,11054],{"class":998},"a76800",[193,11056,10983],{"class":1002},[193,11058,10986],{"class":1002},[193,11060,11061,11063,11066],{"class":195,"line":271},[193,11062,10991],{"class":1002},[193,11064,11065],{"class":3254},"btn-yellow",[193,11067,2534],{"class":1002},[193,11069,11070,11072,11074,11076,11078],{"class":195,"line":600},[193,11071,10535],{"class":4273},[193,11073,1018],{"class":1002},[193,11075,4626],{"class":1002},[193,11077,10641],{"class":998},[193,11079,1192],{"class":1002},[193,11081,11082,11084,11086,11088,11091,11093],{"class":195,"line":606},[193,11083,10771],{"class":4273},[193,11085,1018],{"class":1002},[193,11087,4626],{"class":1002},[193,11089,11090],{"class":998},"b3a900",[193,11092,10983],{"class":1002},[193,11094,10986],{"class":1002},[193,11096,11097,11099,11102],{"class":195,"line":612},[193,11098,10991],{"class":1002},[193,11100,11101],{"class":3254},"btn-green",[193,11103,2534],{"class":1002},[193,11105,11106,11108,11110,11112,11114],{"class":195,"line":618},[193,11107,10535],{"class":4273},[193,11109,1018],{"class":1002},[193,11111,4626],{"class":1002},[193,11113,10659],{"class":998},[193,11115,1192],{"class":1002},[193,11117,11118,11120,11122,11124,11127,11129],{"class":195,"line":624},[193,11119,10771],{"class":4273},[193,11121,1018],{"class":1002},[193,11123,4626],{"class":1002},[193,11125,11126],{"class":998},"004d22",[193,11128,10983],{"class":1002},[193,11130,10986],{"class":1002},[193,11132,11133,11135,11138],{"class":195,"line":630},[193,11134,10991],{"class":1002},[193,11136,11137],{"class":3254},"btn-blue",[193,11139,2534],{"class":1002},[193,11141,11142,11144,11146,11148,11150],{"class":195,"line":636},[193,11143,10535],{"class":4273},[193,11145,1018],{"class":1002},[193,11147,4626],{"class":1002},[193,11149,10677],{"class":998},[193,11151,1192],{"class":1002},[193,11153,11154,11156,11158,11160,11163,11165],{"class":195,"line":642},[193,11155,10771],{"class":4273},[193,11157,1018],{"class":1002},[193,11159,4626],{"class":1002},[193,11161,11162],{"class":998},"003d6b",[193,11164,10983],{"class":1002},[193,11166,10986],{"class":1002},[193,11168,11169,11171,11174],{"class":195,"line":648},[193,11170,10991],{"class":1002},[193,11172,11173],{"class":3254},"btn-purple",[193,11175,2534],{"class":1002},[193,11177,11178,11180,11182,11184,11186],{"class":195,"line":654},[193,11179,10535],{"class":4273},[193,11181,1018],{"class":1002},[193,11183,4626],{"class":1002},[193,11185,10694],{"class":998},[193,11187,1192],{"class":1002},[193,11189,11190,11192,11194,11196,11199,11201],{"class":195,"line":660},[193,11191,10771],{"class":4273},[193,11193,1018],{"class":1002},[193,11195,4626],{"class":1002},[193,11197,11198],{"class":998},"490442",[193,11200,10983],{"class":1002},[193,11202,10986],{"class":1002},[13,11204,11205],{},"それぞれの色パターンのボタンクラスができました。実際に適用してみると以下の通りです。",[2959,11207],{":src":11208},"'useful-sass-mixins\u002Fsch2021-06-28 22.50.04.png'",[13,11210,11211],{},"mapとeachを使うとカラーパターンのクラスを簡単に実装できます。",[419,11213,11214],{},"html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .s6YsC, html code.shiki .s6YsC{--shiki-default:#B2CCD6}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}",{"title":57,"searchDepth":90,"depth":90,"links":11216},[11217,11218],{"id":9610,"depth":93,"text":9610},{"id":10563,"depth":93,"text":10563},[96],"設定しておきたいmixinと記述週",{},"\u002Farticles\u002Fuseful-sass-mixins",{"title":9585,"description":11220},"articles\u002Fuseful-sass-mixins",[4259],"useful-sass-mixins\u002Fthumbnail.png","ZczNQ4FtkqMbeh7MFTHHTJ3BRi4RWjEA8rwabquN6pI",1780987153753]