20200521のCSSに関する記事は10件です。

初学者がjavascript教えるならどうするか内容を考えてみた!

前提

本記事はプログラミング初学者の筆者が
「プログラミング初学者に対し、JavaScriptのイベントを分かりやすく教えるならどう教えるか」
という目線で書いております。
筆者もプログラミング初学者のため拙いところや詰めが甘い箇所があると思います。
その際はご指摘頂ければ幸いです。

目次

  1. JavaScriptのイベントとは?
  2. ドッキリに例えて考えてみよう!
  3. clickイベントの実例

 1. JavaScriptのイベントとは?

  • JavaScriptにおける「イベント」とはウェブページ上で発生するあらゆるアクションの総称のことです。
    例えば、下記の様な内容がイベントとして挙げられます。
    ・ボタンをクリックすると入力フォームが表示される。
    ・ボタンがクリックされた際にアラートを表示させる。
    ・マウスポインタが重なると色が変わる。
    クリックするとカテゴリーが表示される。

このイベントをする(処理)することをイベントハンドラとはと言います。
ちなみにハンドラとは英語だと「handler」で動詞の「handle(扱う)」から由来しているそうです。
イベントハンドラの一例は下記内容が挙げられます。

イベント名 イベント
ハンドラ名
説明
click onclick 要素がクリックされた時
change onchange 要素の内容が変更された時
keypress onkeypress キーボードのキーを押した時
mouseover onmouseover 要素にマウスのカーソルが重なった時
select onselect 要素がダブルクリックされた時
drag ondrag 要素がドラッグされた時
scroll onscroll スクロールバーがスクロールされた時

2. ドッキリに例えて考えてみよう!

今回は「HTMLにscriptタグを読み込む」「JavaScriptは別のファイルに書く」という前提で記載しております。。

実際にJavaScriptを書くときは以下のステップを踏みます。
なお、今回はドッキリに例えながら記載していきます。
①scriptタグをhtmlに記載する。
イベントを発生させるためにはJavaScriptのコードを読み込む必要があります。
そのため、htmlのファイル内に「JavaScriptのコードを読んでね!」とお願いするコードを記入します。
その際に注意して欲しいのが、head要素に書かず、body要素の最後にコードを書くことです。

プログラミングは基本的にコードは上から順に読み込むので、
head要素にコードを書き読み込むとbody要素とその子孫はまだ取得できないのでエラーになります。

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>Javascript</title>
    <link rel="stylesheet" href="style.css">
       <!-- head要素の中にscriptコードを書いてみる -->
      <script type="text/javascript" src="test.js"></script>
  </head>
  <body>
    <div id="gold-medal" class="medal"></div>
    <div id="silver-medal" class="medal"></div>
    <div id="bronze-medal" class="medal"></div>
  </body>
</html>

上記コードを例にすると、onclickの結果は「該当要素なし」としてnullになり、
Uncaught TypeError: Cannot set property 'onclick' of null at test.js:12
コンソールに出力されます。しかし、body要素の最後であれば、全てのHTMLを読み込んだ後なので、
情報を取得してイベントを発生させることができます。

②イベントハンドラする対象を決めイベント発生後のアクションを書く。
例えばclickしたらclickしたモノが消えるイベントを発生させることにしましょう。
対象となるモノをイベントの内容を紐付けてコードを書く必要があるので、以下の手順でコードを書いていきます。
(1)「html内に対象となるモノにidやclassを指定する。」
(2)「指定したモノに対しJavaScriptのファイルにイベント発生のコードを書く」

ドッキリに置き換えると

①〜②の動作をドッキリに置き換えると以下の様に例えることができます。

①どこでドッキリをやるのかを決める。
まず、どこでドッキリをするのかを決めます。
なお、早とちりしてドッキリを台無しにしないために最後の方で仕掛けます。

②ターゲットとどんなドッキリを仕掛けるのかを決める。
ターゲットを決めないとドッキリは始まりません。
対象となるターゲットに対しidの指定やclassの指定を行いましょう。
そして、仕掛けるドッキリ(アクションの内容)を仕掛け人(ジャバスクリプト やCSSのファイル)に対して
指示し(コードを書き)ましょう。

3. clickイベントの実例

今回は「金メダル、銀メダル、銅メダルをクリックしたら消える。」というイベントを書きました。
簡易的なモノなのでイメージがしやすいと思います。
詳細を記載したコードを記入したので、実際に挙動を確認していただければ幸いです。

Gyazo gif

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>Javascript</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="gold-medal" class="medal"></div>
    <div id="silver-medal" class="medal"></div>
    <div id="bronze-medal" class="medal"></div>
    <script type="text/javascript" src="test.js"></script>
</body>
</html>
style.css
body {
  font-family: Helvetica, Arial, sans-serif;
  margin: 0;
  padding: 0;
}
#gold-medal {
  background-color: #DBB400;
}
#silver-medal {
  background-color: #C9CACA;
}
#bronze-medal {
  background-color: #C47022;
}
.medal {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  float: left;
  margin: 20px;
}
test.js
//document.getElementById("").onclickでクリックしたターゲットの要素を取得。
//function(){ }でドッキリの内容を記載
//document.getElementById("").style.display = "none";でドッキリの内容が記載されている。

//(1行目)金メダルをクリックするとイベントが発生。 ← (2行目)金メダルのCSS要素にdisplya: none;が追加される。
document.getElementById("gold-medal").onclick = function(){
  document.getElementById("gold-medal").style.display = "none";
  }
//(1行目)銀メダルをクリックするとイベントが発生。 ← (2行目)銀メダルのCSS要素にdisplya: none;が追加される。
  document.getElementById("silver-medal").onclick = function(){
    document.getElementById("silver-medal").style.display = "none";
  }
//(1行目)銅メダルをクリックするとイベントが発生。 ← (2行目)銅メダルのCSS要素にdisplya: none;が追加される。
  document.getElementById("bronze-medal").onclick = function(){
    document.getElementById("bronze-medal").style.display = "none";
  }

