- 投稿日:2020-05-20T23:16:26+09:00
PHP&MySQLでデータの個数を数える方法(PDO)
MySQL接続をした後この処理をします。
$sql_form = "SELECT * FROM テーブル名"; $sql_form_result = $PDO -> query($sql_form); $form_row_count = $sql_form_result->rowCount();変数の名前は必要に応じて変えても大丈夫です。
$form_row_countという変数にデータ数が格納されています。
- 投稿日:2020-05-20T23:03:56+09:00
PHPでデータベースの重複を取得するには
<?php $query = $dbh->query("SELECT COUNT(*) FROM formdata WHERE userid = '".$userid."' AND kind = '".$kind."'"); $count = $query->fetchColumn(); if ($count > 0){ ?> <p align="center">投稿が重複しています</p> <?php }else{ // データの追加 $sql = 'INSERT INTO formdata(id, kind, star, message, userid) VALUES("'.$id.'","'.$kind.'","'.$star.'","'.$message.'","'.$userid.'")'; $stmt = $dbh -> prepare($sql); $stmt -> execute(); ?> <p align="center">投稿ありがとうございました。</p>mysqli接続だとfetchColumやprepare関数が使えなくなるのでpdo接続してあります。
2行目は
formdataというテーブルの中に
kindというフィールドがphpの変数kindと同じかつ、useridというフィールドがphpの変数useridと同じデータが
何個あるかカウントしています。4行目のif文で、カウントした個数が0よりも多かった場合に重複した時の処理を出力します。
(ここではhtmlのテキストを出力)10行目では、データが重複しなかったので新たなデータをデータベースに追加します。
id, kind, star, message, useridは追加するデータのフィールド名
- 投稿日:2020-05-20T22:52:38+09:00
phpでひとつ前のページにリダイレクトする方法
header('Location: '.$_SERVER['HTTP_REFERER']); exit;リダイレクトで処理が中断されるのでexit;を書いておきましょう。
- 投稿日:2020-05-20T22:52:38+09:00
PHPでひとつ前のページにリダイレクトする方法
header('Location: '.$_SERVER['HTTP_REFERER']); exit;リダイレクトで処理が中断されるのでexit;を書いておきましょう。
- 投稿日:2020-05-20T22:28:55+09:00
onclickを用いて複数の関数を呼び出す
Onclickで複数の関数を記述する
初心者プログラマーの備忘録です。
記法1:関数をセミコロン(;)で区切る
input type = "XXX" value = "a" onclick = "YYY;ZZZ"
このように、関数をセミコロンで区切って記述した場合、YYY → ZZZの順に関数を実行。
仮にYYY = true, ZZZ = false
であっても、XXXが実行される。
YYY = false, ZZZ = true
の場合は、YYYの結果ではじかれるためXXXは実行されない。記法2:関数をカンマ(,)で区切る
input type = "XXX" value = "a" onclick = "YYY, ZZZ"
基本的にカンマで関数を区切ることはないが、上記のように記述した場合
カンマの右側の関数(ZZZ)の結果がtrue
であれば、YYYの結果に依らずXXXが実行される。記法3:関数を「&&」で区切る
input type = "XXX" value = "a" onclick = "YYY && ZZZ"
このように記述した場合、関数 YYY および ZZZ の結果がともにtrue
であれば、XXXが実行される。おまけ
まだ試していないが、仮に
input type = "XXX" value = "a" onclick = "YYY || ZZZ"
とすれば、YYYあるいはZZZのどちらかの結果がtrue
であれば、XXXが実行されると考えられる。
- 投稿日:2020-05-20T21:44:37+09:00
乱出するCTAリンクの更新にイライラしているLP更新者の方への提案
LPあるある
1ページ中に同じお問い合わせエリア(CTAボタンやら電話番号やら)が複数回でてくる
例えばこんな感じ
LP/index.html:before<body> <section id="sec1"> <div><p>内容1</p></div> </section> <div class="cta"> <div class="tel"> <a href="tel:0123456789">0123-45-6789</a> </div> <div class="link"> <a href="//google.com"><div class="button">お問い合わせはこちら</div></a> </div> </div> <section id="sec2"> <div><p>内容2</p></div> </section> <div class="cta"> <div class="tel"> <a href="tel:0123456789">0123-45-6789</a> </div> <div class="link"> <a href="//google.com"><div class="button">お問い合わせはこちら</div></a> </div> </div> <section id="sec3"> <div><p>内容3</p></div> </section> <div class="cta"> <div class="tel"> <a href="tel:0123456789">0123-45-6789</a> </div> <div class="link"> <a href="//google.com"><div class="button">お問い合わせはこちら</div></a> </div> </div> </body>「どんだけ、お問い合わせエリアで場所とってんねん」って気分になる
視認性も良くないさらに「計測用のクリックイベントを追加して」「電話番号が変わりました」なんて修正依頼もあったり...
いちいち検索して手作業もたいへんだし
エディタで一括置換もできるけど、本当にちゃんと出来てるかも不安だし...なんとか1箇所の変更で済むようにしたい(一括編集したい)
JSに頼ろう
こんな感じにして解決 (JavaScript で HTML を書き換え)
LP/index.html:after<body> <section id="sec1"> <div><p>内容1</p></div> </section> <div class="cta"></div> <!-- ← ココにお問い合わせ表示 --> <section id="sec2"> <div><p>内容2</p></div> </section> <div class="cta"></div> <!-- ← ココにお問い合わせ表示 --> <section id="sec3"> <div><p>内容3</p></div> </section> <div class="cta"></div> <!-- ← ココにお問い合わせ表示 --> </body> <!-- 表示させるお問い合わせのコード --> <script id="cta_code" type="text/html"> // ココから <div class="tel"> <a href="tel:0123456789">0123-45-6789</a> </div> <div class="link"> <a href="//google.com"><div class="button">お問い合わせはこちら</div></a> </div> // ココまで </script> <!-- END 表示させるお問い合わせのコード --> <!-- .cta にコードを入れるスクリプト --> <script type="text/javascript"> var code = document.getElementById("cta_code").innerHTML; // 上記の「表示させるお問い合わせのコード」がつまった #cta_code を格納 var cta = document.querySelectorAll(".cta"); // ソース中から .cta を見つけて格納 var arr = Array.prototype.slice.call(cta); // forEach が使えるように配列に arr.forEach(function (e) { e.innerHTML = code; // 入れ替え実施 }); </script> <!-- END .cta にコードを入れるスクリプト -->解説
1)お問い合わせエリアに
お問い合わせを入れたい部分に
<div class="cta"></div>
を入れる2)表示させるお問い合わせのコード
// ココから
// ココまで
の間に書き換えたいHTMLを置くポイントは
<script id="cta_code" type="text/html">
の部分
type="text/html"
で、表には表示させないように。(
<div id="cta_code" style="display:none">
でも動くと思うけど、どちらでも)3).cta にコードを入れるスクリプト
Array.forEach()
を使いたい- IE11でも動くようにしたい
ということから
Array.prototype.slice.call()
を使うことに参考サイト:IEで NodeList を forEach するとエラーになる問題の対処方
解決
これで、今後に更新があっても、1箇所だけの修正で対応できます
↑ レンダリングされたあとは冒頭の
LP/index.html:before
と同じソースになってる
- 投稿日:2020-05-20T21:26:25+09:00
PC版ではロゴと検索窓が出て、スマートフォン版では切り替え表示したいなと思ったら・・・
タイトルの通りですが、PC版では検索窓とサイトのロゴを出したいけど、スマホ版ではどちらも出す余裕はありませんが、ハンバーガーデザインに分けることもしたくなかったので作ってみました
コードとデモ
デモ
https://jsfiddle.net/mqgc207L/
コード
CSS部
@media screen and (max-width: 768px) { .SearchWindow__view { display: none; } }サンプルではBootstrap4を使っていることもあり、今回は768pxを区分けしましたが、検索窓に張り付けるクラスをとりあえずスマホとPC版を切り替えたいブレークポイントで非表示と表示に切り替えるようにします。
JS部
const SMP_SEARCH = document.getElementById("SearchWindow"); const SMP_LOGO = document.getElementById("LogoWindow"); const SMP_LINK = document.getElementById("header__btm--icon"); const CLS_SEARCH = 'fas fa-search'; const CLS_CROSS = 'fas fa-times'; const WINDOWS_MD = 768; let flgChenge = true; window.addEventListener('resize', function(e) { //現在のサイズを取得 let nowsize = window.innerWidth; if( (nowsize >= WINDOWS_MD) ){ //基準以上ならリセット display_reset(); SMP_SEARCH.style.display =""; } }); function clickBtn1(){ if(flgChenge){ // 検索窓表示 SMP_LINK.className = CLS_CROSS; $(SMP_LOGO).hide(); $(SMP_SEARCH).show(); $(SMP_SEARCH).removeClass('SearchWindow__view'); flgChenge = false; }else{ // 検索窓非表示 display_reset(); } } function display_reset(){ SMP_LINK.className = CLS_SEARCH; $(SMP_LOGO).show(); $(SMP_SEARCH).hide(); $(SMP_SEARCH).addClass('SearchWindow__view'); flgChenge = true; }起動時にフラグ用引数を用意し、ボタンを操作する度にclickBtn1関数を呼び出して表示・商事を繰り返しますが、PC版ではリセットする必要があるので、 window.addEventListener('resize', function(e) {});でリサイズ時のサイズを算定。所定以上ならリセットを行います。なお、display: block;が残っていると拡大→縮小を繰り返すと最初は隠しておくべき検索窓が表示されるので、SMP_SEARCH.style.display ="";で消しておきます。
<header id="header"> <div class="row" id="header__top"> <div id="LogoWindow" class="col-md-4 col-12"> <h1><a href="#">LOGO</a></h1> </div> <div id = "SearchWindow" class="col-md-8 col-12 SearchWindow__view"> <form id="header__search" action="/" method="get"> <input class="validate" name="search" type="text" autocomplete="off" placeholder="キーワードを入力" > <button type="submit">検索</button> </form> </div> </div> <!--ボタン--> <div id="header__btm"> <div class="d-block d-md-none"> <a href="#" class="text-grey darken-4" onclick="clickBtn1()"> <i id="header__btm--icon" class="fas fa-search" style="font-size:2.0rem;"></i></a> </div> </div>HTMLの本文です。画像サイズによって表示するかどうかを区分けするのは難しく車輪の差発明になるので、ここではBootstrapの表示ユーティリティを多用しています。グリッドシステムのみのCSSが入ったBootsrap Gridにもこのユーティリティは附属しているので活用して頂ければと思います。
- 投稿日:2020-05-20T19:50:17+09:00
herokuでLPを無料で公開する方法
この記事について
htmlファイルをherokuでデプロイしようと思った時、あれ?できない。。。となったので備忘録として手順を振り返りつつ残しておきたいので記事にしました。
参考記事
・HTMLページをHerokuにデプロイ
https://qiita.com/Hai-dozo/items/f0829dd121f477754b98
こちらの記事はとてもわかりやすく書いてます。開発環境
・Mac Pro
・Herokuアカウントがあること
・PHPがローカルにインストールされていること
・Composerがローカルにインストールされていること
・githubにファイル登録済み1.自分のLPファイルにindex.php,package.jsonを追加 以下の内容を入れておく
index.php<?php include_once("index.html"); ?>package.json{}
2.herokuにログイン
heroku login3.herokuでアプリを作成するか追加する、その後確認
heroku create アプリ名 or git remote add heroku 作成したherokuアプリのurl git remote -vorigin と herokuが作成されていたら完了です。
4.gitとherokuにpushする
git add . git commit -m "コメント" git push origin master git push heroku master5.herokuにデプロイされたか確認
heroku ps:scale web=1 heroku openこれで画面が正常にでたら完了です。
6.最後に
以上がhtmlファイルをherokuにアップする備忘録でした。
デプロイ作業はどこがミスしてるかわかりにくいので振り返りに使おうと思います。
- 投稿日:2020-05-20T17:38:53+09:00
リンクの中にリンクを入れたい時は?
リンクの中にリンクを入れたいレイアウト
こんなレイアウ見たことありますよね?
業務でこんなレイアウトで実装しなきゃいけなくて、どうやるか色々と調べたので、まとめようと思います。
aタグの中にaタグを設置して見る
sample.html<a> <p> <a>リンク</a> </p> </a>とレイアウトが、崩れてしまいました。
対策1:Objectタグで囲む
sample.html<a> <p> <object><a>リンク</a></object> </p> </a>objectタグとは?
HTML の 要素は、画像、内部の閲覧コンテキスト、プラグインによって扱われるリソースなどのように扱われる外部リソースを表現します。
リファレンス属性は、HTML5で廃止されたものも多いので注意です。
主要なブラウザには対応しているので、使えそうですね、、、。対策2:JavaScriptのclickイベントを使う
sample.html<a> <p> <span data-url="/link" class="js-click">リンク</span> </p> </a>$('.js-click').on('click', function(event){ //伝播をストップ e.stopPropagation(); e.preventDefault(); //リンクを取得して飛ばす location.href = $(this).attr('data-url'); })引用
ここの実装は、実装環境にもよるので、引用させてもらいました。
location.href を使うって感じです。SEOは大丈夫?
googleサイトをみる限り、jsを読んでくれますが、イベントで生成されるリンクまでを読んでくれるかは不確かです。
調べてみると
- https://www.suzukikenichi.com/blog/content-and-link-generated-by-javascript-are-treated-just-same-as-static-content-and-link/
- https://www.suzukikenichi.com/blog/google-can-read-javascript-and-pass-pagerank-and-anchor-text/
- https://webtan.impress.co.jp/e/2019/10/07/34043#moz16
という記事もあり、レンダリングされるようなリンクであれば読み取ってくれそうですが、、、。
「local.href」はわからないです。aタグの中にaタグを書くのはNG×
リファレンスを読むと許可されている親要素に
記述コンテンツを受け入れるすべての要素、フローコンテンツ を受け入れるすべての要素。ただし 要素を除く。
と書いてあります。
aタグ内でaタグを書くのはよくなさそうですね、、、結局リンクの中にリンクを入れたい時は?
- 最初にレイアウトの変更を考える
のがいいかなーって思います。
リンクの中にリンクをいれると、ユーザが間違ってクリックしてしまう、間違ってタップしてしまう可能性も高いですしね。
- 投稿日:2020-05-20T10:21:30+09:00
マイライブラリ:html基本構造
<!DOCTYPE html> <html lang="ja"> <head> </head> <body> </body> </html>
- 投稿日:2020-05-20T10:01:48+09:00
マイライブラリ:ベースのhtmlファイル
基本構造
headの記述
<head> <meta charset="UTF-8"> <title>HTML文書の基本</title> <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css"> <link rel="stylesheet" href="css/style.css"> <meta name="description" content="文書の説明は検索エンジンの検索結果ページに表示されるため、タイトルと並びSEO上非常に重要です。"> </head>
- 投稿日:2020-05-20T10:01:48+09:00
マイライブラリ:headの記述
headの記述
〇基本セット
<head> <meta charset="UTF-8"> <title>HTML文書の基本</title> <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css"> <link rel="stylesheet" href="css/style.css"> <meta name="description" content="文書の説明は検索エンジンの検索結果ページに表示されるため、タイトルと並びSEO上非常に重要です。"> </head>〇必要に応じて追加
・googleフォント https://fonts.google.com/
フォントを選んでEmbedでソースをコピーして貼り付ける
- 投稿日:2020-05-20T09:34:24+09:00
フォームをGETで送信するときは送信したいパラメータをURLではなくhiddenタグに設定する必要がある、という話
はじめに:イントロダクション
以下のような単純なRailsのフォームがあったとします。
<%= form_tag foo_blogs_path(some_flag: 1) do %> <%= button_tag 'Foo' %> <% end %>コントローラのコードは次のように
some_flag
の値をnoticeに出力するようになっています。class BlogsController < ApplicationController def foo redirect_to :blogs, notice: "Foo / some_flag: #{params[:some_flag]}" end end以下はFooボタンをクリックしたときの実行結果です。
フォームのURLに設定したsome_flag: 1
の値が表示されています。本題:困ったこと
上の例と同じようなことを以下のようなフォームでもやろうとしました。
<%= form_tag bar_blogs_path(some_flag: 1), method: :get do %> <%= button_tag 'Bar' %> <% end %>先ほどのコード例と違うのはフォームのHTTPメソッドがGETになっている点(
method: :get
)です。コントローラ側のコードはほぼ同じです。
class BlogsController < ApplicationController def bar redirect_to :blogs, notice: "Bar / some_flag: #{params[:some_flag]}" end endしかし、Barボタンをクリックしてみると・・・
あれっ、
some_flag
の値が空になってる!ログを見るとこんなふうになっていて
some_flag
の値が渡されていません。Started GET "/blogs/bar?button=" for 127.0.0.1 at 2020-05-20 09:13:49 +0900出力されたHTMLを見てみると、
action="/blogs/bar?some_flag=1"
のようにsome_flag
の値がちゃんと設定されているように見えます。<form action="/blogs/bar?some_flag=1" accept-charset="UTF-8" method="get"> <button name="button" type="submit">Bar</button> </form>なんでだろう、おかしいなあ・・・。
原因を突き止めるためにいろいろ試行錯誤したものの、some_flag
の値をサーバーに送信することができず、この日は諦めて寝ることにしました。「こんな仕様変更、楽勝やわー」と思ってコードをいじったけど、なぜか思い通りに動いてくれず、「たぶんこれが原因かな?」と雑な推測を元にコードを書き換えたけど、それでも動かず、何度か試行錯誤して「うーん、今日はもうダメだな」と仕事を切り上げた。一晩頭を冷やせばきっとすぐ解決するはず!!
— Junichi Ito (伊藤淳一) (@jnchito) May 18, 2020翌日・・・解決しました!
次の日、デバッグを再開したところ、今度は原因と解決策がわかりました。
フォームをGETで送信する場合は、action
のURLではなくhiddenタグに送信したいパラメータを含める必要があるのでした。<%= form_tag bar_blogs_path, method: :get do %> <!-- hiddenタグに送信したいパラメータを含める --> <%= hidden_field_tag :some_flag, 1 %> <%= button_tag 'Bar' %> <% end %>こうすれば
some_flag
の値をサーバーに送信することができます!ログを見ても
some_flag=1
が送信されていることがわかります。Started GET "/blogs/bar?some_flag=1&button=" for 127.0.0.1 at 2020-05-20 09:22:21 +0900これで解決です。めでたしめでたし。
そういえば、昨日困っていた謎の挙動は予想通り「冷えた頭」で見直したら原因が見つかりました✨
— Junichi Ito (伊藤淳一) (@jnchito) May 19, 2020
他の人も僕と同じようにうっかりハマりそうな落とし穴だったので、そのうちQiitaとかに書くかも〜。
- 投稿日:2020-05-20T04:56:48+09:00
初心者によるプログラミング学習ログ 321日目
100日チャレンジの321日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
321日目は、
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) May 19, 2020
321日目 1.5h
・架空LP模写10日目1.5h(@ririru_123
)
・架空LP模写:お問い合わせ部分を作成#早起きチャレンジ#駆け出しエンジニアと繋がりたい#100DaysOfCode
- 投稿日:2020-05-20T04:41:58+09:00
vue.jsとlocalStrageで閲覧履歴とお気に入り履歴を作ってみた
やったこと
ユーザの閲覧履歴やお気に入り履歴をlocal Strageに溜め込んでブラウザ側だけで履歴情報を表示するページを作りました。
中の処理ではVue.jsを使っています。使っているもの / できること
- 犬の画像をランダムで取得するAPI
- 直近5枚の見た画像の履歴を表示
- お気に入りへの追加、およびその削除
動いているページ
http://shima-07.ml/ソースコード
<html> <head> <title>Hello My WebSite!</title> <style> img.pic1 { width: 50%; height: auto; } </style> <style> img.pic2 { width: 96px; height: 65px; } </style> </head> <body> <div id= "app"> <a v-bind:href="src" target="_blank"> <img v-bind:src="src" class="pic1"/> </a> <p><button v-on:click="getData()">次へ</button></p> <p> <button v-if="good" v-on:click="delfavo()">お気に入りから削除する</button> <button v-else v-on:click="favo()">お気に入りに追加する</button> </p> <p>最大5件まで過去閲覧画像を表示</p> <!-- 画像URLが存在するときのみ表示する--> <a v-bind:href="his_1" target="_blank"> <img v-if="his_1" v-bind:src="his_1" class="pic2"/> </a> <a v-bind:href="his_2" target="_blank"> <img v-if="his_2" v-bind:src="his_2" class="pic2"/> </a> <a v-bind:href="his_3" target="_blank" > <img v-if="his_3" v-bind:src="his_3" class="pic2"/> </a> <a v-bind:href="his_4" target="_blank" > <img v-if="his_4" v-bind:src="his_4" class="pic2"/> </a> <a v-bind:href="his_5" target="_blank" > <img v-if="his_5" v-bind:src="his_5" class="pic2"/> </a> <p>お気に入りのわんちゃんを表示</p> <!-- 画像URLが存在するときのみ表示する--> <a v-bind:href="fav_1" target="_blank"> <img v-if="fav_1" v-bind:src="fav_1" class="pic2"/> </a> <a v-bind:href="fav_2" target="_blank"> <img v-if="fav_2" v-bind:src="fav_2" class="pic2"/> </a> <a v-bind:href="fav_3" target="_blank" > <img v-if="fav_3" v-bind:src="fav_3" class="pic2"/> </a> <a v-bind:href="fav_4" target="_blank" > <img v-if="fav_4" v-bind:src="fav_4" class="pic2"/> </a> <a v-bind:href="fav_5" target="_blank" > <img v-if="fav_5" v-bind:src="fav_5" class="pic2"/> </a> <a v-bind:href="fav_6" target="_blank"> <img v-if="fav_6" v-bind:src="fav_6" class="pic2"/> </a> <a v-bind:href="fav_7" target="_blank"> <img v-if="fav_7" v-bind:src="fav_7" class="pic2"/> </a> <a v-bind:href="fav_8" target="_blank" > <img v-if="fav_8" v-bind:src="fav_8" class="pic2"/> </a> <a v-bind:href="fav_9" target="_blank" > <img v-if="fav_9" v-bind:src="fav_9" class="pic2"/> </a> <a v-bind:href="fav_10" target="_blank" > <img v-if="fav_10" v-bind:src="fav_10" class="pic2"/> </a> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> var favlist =[]; var u0,u1,u2,u3,u4,u5,u6; var strage = []; var s = localStorage.getItem('imgs'); /// お気に入りようの配列/// if(localStorage.getItem('fav')){ // JSON.parse(data) の形で取り出す必要がある。 // ocalStorage.getItem('imgs').lengthにすると文字の長さになってしまうからダメ。JSON.parse()する for(let i = 0 ; i < JSON.parse(localStorage.getItem('fav')).length -1 ; i++){ favlist.push(JSON.parse(localStorage.getItem('fav'))[i]); } } /// 過去画像ようの配列//// if(localStorage.getItem('imgs')){ // JSON.parse(data) の形で取り出す必要がある。 // ocalStorage.getItem('imgs').lengthにすると文字の長さになってしまうからダメ。JSON.parse()する for(let k = 0 ; k < JSON.parse(localStorage.getItem('imgs')).length -1 ; k++){ strage.push(JSON.parse(localStorage.getItem('imgs'))[k]); } } ////////// メイン処理 ////////// const app = new Vue({ el: '#app', data: { src:'' , his_1: '', his_2: '', his_3: '', his_4: '', his_5: '', good: false, fav_1: '', fav_2: '', fav_3: '', fav_4: '', fav_5: '', fav_6: '', fav_7: '', fav_8: '', fav_9: '', fav_10: '' }, /// 過去の履歴を出すところ methods: { getData: async function(){ const URL = 'https://dog.ceo/api/breeds/image/random'; const response = await axios.get(URL); this.message = response.data; this.src = response.data.message; // local strageにため込む処理 strage.unshift({url:this.src}); //先頭に追加 // 5こ以上は消す strage = strage.slice(0,6); localStorage.removeItem('imgs'); //imgsだけ消す localStorage.setItem('imgs',JSON.stringify(strage)); // JSON.stringify(data) の形が需要。 console.log(strage); u0 = this.src; // 過去見たものの表示をする if(localStorage.getItem('imgs')){ // エラーを防ぐ為に、過去履歴が存在するときだけ、その分だけ表示する for(let j = 0 ; j < JSON.parse(localStorage.getItem('imgs')).length ; j++){ eval("this.his_"+ j + "= JSON.parse(localStorage.getItem('imgs'))[" + j + "].url"); // 普通に this.his_j = JSON.parse(localStorage.getItem('imgs'))[j].url;とは書けない } } console.log(this.his_1); this.good = false; // 画像が変わったらボタンを変える }, ///お気に入り登録する機能 favo: function(){ this.url = u0; favlist.unshift({url:this.url}); localStorage.setItem('fav',JSON.stringify(favlist)); this.good = true ; console.log(favlist); console.log(this.good); ///表示する if(localStorage.getItem('fav')){ // 存在確認とあまりにお気に入りが多い場合は10個にする var len1 = JSON.parse(localStorage.getItem('fav')).length; if(len1 > 10){ len1 = 10; } // エラーを防ぐ為に、過去履歴が存在するときだけ、その分だけ表示する for(let a = 0 ; a < len1 ; a++){ eval("this.fav_"+ (a+1) + "= JSON.parse(localStorage.getItem('fav'))[" + a + "].url"); // a番目のものをfav_a+1に格納する // 普通に this.his_j = JSON.parse(localStorage.getItem('imgs'))[j].url;とは書けない } } }, /// お気に入りから削除する機能 delfavo: function(){ favlist.shift(); //JSON.parse(localStorage.getItem('fav')).shift(); localStorage.setItem('fav',JSON.stringify(favlist)); this.good = false ; // falseに戻す console.log(favlist); if(localStorage.getItem('fav')){ // 存在確認とあまりにお気に入りが多い場合は10個にする var len2 = JSON.parse(localStorage.getItem('fav')).length; if(len2 > 10){ len2 = 10; } // エラーを防ぐ為に、過去履歴が存在するときだけ、その分だけ表示する for(let b = 0 ; b < len2 ; b++){ eval("this.fav_"+ (b+1) + "= JSON.parse(localStorage.getItem('fav'))[" + b + "].url"); // b番目のものをfav_b+1に格納する // 普通に this.his_j = JSON.parse(localStorage.getItem('imgs'))[j].url;とは書けない } } } }, mounted: function(){ this.getData(); this.favo(); this.delfavo(); } }) </script> </body> </html>
- 投稿日:2020-05-20T00:19:29+09:00
Angularの公式ドキュメントをざっくり読む(はじめてのアプリ~ルーティング)
こんばんは。社会人になりましてフロントエンド周りの勉強を始めまして、
まずAngularというフレームワークを勉強し始めました。
手始めに公式ドキュメントの「入門」の「はじめてのアプリ」から「ルーティング」までを読んでみて、理解したことなどをメモってみました。中の人について
- エンジニアで採用され、まずはフロントエンドの担当に
- 昔pythonは書いていたが、スキル is 低い
- まずはここからということで公式docを読んでる ←イマココ!
という訳で、
Qiitaヤクザ造形の深い皆様は、
「まったく分かってないやん・・・」とキレずにコメントなどで
お手柔らかにご教授くださいませ(わがまま)Angularってなに?
調べた内容をまとめてみました。
- フレームワーク
- 画面まわりを作成する際に便利
- HTML, CSS, JavaScriptの見た目に関する機能に加えてページ移動に関すること(ルーティング)などの機能もある ↑比較ででてくるVueとかReactとかは後者がない模様。
- JavaScriptの上位互換であるTypeScriptが使用されている ↑型の宣言ができる点で上位互換とのこと
といった感じで、すごい便利そう(小並感)
では、実際に読んで分かったことなどをまとめていきます。はじめてのアプリ
基礎が書かれています。が基礎だけにめちゃ大切なことが書かれてます。
分かったこと
- 「プロパティ」・・・ざっくりと変数のこと
- 「属性」・・・ざっくりと数値や文字列のこと。
- 「バインド」・・・プロパティに数値・文字列をいれるようなもの (紐づけてバインドするっていう連想が分かりやすそう)
- インプットとアウトプットの概念
中々理解しづらい感じですが、以下リンクのボタン呼び出し側(親要素)に対して色・形(子要素)を渡す、という例がとてもいい感じ!
Angularの@Input(), @Output()を理解する。
☆インプット:親→子へ属性を渡す & []を使用
☆アウトプット:子から親へ考え(ロジック)を渡す & ()を使用
といった感じ・・・?ルーティング
そもそもルーティングとは複数のページがあるときに、このページにはこのルートで行けば辿りつくよ、という道しるべの情報のこと(ざっくり)
ここからは、実際にコードを書く際にどんな流れなのかを書いてみました。
①コンポーネントを作成
※「コンポーネント」・・・tsファイル, htmlファイル, cssファイル, scssファイルをまとめたもの。
②tsファイル内にpathとコンポーネント名のペアをつくる
こんな感じです。src/app/app.module.ts(公式ドキュメントより引用)RouterModule.forRoot([ { path: '', component: ProductListComponent }, { path: 'products/:productId', component: ProductDetailsComponent }, ])③htmlファイルにリンク先の設定をします。
src/app/product-list/product-list.component.html(公式ドキュメントより引用)<a [title]="product.name + ' details'" [routerLink]="['/products', productId]"> {{ product.name }} </a>ここで、②のpathと、③の[routerLink]の内容が同じになるように設定するようです。
これでルーティングの登録が完了しました。
以後はルーティング情報を使う流れになります。④tsファイルでimportによって各種道具類をもってきます。
src/app/product-details/product-details.component.ts(公式ドキュメントより引用)import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { products } from '../products';importで使えそうなイメージがありますが、以下の⑤を実行しないと使えない?ようです。
イメージとしては、
キャンプ場で金網やトングを借りてきました!(だけど持ってきただけで洗ってないので使えない・・・)みたいな感じかなと思います。⑤tsファイルでexportによってクラス名を定義する
ここでウラス名を定義しますが、②のコンポーネント名と同じな点が重要。
src/app/product-details/product-details.component.ts(公式ドキュメントより引用)//⑤の部分 export class ProductDetailsComponent implements OnInit { product; //⑥の部分 constructor( private route: ActivatedRoute, ) { } }⑥tsファイルでコンストラクタで初期化して使えるようにする
上記コードのconstructorからの部分です。
これによって④で持ってきた道具類を初期化している、とのこと。
キャンプのたとえの場合、金網やトングを洗うことによって使用が可能になるイメージですね。まとめ&今後の目標
そんなこんなで、初学者がドキュメントを読んで書いてみました。
公式ドキュメントが丁寧で分かりやすい(概念は少し難しいけど)のでこのまま続けていこうと思います。
今後はデータがどういう流れになっているのか?を図示したいところです。