引用
teratail(Javascriptで記述したコードでエラーが出てしまう。)
【JavaScript入門】初心者でも分かるイベント処理の作り方まとめ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「初学者がJavaScriptのイベントを分かりやすく教えるならどう教えるか?」を考えてみた!

前提

本記事はプログラミング初学者の筆者が
「プログラミング初学者に対し、JavaScriptのイベントを分かりやすく教えるならどう教えるか」という目線で書いております。
筆者もプログラミング初学者のため拙いところや詰めが甘い箇所があると思います。
その際はご指摘頂ければ幸いです。

目次

  1. JavaScriptのイベントとは?
  2. ドッキリに例えて考えてみよう!
  3. clickイベントの実例

 1. JavaScriptのイベントとは?

  • JavaScriptにおける「イベント」とはウェブページ上で発生するあらゆるアクションの総称のことです。
    例えば、下記の様な内容がイベントとして挙げられます。
    ・ボタンをクリックすると入力フォームが表示される。
    ・ボタンがクリックされた際にアラートを表示させる。
    ・マウスポインタが重なると色が変わる。
    クリックするとカテゴリーが表示される。

このイベントをする(処理)することをイベントハンドラとはと言います。
ちなみにハンドラとは英語だと「handler」で動詞の「handle(扱う)」から由来しているそうです。
イベントハンドラの一例は下記内容が挙げられます。

イベント名 イベント
ハンドラ名
説明
click onclick 要素がクリックされた時
change onchange 要素の内容が変更された時
keypress onkeypress キーボードのキーを押した時
mouseover onmouseover 要素にマウスのカーソルが重なった時
select onselect 要素がダブルクリックされた時
drag ondrag 要素がドラッグされた時
scroll onscroll スクロールバーがスクロールされた時

2. ドッキリに例えて考えてみよう!

今回は「HTMLにscriptタグを読み込む」「JavaScriptは別のファイルに書く」という前提で記載しております。。

実際にJavaScriptを書くときは以下のステップを踏みます。
なお、今回はドッキリに例えながら記載していきます。
①scriptタグをhtmlに記載する。
イベントを発生させるためにはJavaScriptのコードを読み込む必要があります。
そのため、htmlのファイル内に「JavaScriptのコードを読んでね!」とお願いするコードを記入します。
その際に注意して欲しいのが、head要素に書かず、body要素の最後にコードを書くことです。

プログラミングは基本的にコードは上から順に読み込むので、
head要素にコードを書き読み込むとbody要素とその子孫はまだ取得できないのでエラーになります。

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>Javascript</title>
    <link rel="stylesheet" href="style.css">
       <!-- head要素の中にscriptコードを書いてみる -->
      <script type="text/javascript" src="test.js"></script>
  </head>
  <body>
    <div id="gold-medal" class="medal"></div>
    <div id="silver-medal" class="medal"></div>
    <div id="bronze-medal" class="medal"></div>
  </body>
</html>

上記コードを例にすると、onclickの結果は「該当要素なし」としてnullになり、
Uncaught TypeError: Cannot set property 'onclick' of null at test.js:12
コンソールに出力されます。しかし、body要素の最後であれば、全てのHTMLを読み込んだ後なので、
情報を取得してイベントを発生させることができます。

②イベントハンドラする対象を決めイベント発生後のアクションを書く。
例えばclickしたらclickしたモノが消えるイベントを発生させることにしましょう。
対象となるモノをイベントの内容を紐付けてコードを書く必要があるので、以下の手順でコードを書いていきます。
(1)「html内に対象となるモノにidやclassを指定する。」
(2)「指定したモノに対しJavaScriptのファイルにイベント発生のコードを書く」

ドッキリに置き換えると

①〜②の動作をドッキリに置き換えると以下の様に例えることができます。

①どこでドッキリをやるのかを決める。
まず、どこでドッキリをするのかを決めます。
なお、早とちりしてドッキリを台無しにしないために最後の方で仕掛けます。

②ターゲットとどんなドッキリを仕掛けるのかを決める。
ターゲットを決めないとドッキリは始まりません。
対象となるターゲットに対しidの指定やclassの指定を行いましょう。
そして、仕掛けるドッキリ(アクションの内容)を仕掛け人(ジャバスクリプト やCSSのファイル)に対して
指示し(コードを書き)ましょう。

3. clickイベントの実例

今回は「金メダル、銀メダル、銅メダルをクリックしたら消える。」というイベントを書きました。
簡易的なモノなのでイメージがしやすいと思います。
詳細を記載したコードを記入したので、実際に挙動を確認していただければ幸いです。

Gyazo gif

sample.html
<!DOCTYPE html>
<html>
  <head>
    <title>Javascript</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="gold-medal" class="medal"></div>
    <div id="silver-medal" class="medal"></div>
    <div id="bronze-medal" class="medal"></div>
    <script type="text/javascript" src="test.js"></script>
</body>
</html>
style.css
body {
  font-family: Helvetica, Arial, sans-serif;
  margin: 0;
  padding: 0;
}
#gold-medal {
  background-color: #DBB400;
}
#silver-medal {
  background-color: #C9CACA;
}
#bronze-medal {
  background-color: #C47022;
}
.medal {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  float: left;
  margin: 20px;
}
test.js
//document.getElementById("").onclickでクリックしたターゲットの要素を取得。
//function(){ }でドッキリの内容を記載
//document.getElementById("").style.display = "none";でドッキリの内容が記載されている。

//(1行目)金メダルをクリックするとイベントが発生。 ← (2行目)金メダルのCSS要素にdisplya: none;が追加される。
document.getElementById("gold-medal").onclick = function(){
  document.getElementById("gold-medal").style.display = "none";
  }
//(1行目)銀メダルをクリックするとイベントが発生。 ← (2行目)銀メダルのCSS要素にdisplya: none;が追加される。
  document.getElementById("silver-medal").onclick = function(){
    document.getElementById("silver-medal").style.display = "none";
  }
//(1行目)銅メダルをクリックするとイベントが発生。 ← (2行目)銅メダルのCSS要素にdisplya: none;が追加される。
  document.getElementById("bronze-medal").onclick = function(){
    document.getElementById("bronze-medal").style.display = "none";
  }

引用
teratail(Javascriptで記述したコードでエラーが出てしまう。)
【JavaScript入門】初心者でも分かるイベント処理の作り方まとめ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OpenWeatherMapAPIのアイコンを変える方法

1. OpenWeatherMapのお天気アイコン

OpenWeatherMapには予め気象コードに合わせたアイコンが用意されています。
無料なのにとっても親切!
そんな初期設定のアイコンの一例がこちらです。
スクリーンショット 2019-11-13 15.00.06.pngスクリーンショット 2019-11-13 15.00.02.pngスクリーンショット 2019-11-13 14.59.51.png
なんとも画質も微妙ですし、あまりイケてない気がしますね・・・
変えれるものなら変えたいと思っていじってみたら
とっても簡単にできたので、その方法を記録しておきます。

2. ドキュメントを確認してみると...

OpenWeatherMapのドキュメントを確認してみると、下記アイコンの一覧が確認できます。
実際に表示されるものとは少し違いますが、
ファイル名がわかるのでこちらをいじればどうにかなりそうということが分かります。
https://openweathermap.org/weather-conditions
スクリーンショット 2019-11-13 16.05.08.png

3. 変更方法

weather.js
$.ajax({
        url: "https://api.openweathermap.org/data/2.5/weather",
        dataType: "jsonp",
        data: "q=Tokyo,jp&appid=" + APIKEY + "&lang=ja&units=metric",
        //天気データ呼び出し成功時
        success: function(data) {
          //〜中略〜
          $(".dayWeatherIcon").attr(
            "src",
            "img_tenki/" + data.weather[0].icon + ".png "
          );

他にやり方はあるかと思いますが、今回はこんな感じの手順で実装しました!

1、まず、上記アイコン一覧のファイル名を参考にお天気アイコンの画像を準備し、フォルダに格納
今回はimg_tenkiというフォルダに画像を保存
2、画像を表示させたいimgタグを予め用意しておき、そのsrcを
"img_tenki/" + data.weather[0].icon + ".png "と指定する

4. 完成したのがこちら...

少し良い感じになりました!
スクリーンショット 2019-11-13 16.08.49.png

5. 参考サイト

https://qiita.com/b-wind/items/06e19043a0cd70b10b03

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webサイト作成~公開までの簡単な流れ

はじめに

ITエンジニア2年目のひよっこです。
趣味丸出しの旅行記のような簡単なWebサイトを作成したので、公開までに行った流れを備忘録がてら記録します。

ちなみに、作成サイトはこちらです。
わたしの瀬戸内

前提

文学部出身のバリバリのド文型。
新卒未経験で入った会社の研修で掲示板を作成した際、Webサイト作るの楽しいなと思ったのがきっかけ。単純ですね。
結局画面周りをやったのは研修中だけだったので、体系的な基礎知識のないまま「とりあえず作っちゃえ」という見切り発車です。
Web制作の実務経験のない人間が、練習がてらに作成したものということをご了承ください。

どんなサイトを作ったか

まずは、自分で作ったものを実際に公開するという実績を作ることを一番の目的にしました。

・過去の島旅の思い出を、写真と文章で綴るサイト
・ページ構成、内容、デザインはシンプル
・レスポンシブ対応なし
・データベースは使用なし
・使用言語はHTML5とCSS3のみ

流れ

1.企画

コンセプト設計

・どんなサイトを作りたいか
・それはなぜか
・どんな人に見てほしいか
・見た人にどう思ってほしいか
等をまとめて、作成予定サイトのイメージを固めます。

サイトマップ作成

サイトマップとは、Webサイト全体のページの構成をリスト形式でまとめたものです。
どのページがどのページに紐付いているのかをツリー状に繋げていきます。
 ①必要そうなページを洗い出す
 ②洗い出したページをグループ分けする
 ③ページを階層化する
 ④清書(ドキュメント化)する ←私はgoogleのスライドショーを使用しました

ワイヤーフレーム作成

ワイヤーフレームとは、各ページのレイアウトを表した設計書のことです。
どの要素がページのどの位置にあるのかというのを可視化していきます。
 ①必要な各ページの掲載する要素を洗い出す(タイトル、写真、テキスト、ナビ、リンク等)
 ②洗い出した要素を関連性のあるものでグループ分けする
 ③要素の優先順位をつける
 ④清書(ドキュメント化)する ←photoshopを使用しました

2.サイト制作

パーツの準備

サイトに使う画像やテキストを準備します。
今回作成したのは旅行の記録サイトなので、私は以下のことをやりました。
 ①写真のレタッチ
 ②写真のサイズをカテゴリごとに統一(TOPページ用、見出し用、小見出し用等)
 ③パーツ用写真の編集
 ④説明文の草案

デザインの作成

本来なら、フォントや色や配置等を詰め、「デザインカンプ」というデザイン案を作成します。
が、私はここの工程をすっ飛ばしてしまいました。反省…。
今回作成したのはシンプルなものだったので、頭の中のイメージをコーディングしながら形にすることに支障はあまりなかったのですが、次はちゃんと作りこみます。

コーディング

イメージしている画面になるように実際にコーディングしていきます。

 ①エディタをDLする。
  様々なコードエディタがありますが、私はAdobeが出している「Brackets」を使用しました。
  コーディングしたらボタンひとつでchrome上で確認できるという優れもの。
  正直めちゃめちゃ使いやすかったです。
 ②HTMLで各ページに必要な要素を書いていく
  横並びにする作業や、位置・サイズ調整などは後ほどCSSで整えるので、ヘッダーやメニューや画像・テキストなどを一旦全部コーディングします。
 ③CSSでイメージに近づける
  ただずらっと並んでいるだけの要素たちを、CSSを使って整理します。
 ④微調整して完成

3.サイト公開

サーバーを借りる

作成したHPをインターネット上に公開するためには、サーバーに作成物を置かなくてはなりません。
私は、「さくらのレンタルサーバ」で一番安いプランを契約しました。

独自ドメインを取得する

ドメインとは、ホームページのネット上の住所のようなものです。
「https://qiita.com/」の「qiita.com」の部分ですね。
さくらのレンタルサーバ」ではサーバーレンタル時に独自ドメイン取得も希望できるので、一緒にやりました。

独自ドメイン取得にはお金がかかります。
「.com」や「.jp」等の種類によって金額はピンきりです。
私は「.com」」を契約しました(1年契約で3,000円位)。

※デフォルトでついてくる無料ドメインも使えますが、それだと「http://my-setouchi.sakura.ne.jp/」と借りたところの会社名が記載されてかっこ悪いので、完全に見栄えのためだけに課金しました(笑)

ファイルをサーバにアップロードする

いよいよ、PCに保存してあるHTMLファイル・CSSファイル・画像をレンタルしたサーバ上にアップロードしていきます。
通常はFTPクライアントソフトというファイル転送用のソフトを使ってアップロードを行いますが、さくらのサーバにはファイル転送ソフトを使わなくてもアップロードできるファイルマネージャが用意されているので、今回はそちらを使用しました。

次回は、FFFTPやWinSCP等のフリーで配布されているFTPソフトを使う練習もしたいです。

実際にページを確認する

作成したサイトのURLにアクセスしてみて、ページの飛び先や表示位置等、想定通りの作りになっているかを確認していきます。
エディタのプレビューでは問題なくても、サーバに置いたら表示されない画像がある等のケアレスミスを発見しました。
修正したファイルをアップロードし直して、再度確認したら完了です。

おわりに

やっぱり基礎知識は大事

今回、見切り発車でとりあえず作ってみましたが、コーディング中難航する場面や諦めた機能もありました。
そんな時、土台として体系的な知識があったらもう少しできる事も増えたのかなと思ったので、一旦ちゃんと勉強しようと思います。

今後

自分の作ったものがChromeでもIEでもスマホでも見れた時はやっぱりちょっと感動しました。
次は今回省いた「デザインカンプの作成」「FTPソフトの使用」も行い、js等他の言語も使ってもう少し本格的なWebサイトを作成してみたいです。

※ちなみに今回作成したサイトは、サーバが月ごとのレンタルなので恐らく1ヶ月で閉めると思います。(せっかく取得したドメインは1年間有効なので勿体無いのですが。)

ここまで読んでいただけてありがとうございます。
ど素人の備忘録ですが、少しでも参考になる部分があれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

webkitブラウザでは、css mask画像を取得する時に、同一オリジン下でもリクエストヘッダーにOriginを付ける

CSSマスクに関して、Safariにはバグがある

表題の通り、CSSマスクに指定した画像を取得する際に、同一オリジンのものであってもRequest headerにOriginを付けるようだ。

  -webkit-mask: url(../images/mask.png) no-repeat center top / 100% auto;
  mask: url(../images/mask.png) no-repeat center top / 100% auto;

スクリーンショット 2020-05-21 13.12.09.png

他の画像ファイルでは、ヘッダーにOriginはついていない。
Safari以外のブラウザでもChromeでも同様にOriginがついているので、Webkit系の挙動なのだろう。どうもcssマスク画像だけ、他の画像と違う扱いが行われているようなのだ。
Firefoxではついていないことを確認した。

どのような問題があるか

リクエストヘッダーが他の画像と異なることでどのような問題が発生しているかというと以下の通りである。
(正確にはこれが原因というか、このことから推測されるブラウザの挙動に関連する問題というべきか。)
この問題はSafariでのみ(Mobile Safariを含む)発生する。

Basic認証が複数回発生する

Basic認証をかけたサイトにアクセスする時、IDとパスワードを聞かれるわけだが、
通常は一度入力すれば、サイト全体が表示される。
しかし、-webkit-maskで指定した画像は、再度basic認証を聞かれるようなのだ。
調査したところ、他の画像との違いはリクエストヘッダーにOriginがあるか否かという点だった。
おそらく別環境のソースだと認識され、なんども認証を求めてくるのではないだろうか。

対処法

今のところ見いだせてない。
当然ながらこの問題は本番環境では発生しないわけなので、対処法を探しても詮無い。

2回認証すればよいのではないか

それはそうなのだが、問題は受託制作でクライアント確認時に起こる。
1回目の認証で、サイト全体はロードされ始めていて、2回目の認証時ダイアログの裏ではもうサイトのレンダリングが完了しているように見えるので、そこで認証をキャンセルしてしまうという事態が発生する。
そして、-webkit-maskが読み込めずに表示崩れが起こり、「崩れているんだけど」と問い合わせが来る。
面倒だけど、サボらずに複数回のBasic認証をクリアしてくださいとしか言えない。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者に捧げるハンバーガーメニューの作り方

対象読者

・ハンバーガーメニューを作りたい人
・細かく作り方の手順を知りたい人
・自分でオリジナルの見た目を作って応用したい人
・(ちなみに筆者の自己学習のためにも記事を書いているので間違っている箇所があれば是非とも教えて頂きたい)

目次

・HTMLのソース
・CSSのソース
・JavaScript(jQuery)のソース
・ハンバーガーメニュー作成の手順
・まとめ

HTMLのソース

Hamburger.html
<body>
    <div class="container">
        <button class="click-menu-icon">
            <span></span>
            <span></span>
            <span></span>
        </button>
        <nav>
            <ul>
                <li>111</li>
                <li>222</li>
                <li>333</li>
            </ul>
        </nav>
        <div class="overlay"></div>
    </div>
</body>

CSSのソース

style.css
* {
            margin: 0;
            padding: 0;
        }
        .overlay {
            display: block;
            width: 0;
            height: 0;
            background-color: rgba(0,0,0,0.5);
            position: absolute;
            top: 0;
            right: 0;
            z-index: 2;
            opacity: 0;
            transition: opacity 0.5s;
        }
        .overlay.open {
            width: 100%;
            height: 100%;
            opacity: 1;
        }

        .click-menu-icon {
            border: none;
            display: inline-block;
            width: 36px;
            height: 28px;
            vertical-align: middle;
            cursor: pointer;
            position: fixed;
            top: 30px;
            left: 30px;
            z-index: 100;
        }
        .click-menu-icon span {
            display: inline-block;
            box-sizing: border-box;
            position: absolute;
            left: 0;
            width: 100%;
            height: 4px;
            background-color: #000;
            transition: all 0.5s;
        }
        .click-menu-icon.active span {
            background-color: #000;
        }
        .click-menu-icon span:nth-of-type(1) {
            top: 0;
        }
        .click-menu-icon.active span:nth-of-type(1){
            transform: translateY(12px) rotate(-225deg);
        }
        .click-menu-icon span:nth-last-of-type(2) {
            top: 12px;
        }
        .click-menu-icon.active span:nth-of-type(2){
            opacity: 0;
        }
        .click-menu-icon span:nth-of-type(3) {
            bottom: 0;
        }
        .click-menu-icon.active span:nth-of-type(3){
            transform: translateY(-12px) rotate(225deg);
        }

        nav {
            width: 250px;
            height: 100%;
            padding-top: 100px;
            background-color: rgba(16, 69, 153, 0.8);
            position: fixed;
            top: 0;
            left: 0;
            z-index: 10;
            transform: translateX(-250px);
            transition: all 0.5s;
        }
        nav.open {
            transform: translateX(0);
        }
        nav li {
            color: #fff;
            text-align: center;
            padding: 10px 0;
        }

JavaScript(jQuery)のソース

main.js
$('.click-menu-icon').on('click',function(){
            if($(this).hasClass('active')){
                $(this).removeClass('active');
                $('nav').removeClass('open');
                $('.overlay').removeClass('open');
            } else {
                $(this).addClass('active');
                $('nav').addClass('open');
                $('.overlay').addClass('open');
            }
            });
            $('.overlay').on('click',function(){
            if($(this).hasClass('open')){
                $(this).removeClass('open');
                $('.click-menu-icon').removeClass('active');
                $('nav').removeClass('open');      
            }
            });

ハンバーガーメニュー作成の手順

作成手順
<!-- ハンバーガーメニュー作成の手順
*   1:buttonでspan*3を囲う
*   2:nav>ul>liでメニューを作る
*   3:</nav>の下に影をつけるための<div class="overlay">を作る
*   4:・・・・・以下からCSSの記述手順↓・・・・・
*       1.overlay
*           ・blockでwidthとheightを0にする
*           ・色はお好み_rgbaでaを0.5くらいにする(透明度の最大値)
*           ・position:absoluteでtop:0、left/rightはお好みで0
*           ・z-indexで上に来るために2くらいにする
*           ・初期状態はopacity:0にする
*           ・transition: opacity 0.5s;秒数は好み
*           ・overlay.openにwidth/height:100%、opacityを1にして変化させる
*
*       2.button.class名
*           ・buttonのborderを消しておく
*           ・vertical-alignを指定するためにinline-blockにする
*           ・ハンバーガーアイコンのwidth/heightを指定する(お好み)
*           ・vertical-align: middle;で縦に中央揃えする(大きさを変更しても中央揃えになる)
*           ・cursor:pointer;にする(お好み)
*           ・position: fixed;でスクローるしてもついてくるようにする。top/left/rightを指定する(お好みでfixedなしでもok)
*           ・必ず前面に出したいのでz-indexで一番大きい数にする
*       
*       3.button>span
*           ・box-sizing:border-box;でbutton自体の大きさ内でpaddingやborderなどを指定できる
*           ・left:0;width:100%;で左端から100%button内でspanの長さを指定する
*           ・heightはお好み(必ず指定しないと縦が0なので表示されなくなる)
*           ・色をつける(基本は背景に同化せずハッキリとした色にする)
*           ・transitionでクリックした時のspanが動く秒数を指定する
*       
*       4.buttonに.activeが追加された時のspan
*           ・click後の色を指定する
*           ・span:nth-of-type(1)でtop: 0;を指定する
*           ・.active span:nth-of-type(1)でtransform: translateY(お好み) rotate(-お好み);で1つ目の動きをつける
*           ・span:nth-of-type(2)でtop: お好み;で真ん中に表示する
*           ・.active span:nth-of-type(2)でopacity: 0;で表示を消す
*           ・span:nth-of-type(3)でbottom: 0;を指定する
*           ・.active span:nth-of-type(3)でtransform: translateY(-お好み) rotate(お好み);で3つ目の動きをつける
*           ※translateYとrotateは符号違いで数値は同じにする
*
*       5.nav
*           ・navのwidth:お好み;height: 100%;を指定する  
*           ・padding-topでハンバーガーの下に指定する(お好み)
*           ・background-colorを指定する(お好み)
*           ・position: fixed;でスクロールしてもついてくるようにする
*           ・top: 0;left or right: 0;にする
*           ・z-indexでコンテンツよりは上、overlayより上でハンバーガーより下にする
*           ・transform: translateX(-navのwidth分);で初期位置を画面の外にする
*           ・transitionで動きの秒数を指定する(お好み)
*         
*       6.nav.open
*           ・transform: translateX(0);でclickされた時に画面に表示する
*
*       7.nav li
*           ・colorでliの色を指定する(お好み)
*           ・text-align: center;でnav内の中央に寄せる
*           ・padding:お好み 0;で上下の数値だけ指定する
*
*       ・・・・・以上がCSSの記述手順↑・・・・・
*
*   5.・・・・・以下からJavaScript(jQuery)の記述手順↓・・・・・
*
*
           $('.buttonのクラス名').on('click',function(){    @クリックイベント
            if($(this).hasClass('active')){         @もしbuttonがactiveクラスを持っていたら
                $(this).removeClass('active');      @buttonからactiveクラスを外す
                $('nav').removeClass('open');       @navからopenクラスを外す
                $('.overlay').removeClass('open');  @overlayからopenクラスを外す
            } else {                                @activeクラスを持っていなかったら
                $(this).addClass('active');         @buttonにactiveクラスを追加する
                $('nav').addClass('open');          @navにopenクラスを追加する
                $('.overlay').addClass('open');     @overlayにopenクラスを追加する
            }
            });         @@ overlayをクリックしても開いたメニューを閉じれるようにする @@
            $('.overlay').on('click',function(){                @クリックイベント
            if($(this).hasClass('open')){                   @もしoverlayがopenクラスを持っていたら
                $(this).removeClass('open');                @overlayからopenクラスを外す
                $('buttonのクラス名').removeClass('active');  @buttonからactiveを外す
                $('nav').removeClass('open');               @navからopenクラスを外す
            }
            });
*
*
*
*
*
*
-->

まとめ

自分のコーディング技術向上のためにコードや書き方の手順を記してみました。
実はプログラミング学習を始めてまだ2.3ヶ月の初心者です。なのでもっと効率よく、尚且つ綺麗に記述できると思います。
ですが、過去の自分はただコードだけ見せられてもどう書けばいいか分からなかった経験があります。なので日本語で手順も記載することによって中の値だけ変えれば誰でもとりあえず実装できるようになると思います。
作成の手順通りに作って中の値だけ変えることによってオリジナルのハンバーガーメニューに応用できると思います。
過去の自分が知りたかったような記事でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

クリックした際に、「ⅴ」の向きを変更する方法

<section>
      <h1 id="one">&nbsp; メニュー1</h1>
       <ul class="menu" id="open-menu">
             <li>中身1</li>
             <li>中身2</li>
             <li>中身3</li>
        </ul>
    </section>

ulなどは、関係ない要素だが、日常で使う場合はアコーディオンメニューなどで
使うことが多いと予想されるため記載

続いてCSS

/* 記号> */
section > h1::before {
  content: '';
  width: 4px;
  height: 4px;
  border: 0;
  border-right: 2px solid black;
  border-bottom: 2px solid black;
  transform: rotate(45deg); 
  position: absolute;
  margin-top: 15px;
}
/* クリックした際に上向きにする */
.up::before {
  content: '';
  width: 4px;
  height: 4px;
  border: 0;
  border-right: 2px solid black;
  border-bottom: 2px solid black;
  transform: rotate(-135deg); 
  position: absolute;
  margin-top: 15px;
}

まず、疑似要素で>の記号を作る。
その後、jsでクリックした際に、section > h1::beforeに.up::beforeが
つくようなCSSを用意する。

const clickone = document.getElementById('one');
clickone.addEventListener('click', ()=>{
  clickone.classList.toggle('up');
});

まず、h1要素を取得して、そのh1(clickone)をクリックした場合に
.up::beforeがCSSにつくようにする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

border-image の表示がブラウザで異なる

見出しに下線を引いたとき、safari と chrome で表示が異なっていた。
原因は border-width の違いのようで、初期値は normal で safari はそうなっているけど、chrome は 初期値が 0 のようです。

仕様書ではイメージが読み込めなかった時のためにスタイルが必須のようなので、 border-style の有無で判定すると思いきや、safari は width だけ、 chrome は width と style の合わせ技で判断してるのですね。

両立させたい時は border-width: 0; 必須という感じですかね。
感覚的には Mac の chrome がわかりやすい。( chrome の width の初期値が 0 なのはどうかと思いますが)

参考:
MDN の border-image の説明
MDN の border-width の説明

See the Pen border-image by kihi1215 (@kihi) on CodePen.

環境

Mac : バージョン 10.15.4(19E287)
Safari : バージョン13.1 (15609.1.20.111.8)
Chrome : バージョン: 83.0.4103.61

ios の chrome (81.0.4044.124) では safari と同じ表示でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 322日目

100日チャレンジの322日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
322日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

プチ・クラウドストレージ作ってみた

初めまして

60歳を間近にウェブデザイナーを目指して独学で勉強しているお婆ちゃんです。

去年の暮れからphpを勉強して、初めてシステムらしきものを作ってみました。

やりたいこと
プチ・クラウドストレージ
・ファイルをどこからでもアップ、保管してダウンロードもできる。
・セキュリティも兼ねてIDとパスワードでログイン形式にする。

まずはパワーポイントでサイトの系図を設計しました。
Excel、Word、パワポは商工会議所で習いたてホヤホヤです。
それぞれ基礎編までクリアして1月半くらいかかりました。
全部で5万円くらいはかかったかな。

siteroot.jpg

次は手順を考えてイメージを具体化。
これは無料版のAdobeのXDを使ってみました。

操作も簡単で、感覚的に作れちゃうので便利です。
ページ自体はシンプルにしたかったのでフォントだけで作りました。
コードを書くのもAdobeの無料Brackets。Adobeドップリ。


ログインページ

AdobeXD イメージ図
Top.jpg
パスワードとIDはここで決めてます。
空文字NGの条件も設定。

login.php
//XSS
function html_escape($word){
    return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
$logid = '';
$pass = '';
$messege = '';

if($_SERVER['REQUEST_METHOD'] === 'POST'){
    //isset入れると空文字条件が効かない
    $logid = $_POST['logid'];
    $pass = $_POST['pass'];
    $logid = html_escape($logid);
    $pass = html_escape($pass);

    //IDとパスワード設定
    if($logid === 'keserasera' && $pass === 'keserasera'){
        session_start();
        $_SESSION['login'] = 1;
        //ファイル一覧へリロード
        header('Location: file_list.php');
        exit();
    } elseif ($logid === '' || $pass === ''){
        $messege = '<p class="notice"><i class="fas fa-info-circle"></i>IDとパスワードを空文字にしないで入力してください</p>';
    } else {
        $messege = '<p class="notice"><i class="fas fa-info-circle"></i>IDかパスワード、もしくは両方違います</p>';
    }
}

?>
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ファイル預かり処・マイ保管庫</title>
   <!-- headerインクルード -->
    <?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
    <header>
       <div id="titleVar">
          <h1><i class="fas fa-circle"></i>ファイル預かり処 マイ保管庫</h1>
          <p class="tx14">ログインページ</p>
       </div>       
       <div id="topvew">My keep folder</div>             
    </header>
    <main id="topMain">
      <form action="" method="post" class="clearfix">
         <label>ログインID</label>
         <input type="text" name="logid">
         <label>パスワード</label>
         <input type="password" name="pass">
         <p id="logBtn"><input type="submit" value="ログイン"></p>
         <?php echo $messege; ?>
      </form>      
    </main>
    <!-- footerインクルード -->
    <?php require_once(dirname(__FILE__).'/footer.php'); ?>

ファイルリスト一覧ページ

AdobeXD イメージ図
file_list.jpg

アップロードとダウンロード、削除ファイルの3つのformがあります。

  • アップロードは同一ページで処理
  • ダウンロードはチェックページに飛ばしてリロード処理
  • 削除ファイルは確認ページを別に作ってpostデータを渡す

ちなみにダウンロードと削除ファイル一覧リストはタブ切替。
フォルダーの中身は一緒でアップすると自動でリストが増えて、削除すると減っていきます。

file_list.php
//ログインしていないとアクセスさせない
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
    header('Location: un_login.php');
    exit();
}

function html_escape($word){
        return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
    }
$up_file = '';
$messege = '';
$select_file = '<p id="take">ファイルを選択して下さい</p>';
$restore = '';
$up_before = 'upBefore';//非表示css
$filename = '';

if($_SERVER['REQUEST_METHOD'] === 'POST'){
    $up_file = $_FILES['file_up'];
    $up_file['name'] = html_escape($up_file['name']);
    $up_file['name'] = strtolower($up_file['name']);//英小文字に変換  
    //var_dump($up_file['name']);

    $extension = Pathinfo($up_file['name'],PATHINFO_EXTENSION);//.以降の拡張子を重複しないよう整形
    $filename = Pathinfo($up_file['name'],PATHINFO_FILENAME);
    $filename = str_replace('.', '', $filename);//ファイル名に.があったら除去

    //ファイルがNGの場合条件処理
    if($up_file['size'] > 30000000 ){
        $messege = '<p id="caution" class="notice"><i class="fas fa-info-circle"></i>ファイルサイズが容量を超えています</p>';
        $up_before = 'upBefore';
        $restore = '<a id="restore" href="file_list.php">こちらからUPし直してください</a>';
        $select_file = '';
        //phpよりエラー表示を出すときファイル選択ボタンを出さないで再読み込みさせる為、空文字設定に
    } else {
        $messege = '';
        $up_before = 'upAfter';
        //fileをアップする関数
        move_uploaded_file($up_file['tmp_name'], './up_file/'.$filename.'.'.$extension);
    }
 }

   //upフォルダの中身
    $dw_items =  glob('./up_file/*');//DL用、同じでも変数変えないとエラーになる
    $del_items = glob('./up_file/*');//削除用、grobは配列形式でファイルパスを取得
?>
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ファイル一覧 | ファイル預かり処・マイ保管庫</title>  
<!-- headerインクルード -->
<?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
    <header>
       <div id="titleVar">
          <h1><i class="fas fa-circle"></i>ファイル預かり処 マイ保管庫</h1>
           <p id="logout"><a href="logout.php">ログアウト</a></p>
       </div>       
       <div id="topvew">My keep folder</div>             
    </header>
    <main id="main">
        <h2 class="pageTitle">ファイルアップロード</h2>
     <!-- ファイルup -->
        <form id="upBox" action="" method="post" enctype="multipart/form-data">
              <p class="notice">※ファイルsizeは1つにつき30MBまで、名前は英小文字で</p>
              <!-- UPし直し表示 -->
              <?php echo $restore; ?>
              <p id="<?php echo $up_before; ?>">ファイル「<?php echo $filename; ?>」はアップされました。続けてUPできます</p>
              <label for="up">
                  <!-- ファイルを選択ボタン -->
                  <?php echo $select_file; ?>
              </label>
              <input id="up" type="file" name="file_up">
              <p id="send"><input type="submit" value=""></p>
              <!-- エラーメッセージ -->
              <?php echo $messege; ?>
        </form>

      <div id="fileBox">
          <p id="fileCount">ファイル数<?php echo count($dw_items); ?>項目</p>         
          <h3 class="selectFile" id="dowTab">DL用ファイル一覧</h3>  
          <form id="dowList" action="download_file.php" method="post">
             <!-- 飛び先でLocation リダイレクト処理-->
              <ul>
                 <?php if(count($dw_items) === 0): ?>
                    <li>まだファイルはありません</li>
                    <?php else: ?>
                      <?php foreach($dw_items as $items): $dw_name = Pathinfo($items,PATHINFO_BASENAME); ?>                   
                     <li><input type="radio" name="dowl" value="<?php echo $dw_name; ?>"><?php echo $dw_name; ?></li>                     
                      <?php endforeach; ?>
                  <?php endif; ?>
              </ul>
              <p class="notice">※左のラジオボタンにチェックしてダウンロードボタンをクリックしてください</p>
              <p class="pibtn"><input type="submit" value="Download"></p>
          </form>

          <h3 class="selectFile" id="delTab">削除用ファイル一覧</h3>
          <form id="delList" action="delete_confilm.php" method="post">
              <ul>
                 <?php if(count($dw_items) === 0): ?>
                    <li>まだファイルはありません</li>
                    <?php else: ?>
                      <?php foreach($del_items as $items): $del_name = Pathinfo($items,PATHINFO_BASENAME); ?>
                         <li><input type="checkbox" name="del[]" value="<?php echo $del_name; ?>"><?php echo $del_name; ?></li>  
                      <?php endforeach; ?>
                  <?php endif; ?>
              </ul>
              <p class="notice">※左のチェックボックスを選択(複数可)して確認ボタンをクリックしてください</p>
              <p class="vibtn"><input type="submit" value="削除確認"></p>
          </form>
      </div><!-- //id="fileBox"-->

    </main>  
<!-- footerインクルード -->
<?php require_once(dirname(__FILE__).'/footer.php'); ?>



input type="file"は特殊で、デフォルトのボタンを使うのはビジュアル面で抵抗があったのでカスタマイズしました。

ファイルが選択されたらボタンがファイル名に変わって、エラーだったら上にメッセージ表示。
OKだったらtype="file"ブロックは非表示になって、type="submit"にすり替え。
見た目は一緒のボタンです。

ファイルアップが成功したらボタンの上にファイル名が表示して下のリストに追加といった仕様。

ただ、ファイル選択時はsubmitボタンは押されてないのでphpでの処理が難しい。
そこでjsのchangeイベントを活用。
ここは頭がこんがらがりました。phpとjsとcssのトリプル連携。

submit_btn.js
jQuery('#up').on('change',function(){
      const upfile = jQuery('#up').get(0).files;
      console.log(upfile);
      //多次元配列になるのかな? upfile[[name: xxx,size: xxx]]
      const fileName = upfile[0].name;            
      console.log(fileName);
       //file選択をsubmitにすり替え
      jQuery('#take').css('display','none');
      jQuery('#send').css('display','block');
      jQuery('#send input').val(fileName);
   });


ダウンロードチェックページ

ダウンロードのコードはどうしても分からなかったのでググって動いたものをコピペさせてもらいました。
それまではダウンロードできても開けられなかったり不具合続出。

ここのコードが一番難しい。
今の段階では理解できなかったのですが、そのうち自分でも組めるようになりたいです。

参考サイトはこちら

download_file.php
//ダウンロードチェック
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
    header('Location: un_login.php');
    exit();
}

function html_escape($word){
        return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
    }
$dowload_file = $_POST['dowl'];
$dowload_file = html_escape($dowload_file);

//var_dump($dowload_file);

//ここのコード分からなかったのでネットからググって拾ってきた
    function download($pPath, $pMimeType = null){
    //-- ファイルが読めない時はエラー(もっときちんと書いた方が良いが今回は割愛)
    if (!is_readable($pPath)) { die($pPath); }

    //-- Content-Typeとして送信するMIMEタイプ(第2引数を渡さない場合は自動判定) ※詳細は後述
    $mimeType = (isset($pMimeType)) ? $pMimeType
                                    : (new finfo(FILEINFO_MIME_TYPE))->file($pPath);

    //-- 適切なMIMEタイプが得られない時は、未知のファイルを示すapplication/octet-streamとする
    if (!preg_match('/\A\S+?\/\S+/', $mimeType)) {
        $mimeType = 'application/octet-stream';
    }

    //-- Content-Type
    header('Content-Type: ' . $mimeType);

    //-- ウェブブラウザが独自にMIMEタイプを判断する処理を抑止する
    header('X-Content-Type-Options: nosniff');

    //-- ダウンロードファイルのサイズ
    header('Content-Length: ' . filesize($pPath));

    //-- ダウンロード時のファイル名
    header('Content-Disposition: attachment; filename="' . basename($pPath) . '"');

    //-- keep-aliveを無効にする
    header('Connection: close');

    //-- readfile()の前に出力バッファリングを無効化する ※詳細は後述
    while (ob_get_level()) { ob_end_clean(); }

    //-- 出力
    readfile($pPath);

    //-- 最後に終了させるのを忘れない
    exit;
}

//選択されたファイルがあったらダウンロード、なかったらそのままリダイレクト
//選択されないままダウンロード処理されちゃうと変なファイルがDLされる
if(isset($_POST['dowl'])){
    download('./up_file/'.$dowload_file);
    header('Location: file_list.php');   
} else {
   header('Location: file_list.php');
}


削除確認、完了ページ

AdobeXD イメージ図
check.jpg

削除だけは誤って消してしまって後悔しないように、確認してからの導線にしました。
完了ページのレイアウトもほぼ一緒です。

delete_done.php
//ログインしていないとアクセスさせない
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login']) === false){
    header('Location: un_login.php');
    exit();
}

function html_escape($word){
    return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}

$delete_file = '';

//POSTで渡されたファイルを削除
if(isset($_POST['check'])){
    for($i = 0; $i < count($_POST['check']); $i++){           
        unlink('./up_file/'.html_escape($_POST['check'][$i]));
        //削除ファイルli書出し
        $delete_file .= '<li><i class="far fa-file"></i>'.html_escape($_POST['check'][$i]).'</li>';
    }    
}

?>
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ファイル削除完了 | ファイル預かり処・マイ保管庫</title>
<!-- headerインクルード -->
<?php require_once(dirname(__FILE__).'/header.php'); ?>
<div id="wrapper">
    <header>
       <div id="titleVar">
          <h1><i class="fas fa-circle"></i>ファイル預かり処 マイ保管庫</h1>
           <p id="logout"><a href="logout.php">ログアウト</a></p>
       </div>       
       <div id="topvew">My keep folder</div>             
    </header>

    <main id="confiBox">
        <h2 class="pageTitle">ファイル削除完了</h2>
        <p class="confiText">以下のファイルを削除しました</p>
        <ul>
            <?php echo $delete_file; ?>         
        </ul>
        <p id="toListpage"><a href="file_list.php">ファイル一覧ページへ</a></p>
    </main>

<!-- footerインクルード -->
<?php require_once(dirname(__FILE__).'/footer.php'); ?>

ログアウトページ

ログアウトページは、お約束のセッション破棄だけなのでコードは省きます。
レイアウトはログインページと同じにしました。


ひとまず完成

あとは実際のサーバに上げて動作確認。

動いた時は大感動。
あれ?
でもアップできないファイルがある。

色々試して、どうやら日本語名のファイルはアップできないみたい。

XAMPP開発時では日本語のファイル名でも大丈夫だったんですけどね。
そういえば日本語とサーバの相性は良くないと昔から言われてました。

とりあえず注意書きに日本語NGと追加して応急対処。
preg_matchで条件設定した方がいいのかなと思ったりしています。

ひとまず、これで完成として使い込んでみようと思ってます。
制作期間は約1週間、畑仕事と家事の合間にコツコツと作業

お婆ちゃんのweb制作奮闘記でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む