20210302のHTMLに関する記事は15件です。

Mapbox で 地図検索 機能を付けてみた

1. はじめに

この記事は「Mapboxで地図を表示してみた」の続きになります。

  • Qiita: Mapboxで地図を表示してみた

前回は、Mapbox を使用して 地図をWebブラウザ上に表示しました。

今回は、検索機能を追加し、指定した場所の地図を表示するようにします。

2. 準備

2-1. アカウント作成・アクセストークン 取得

前回記事の [2. 準備] を参考に、
Mapboxのアカウントを作成し、アクセストークン を取得します。

  • Mapboxで地図を表示してみた > [2. 準備]

2-2. スタイル作成

日本語で 地図を表示・検索できるようにするため、日本語に対応したマップスタイルを取得します。

Mapbox では、Mapbox Studio を使ってマップスタイルを設計・管理します。

  • Mapbox | Docs: Mapbox Studio:

① Mapbox Studioを開く

以下リンク先の Mapbox Studio を開きます。

  • Mapbox Studio:

② スタイル選択

今回は、Gallery で すでに用意されたスタイルを使用します。

Mapbox Studio 画面右側の [Find inspiration in the style gallery] をクリックします。

image.png

使用可能なスタイルが 表示されます。

image.png

下にスクロールし、[Mapbox Streets Japan]スタイル を選択します。

image.png

③ スタイル追加

[Add Mapbox Streets Japan to your account] をクリックし、スタイルを 自分のアカウントに追加します。

image.png

④ Style URL取得

追加したスタイルのURLを取得します。
このURLは 後のスクリプトに使用します。

image.png

3. コーディング

今回は 地図を表示した上で、検索機能を追加し、指定した場所の地図を表示するようにします。

3-1. サンプル

・ HTMLファイル

東京駅周辺(緯度: 35.6809591、経度: 139.7673068)のマップを表示し、
さらに検索した場所周辺のマップを表示するような HTMLファイル(map.html)を作成します。

map.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>地図表示</title>
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js"></script>
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css" rel="stylesheet" />

<style>
    html { height: 100% }
    body { height: 100% }
    #map { height: 100%; width: 100%}
</style>
</head>

<body>
    <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js"></script>
    <link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css" type="text/css">

    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>

    <div id='map'></div>

    <script>
        mapboxgl.accessToken = '<アクセストークン>';
        var map = new mapboxgl.Map({
            container: 'map',
            style: '<Style URL>',
            center: [139.7670516, 35.6811673],
            zoom: 15
        });

        map.addControl(
            new MapboxGeocoder({
                accessToken: mapboxgl.accessToken,
                mapboxgl: mapboxgl
            })
        );
    </script>

</body>
</html>

・ ブラウザ表示

map.html をブラウザ(ここではChromeを使用)で開いた画面を下に示します。

初期で指定した座標 (東京駅周辺) の地図が表示されます。
image.png

京都駅」で検索すると、京都駅周辺の地図が表示されます。
image.png
image.png

Mapbox | Docs :Add a geocoder

3-2. 解説

サンプル(map.html)の中身を解説します。

・JavaScript・CSSファイル 読込

head 要素に、
以下のように Mapbox を使用するための jsファイル・cssファイルを読み込みます。

    <script src="https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js"></script>
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css" rel="stylesheet" />

・style属性 指定

style 要素にて、HTMLのスタイルを指定します。

ここでは、ウィンドウの高さheight100%に設定しています。

また、マップ(id : map)のスタイルを、高さheight100%、幅 width100% に設定します。

<style>
    html { height: 100% }
    body { height: 100% }
    #map { height: 100%; width: 100%}
</style>

・mapbox-gl-geocoder 使用のためのJavaScript・CSSファイル 読込

mapbox-gl-geocoder を使用するための jsファイル・cssファイルを読み込みます。

    <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js"></script>
    <link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css" type="text/css">

また、IE11でmapbox-gl-geocoderを使用する場合、
Promise polyfillも読み込みます。

    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>

・マップ表示

div要素にて、マップ(id : map)をブラウザ画面上に配置します。

<div id="map"></div>

・スクリプト記述

script 要素にて、マップ(id:map)を表示し、検索するためのスクリプトを記述します。

    <script>
        mapboxgl.accessToken = '<アクセストークン>';
        var map = new mapboxgl.Map({
            container: 'map',
            style: '<Style URL>',
            center: [139.7670516, 35.6811673],
            zoom: 15
        });

        map.addControl(
            new MapboxGeocoder({
                accessToken: mapboxgl.accessToken,
                mapboxgl: mapboxgl
            })
        );
    </script>

以下に、スクリプトの中身を解説します。

  • アクセストークン設定

第2項 で取得した アクセストークンを、
mapboxgl.accessToken にセット設定します。

mapboxgl.accessToken = '<アクセストークン>';
  • マップ設定

Map オブジェクトを作成し、ページにマップを表示します。

var map = new mapboxgl.Map({
  container: 'map',
  style: '<Style URL>',
  center: [139.7670516, 35.6811673],
  zoom: 15
});

オプションで、マップの細かな設定をすることができます。
ここでは containerstylecenterzoom の4項目のオプションを設定しています。

オプション 説明
container Mapbox GL JSがマップをレンダリングするHTML要素、または要素の文字列ID。
style マップのスタイル。
center 最初にマップ表示する地理的中心点。
zoom マップの初期ズームレベル。

container 項目には、’map’ を設定します。

style 項目には、第2項で取得した Style URL を指定します。

center 項目には、東京駅周辺(緯度: 35.6809591、経度: 139.7673068)のマップを表示するために、
[139.7670516, 35.6811673] を設定します。

zoom 項目には、マップの初期ズームレベルとして 15 を設定します。

  • 検索機能 追加

ジオコーダー(・・・場所から 緯度経度の値を取得する) を追加し、
指定した場所を検索できるようにします。

map.addControl(
  new MapboxGeocoder({
    accessToken: mapboxgl.accessToken,
    mapboxgl: mapboxgl
  })
);

addControl メソッドを使用して、コントロールを追加します。
ここでは、Mapbox Geocoding APIの mapbox-gl-geocoder コントロール ( MapboxGeocoder )を追加します。

MapboxGeocoder でジオコーダーを設定します。
オプションでは、accessTokenmapboxgl の2項目を設定します。

オプション 説明
accessToken アクセストークン
mapboxgl mapboxglオブジェクト

accessTokenには アクセストークン mapboxgl.accessToken を、
mapboxglには mapboxglを設定します。

  • GitHub:mapbox/mapbox-gl-geocoder

4. おわりに

今回は、Mapboxを使って 指定した場所の地図を検索 してみました。

mapbox-gl-geocoderを使用することで、
他の地図サービスと同じような検索機能を、とても簡単に追加することができました。

参考情報

  • Mapbox GL _ JS API REFERENCE

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

フロントエンジニアが本気でCSSだけで「リアルなビー玉」を作る

どうも7noteです。再現シリーズ今回はビー玉に挑戦してみました。

image.png

ビー玉、水晶玉、ガラス玉、、、今回のはなかなかの力作です。
鏡餅を作った時とは比にならないくらいリアルに作れました・・・

いったいなんの役に立つかわからないですがただただ楽しいですね。

ソース

index.html
<div class="b-dama"></div>
style.css
.b-dama {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #182879;
  background-image: radial-gradient(90% 90% at 65% 80%, #48bffe 20%, transparent);
  box-shadow: -7px -20px 7px -10px rgba(26,68,111,0.9) inset, 0px 30px 5px -10px rgba(0,0,0,0.3), inset 0 0 10px 0px #fff, inset 0 0 25px 0px #fff;
  position: relative;
}

.b-dama::before {
  content: "";
  width: 100px;
  height: 100px;
  border-radius: 50%;
  display: inline-block;
  background: radial-gradient(12% 9% at 42% 21%, #fff 45%, transparent), radial-gradient(8% 3% at 52% 95%, #53FAFF 15%, transparent);
  box-shadow: -2px 67px 8px -40px #dbf2ff;
  transform: rotate(-33deg);
  position: absolute;
}

image.png

まとめ

個人的に気に入っているのは光が透けてちゃんと地面に水色の光が差し込んでいるあたりですかね。
また思いついたらいろいろ書いてみたいと思います。

参考:https://oekaki-zukan.com/articles/7902

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】WEB制作のちょいテク詰め合わせ

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

formのオプションを条件分岐する

ポートフォリオのテスト用アカウントやゲストアカウントなどで、アカウントデータを改変できないようにしたい場合があると思います。真っ先に思い浮かぶ記述方法は以下のようなものだと思います。

<%= f.text_area :nickname, readonly: "#{'readonly' if current_user.email == 'test@gmail.com'}" %>

しかし、これだとなぜかどちらでもreadonlyになってしまい、上手く条件分岐できません。おそらく、falseの処理が無いためだと思います。
逆に、trueかfalseになる処理にしてあげれば、上手くいくのではと考えました。

前提

・deviseを使ったユーザー認証を導入している。
・すでにテストアカウントを作成している。
※今回の場合は、「テストアカウントをすでに作成しており、そのデータを編集画面で表示はするが、編集はできないようにしたい。ただし、テストアカウントでは無い場合は編集でき、ビューに<% if ~ %>などで二度同じ様な記述を避けたい。」というものです。

text_areaなどの入力する系

text_area | Railsドキュメント
email_field | Railsドキュメント

<%= form_with model: @user, url: user_registration_path, local: true do |f| %>

  <%= f.text_area :nickname, readonly: current_user.email == "test@gmail.com" %>

  <%= f.email_field :email, readonly: current_user.email == "test@gmail.com" %>

<% end %>

この場合だと、readonly: truereadlonly: falseになるので、正しく条件分岐ができるようになります。
他のメソッドでも同じようにできます。

画像の選択

file_field | Railsドキュメント

<%= f.file_field :image, disabled: current_user.email == "test@gmail.com" %>

画像の場合は、readlonlyオプションが容易されていますが、readlonlyでは画像の選択ができてしまいます。ですので、無効化するdisabledオプションで指定します。

セキュリティ

上記の記述は、あくまでビュー側での条件分岐です。実際にデータを改変できないようにするには、サーバ側で弾く処理を加えてやる必要があると思います。

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

CKEditor をローカルPCでHTML(WYSIWYG)エディタもどきとして使用する

はじめに

windows環境でフリーのHTMLエディタを探したところ、適当なのが見つからずにCKEditorエディタなるものが検索にヒットしたので調べてみたらwebアプリだったので、それを出来るだけwindows環境でローカルアプリのように使用出来るようにしてみた。

まずはカスタマイズを一切せずに使用してみる

以下のコードをCKEditor.htmと名前を付けて保存し、ブラウザで開いてみる

CKEditor.htm
<script src="https://cdn.ckeditor.com/4.16.0/full-all/ckeditor.js"></script>
<textarea name="editor1" id="editor1"></textarea>

<script>
const editor = CKEDITOR.replace('editor1');
</script>

image.png
メニューの左上のソースというボタンで、htmlフォーマットとソースコードを切り替えて、ソースコードをクリップボードにコピーすれば、最小限のHTMLエディタとして機能させることが出来ます。

いろいろカスタマイズして使い勝手を良くしてみる

やりたいこと

  1. 起動時に最大化して起動する
  2. ファイルを開くコマンドを追加する
  3. 保存ボタンで、ファイルを保存出来るようにする
    保存ボタンを有効にするには、<textarea>タグを<form>タグで囲みます
    保存時にダイアログを表示するには、ブラウザの設定が必要です
    例:Google Chromeの場合 image.png
  4. ウィンドウを閉じるときに確認メッセージを表示させる
  5. 自分用のcssファイルを用意して、適用できるようにする
  6. インデント(字下げ)を1文字単位に変更する(デフォルトでは40px単位)
CKEditor.htm
<script src="https://cdn.ckeditor.com/4.16.0/full-all/ckeditor.js"></script>
<form>
<textarea name="editor1" id="editor1"></textarea>
</form> 

<script>
//ファイルを開くボタン押下時のファイル読込み処理
function onOpenFileChange(event) {
  const file = event.target.files[0];
  if(file){
    filename = file.name;
    const reader = new FileReader();
    reader.readAsText(file);
    reader.onload = () => {
        editor.setData( reader.result );
    };
  }
}

//ファイルを開くボタン押下処理
function OpenFile(editor) {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = 'text/html';
  input.setAttribute('onchange', 'onOpenFileChange(event)');
  input.click();
}

//保存ボタン押下処理
function SaveFile(editor) {
  const a = document.createElement('a');
  a.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(editor.getData());
  a.download = filename;
  a.click();
}

CKEDITOR.on('instanceReady', function (event) {
    //保存ボタン置換え
    var overridecmd = new CKEDITOR.command(editor, {exec: SaveFile});
    event.editor.commands['save'].exec = overridecmd.exec;

    //最大化する
    event.editor.execCommand('maximize');
});

let filename = '';
//インデント(字下げ)の単位を1文字に変更する
CKEDITOR.config.indentUnit = 'em';
CKEDITOR.config.indentOffset = 1;
//スキンを適用し、見た目を変更する
CKEDITOR.config.skin = 'moono'; 
//ユーザ定義のCSSを適用する
CKEDITOR.config.contentsCss =  [ './style.css']; 
const editor = CKEDITOR.replace('editor1');

//エディタのプラグインが呼び出される際のcallback
editor.on('pluginsLoaded', function(event) {
  //ファイルを開くボタンを追加する
  this.ui.addButton('openFile', {
    label: 'ファイルを開く', 
    command: 'openFile', 
    toolbar: 'document,3',  //ボタンを追加するtoolbarと位置を指定
    icon: 'https://icongr.am/fontawesome/folder-open-o.svg' 
  });
  this.addCommand('openFile', {exec: OpenFile});
});

//ウィンドウを閉じる時に確認メッセージを表示させる
window.addEventListener('beforeunload', function(event) {
  event.preventDefault();
  event.returnValue = '';
});
</script>
style.css
body
    {background-color:#FEF2DB;}
p
    {margin:2px 0;
    text-align:justify;
    text-justify:inter-ideograph;
    font-size: 1.0em;
    font-family:sans-serif;}
hr
    {margin:20px 0;}
h1
    {margin:8px 0;
    text-align:justify;
    text-justify:inter-ideograph;
    font-size: 1.2em;
    font-family:sans-serif;}
a:link
    {color:blue;
    text-decoration:underline;
    font-family:sans-serif;}
a:visited
    {color:purple;
    text-decoration:underline;
    font-family:sans-serif;}

CKEditor.htm
style.css
を同じフォルダにコピーして、CKEditor.htm をブラウザで開きます

環境

OS : WINDOWS 10
ブラウザ : Google Chrome
CKEditorバージョン : CKEditor4

参考

CKEditor4 リファレンス
CKEditor4 Githubリポジトリ
ブログ記事等のエディタを実装する際はCKEditor!さらに便利でカッコよく使い易く!サンプルソースあり
javascript - CKEditorの[保存]ボタンでクリックイベントをキャプチャする方法
Webデザインで使えるWebアイコンのCDNサービス「icongram」

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

ふりがなを打つのは簡単!

ふりがなをうちたい

この漢字にふりがなを打ちたいなと思うなら、HTMLにこれを書くだけで打てます!

HTML
<ruby>
   <rt>しょう<rt>
   <rt><rt>
</ruby>

簡単なのぜひやってみて下さい!

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

HTML/CSSで縦線を入れる方法

HTML

HTML
<div class="line-left">
   <p>HELLO</p>
</div>

縦線をつけたい要素を親要素で囲む必要があります。今回はdivで囲んでみました。

CSS

CSS
.line-left {
    border-left: 3px solid red;
}

スクリーンショット 2021-03-02 215651.png

border-left: 太さ 種類 色;
このように、border-leftプロパティを使うことでHELLOの左側に縦線が付きます。

HELLOと線の距離を離したいなら、

CSS
.line-left {
    border-left: 3px solid red;
    padding-left: 10px;
}

スクリーンショット 2021-03-02 220038.png

このように、padding-leftプロパティを入れることで間隔をあけることができます。
ぜひやってみてください!

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

HTML & CSS

前回の続きから始めます。
前回なにやってるんだよって方はこちらからどうぞ!
▶<https://qiita.com/akari_0618/items/3526fd7b751d9387667d>

装飾

まずHTMLの確認をします。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/style.css">
  <title>プロフィール</title>
</head>
<body>
<div class="container">
  <h1 class="title">自己紹介</h1>
  <ul class="pro">
    <li>名前:</li>
    <li>趣味:</li>
  </ul>
</div>
</body>
</html>

閉じタグがあるか確認をしてから、CSSに入りましょう。(たった一つのタグがないことで6時間程度時間を溶かしたことがあります笑)
確認が終わったところでコーディングに入ります。

style.css
.container {
  background-color: hotpink;
  padding: 10px;
  margin: 20px ;
  width: 50%;
  border: 10px double black;
} 

.title {
  border: 5px solid black;
  width: 30%;
  padding: 2px 0px 2px 20px ;
  background-color: white;
}

.pro {
  list-style: none;
}

li {
  border: 2px solid black;
  width: 30%;
  background-color: red;
  margin-bottom: 10px;
}

鋭い人は『ん?』って思いますよね?
クラス名の前にあるこれ▶.(ピリオド)
これはCSSで『これからクラスの装飾始めますよ〜』
というものなのHTMLでクラスを宣言した場合は必ず忘れないようにしましょう? 当たり前に忘れると反映されませんw

ulブロックの中にあるli要素に『点』を消す方法は list-style: none;
とします!!
全部完了するとこうなります☺️
 
スクリーンショット 2021-03-02 17.46.22.png

今まで紹介した方法ですべてやりました!
もしわからなかった場合などは記事に戻って振り返ってみてください?

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

【初学者向け】WAI-ARIAを使ってモーダルウィンドウを作る

今まで私はjQueryでモーダルウィンドウを実装していたのですが、最近jQueryを使わないことが増えたのでJavaScriptで実装した際の備忘録です。

使用するWAI-ARIAの属性

aria-controls

指定した要素が値に指定した要素を制御することを示すWAI-ARIAの属性です。
(※HTMLリファレンスから引用)

今回の場合は、モーダルウィンドウを開閉するボタンに使用します。
対応するモーダルウィンドウのidと同じ文字列を、開閉するボタンのaria-controlsの値に設定することで、「このボタンとこのモーダルウィンドウが対応している」という設定をします。

aria-expanded

要素の開閉の状態を示すためのWAI-ARIAの属性です。
(※HTMLリファレンスから引用)

こちらも今回の場合はモーダルウィンドウを開閉するボタンに使用します。
対応する要素が閉じている場合はfalse、開いている場合はtrueを設定します。
例えば、モーダルウィンドウを開くボタンを押下するときは、対応するモーダルウィンドウは閉じているはずです。
そのため、モーダルを開くボタンにはaria-expanded="false"、モーダルを閉じるボタンにはaria-expanded="true"を設定します。

aria-hidden

ユーザーエージェントに認識させたくない要素に指定するためのWAI-ARIA属性です。
(※HTMLリファレンスから引用)

display:none;visibility:hidden;で隠れている要素に指定する属性です。
今回の場合、モーダルウィンドウは最初非表示になっているので、モーダルウィンドウの大枠の要素に
aria-hidden="true"を設定します。

HTMLの準備

modal.html
<!-- モーダルウィンドウ -->
<div class="p-modal" id="modal_01" aria-hidden="true">
  <div class="p-modal__wrap">
   <!-- ↓モーダルを閉じるボタン↓ -->
     <button class="js-modalClose" aria-controls="modal_01" aria-expanded="true"></button>
      <div class="p-modal__contents">
        モーダルの中身
      </div>
   </div>
</div>

モーダルウィンドウ側のHTMLには、まず大枠の要素にidを付与します。
開いたモーダルウィンドウ内に、そのモーダルウィンドウを閉じるボタンを設置する場合は、
js-modalCloseといった閉じる用のクラスを付与し、aria-controlsには閉じる対象のモーダルウィンドウに付与されているidと同じものを記述します。

index.html
<!-- モーダルを開くためのボタン -->
<button class="js-modalOpen" aria-controls="modal_01" aria-expanded="false"></button>

モーダルウィンドウを開くボタンには、js-modalOpenといったクラスを付与し、
aria-controlsには開く対象となるモーダルウィンドウに付与されているidと同じものを記述します。

CSSで整形

デザイン面は除き、モーダルウィンドウの表示非表示に関わる部分だけ記載します。

style.scss
.p-modal {
  &[aria-hidden="true"] {
    visibility: hidden;
    opacity: 0;
    transition: .4s;
  }
  &[aria-hidden="false"] {
    visibility: visible;
    opacity: 1;
    transition: .4s;
  }
}

aria-hidden属性がtrue(要するに非表示)の場合はvisibility: hidden;で隠しています。
display: none;でもいいのですが、transitionが効かなかったりするので今回はvisibilityを使用しました。
反対にaria-hidden属性がfalse(要するに表示)の場合はvisibility: visible;で表示させ、
opacitytransitionでフェードインするような表示の仕方をさせています。

実際にJavaScriptで表示非表示を制御してみる

さて、ここからが本題です。
細かい説明は、各所にコメントアウトで記載しています。

modal.js
function modalWindow() {

  // ここで、HTML上にあるモーダル開閉用のクラスを全て取得
  const modalOpenBtn = document.querySelectorAll('.js-modalOpen');
  const modalCloseBtn = document.querySelectorAll('.js-modalClose');

  // 取得したモーダルを開くボタン一個一個に対しforEachで処理
  modalOpenBtn.forEach((elm) => {
    // ボタンがクリックされたら
    elm.addEventListener('click', () => {
      // ボタンに付与されているaria-controlsの値を取得し、それと同じidが付与されているモーダルウィンドウを取得する
      let targetId = elm.getAttribute('aria-controls');
      let target = document.getElementById(targetId);

      // モーダルが非表示だった場合
      if (target.getAttribute('aria-hidden') === 'true') {
        // ボタンのaria-expanded属性を変更し、対応するモーダルが開いたと設定する
        elm.setAttribute('aria-expanded', 'true');
        // モーダルのaria-hidden属性を変更し、モーダルが開いたと設定する
        target.setAttribute('aria-hidden', 'false');
        // 現在のスクロール位置を取得した後、bodyを固定させる
        const scrollY = window.scrollY;
        document.body.style.position = 'fixed';
        document.body.style.top = -scrollY + 'px';
        document.body.style.left = '0';
        document.body.style.right = '0';
      }
    });
  });

  // 取得したモーダルを閉じるボタン一個一個に対しforEachで処理
  modalCloseBtn.forEach((elm) => {
    // ボタンがクリックされたら
    elm.addEventListener('click', () => {
      // ボタンに付与されているaria-controlsの値を取得し、それと同じidが付与されているモーダルウィンドウを取得する
      let targetId = elm.getAttribute('aria-controls');
      let target = document.getElementById(targetId);

      // モーダルが表示されている場合
      if (target.getAttribute('aria-hidden') === 'false') {
        // 開くボタンクリック時に設定されたbodyのtopを取得し、bodyの固定を解除
        const scrollY = document.body.style.top;
        document.body.style.position = '';
        document.body.style.top = '';
        document.body.style.left = '';
        document.body.style.right = '';
        // スクロール位置をモーダルを開いた時と同じ位置に戻す
        window.scrollTo(0, parseInt(scrollY || '0') * -1);
        // ボタンのaria-expanded属性を変更し、対応するモーダルが閉じたと設定する
        elm.setAttribute('aria-expanded', 'false');
        // モーダルのaria-hidden属性を変更し、モーダルが閉じたと設定する
        target.setAttribute('aria-hidden', 'true');
      }
    });
  });
};

modalWindow();

固定する背景に色を付けたいとか、固定背景クリックでモーダルを閉じるようにしたい場合もあると思いますが、それに関してはまたの機会に…

さいごに

こういった構成にすることで、モーダルが何個に増えても簡単に対応でき、後の作業が楽になったかなと思います。
慣れたらもっとスマートなコードが書けるようになると思うので、その際はまた加筆修正行いたいと思います。

読んでいただきありがとうございました!

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

HTML~classと親子要素~

ここではclassの使い方を学んで行きます。

classとは

個人的なイメージとしてクラスはCSSのためにつけているのかな。と解釈しています。
というのも、h1タグでHTMLがマークアップしても、CSSで装飾しようとしたときに全部装飾されてしまうんですね。
スクリーンショット 2021-03-02 14.44.13.png
こんな感じになってしまうんですよ?

ではclassを付けていきましょう!!

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/style.css">
  <title>プロフィール</title>
</head>
<body>
<h1 class="title">あいうえお</h1>
<h1>かきくけこ</h1>
</body>
</html>
style.css
.title {
  font-size: 45px;
  background-color: aqua;
}

以下のようになりましたね!!

スクリーンショット 2021-03-02 14.47.42.png

ちなみにですが、class付けに決まりがあるのかな。と気になったので調べてみました!
結論的に特に決まりはありませんでした?
ただ自分だけではなく、誰が見てもわかるように命名するのが原則みたいです?
"なんのためなのか""それによって"何を表現するのか"を軸に考えて付けるのが基本のようです!

親要素と子要素

HTMLには親要素と子要素があります!
言葉で並べてもわかりにくいと思うので、実践形式でやっていきましょう?

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/style.css">
  <title>プロフィール</title>
</head>
<body>
<div class="container">
  <h1 class="title">自己紹介</h1>
  <ul class="pro">
    <li>名前:</li>
    <li>趣味:</li>
  </ul>
</div>
</body>
</html>

HTMLから説明していきますね。
不要な人は飛ばしてください。
divってなんやねんって思った方。
この子は何でも屋さんです!便利屋!難しく言うと汎用性ですかね(^_^;)ブロックレベル要素です?(https://qiita.com/akari_0618/items/f3b6892932cb6080c905)
そしてdivさんの隣りにいる先程説明した"class"!! 今回は"container"(コンテナ)と命名しました。ブロック要素で表示エリアを表します。
これが"親要素"です。
そしてその下がh1タグの隣にまたクラス付けがされていますね。今回はこの表示エリアのタイトルに相当するので"タイトル"と名付けました。(まんまやんw)
この子が"子要素"です!
そんでもって、またはじめましてのタグがありますね!
"ul"と"li"タグ!!
"ul"は順序なしlist要素と言います!(リストのブロックだよ〜でも特に順番はないよ〜)
"li"はリストの項目と言います!(いやいや、順番あるから。)
って感じですかね?
そして、忘れてはいけないのは、閉じタグですね。
これはちゃんと付けてくださいね?

ブラウザ表示するとこうなる予定です!

スクリーンショット 2021-03-02 15.55.54.png

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

divをクリックしてタイムピッカーを起動させたい

type="time"

<input type="time">

input要素のtype属性にtimeを指定することで、入力される値は時間の形式になる。
このインプットをクリックするとタイムピッカーが起動する。
step01_pc.jpg

Androidだとこんな感じ。
step01_mobile_1.jpg

いろんなとこでタイムピッカーを使いたい

Windowsはさておき、Androidの方は直感的に操作できてけっこう便利。
という訳で<div>とか、なにかしら要素をクリックしたときにタイムピッカーが起動して時刻が入力できるようにしたい。
もちろんJavaScriptで値も取得したい。

作りたいもの

今回は<div>で作ったボタンをクリックするとタイムピッカーが起動して、入力した時刻がボタンに表示される。っていうのをつくる。
機能としては<input>と変わらないけどデザインの自由度は<input>よりも大きいはず。

作成方法

jQueryとかは別として、どうやらタイムピッカーを<input type="time">以外で起動させる方法はなさそう。
最初は、何か要素をクリックしたらJavaScriptで強制的に<input>をクリックさせてタイムピッカーを起動させようとしたもののWindowsの方で失敗。Androidの場合は<input>をタップするとタイムピッカーが起動するけど、Windowsだと時計のアイコンをクリックしないといけないので、そこで躓いた。
いろいろ調べてみると、<input>の中のアイコンは操作できるらしいので、<input>をボタン内部いっぱいにして透明にして隠しておく方針に変更。
アイコンの操作は以下二つのサイトを参考にした。

https://blog.tmyt.jp/entry/2020/06/24/012442
https://itokoba.com/archives/301

ボタンを作成

ボタンとして<div>を設置。<input>は中に入れて見えないように透明に。CSSはボタンぽくサクッと整える。

html
<div id="button">
 <input type="time">
</div>
css
#button {
 width: 400px;
 height: 100px;
 border-radius: 20px;
 background-color: #2dbed5;
 box-shadow: 0 5px 10px #09262a;
}

/*クリック時の動き*/
#button:active {
 box-shadow: none;
 background-color: #2397aa;
 top: 5px;
}

input {
 height: 100%;
 width: 100%;
 border: none;
 opacity: 0;
}

/*どこをクリックしてもタイムピッカーが起動するようにする*/
input[type="time"]::-webkit-calendar-picker-indicator {
 margin: 0;
 padding: 0;
 height: 100%;
 width: 100%;
}

時刻を表示する

ボタンに時刻を表示するために<span>を追加。
JavaScriptで値を受け取って表示させれば完成。
このとき、ボタンや<input>にもCSSを加えて、要素の重なりを指定しておかないと<input>より<span>が上になってしまい、<input>がクリックできなくなるので注意。
以下のサイトを参考にした。

https://www.codegrid.net/articles/z-index-1

html
<div id="button">
 <input type="time">
 <span>00:00</span> <!-- 追加 -->
</div>
css
/*cssに追加*/

#button {
 position: relative;
 z-index: 1;
}

input {
 position: absolute;
 z-index: 2;
}

span {
 font-size: 80px;
 user-select: none;
 position: absolute;
 z-index: 1;
 top: 50%;
 left: 50%;
 transform: translateY(-50%) translateX(-50%);
 -webkit-transform: translateY(-50%) translateX(-50%);
}
js
let input = document.querySelector('input');
let time = document.querySelector('span');
input.addEventListener("input",  () => time.innerHTML = input.value, false);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSS~border~

前回はpaddingとmarginについて学びました。
次はborderについて学んで行きます。

borderとは

これは枠のことです。
前回のpaddingとmarginの記述がわかれば結構簡単です!?
記述方法は以下のとおりです。

style.css
h1 {
  color: black;
  font-size: 40px;
  background-color: red;
  border:4px solid black;
  width: 15%;
  padding: 10px 20px 10px 20px;
  margin: 30px 20px 10px 40px;
}

記述したあとはこうなるかなと思います。

スクリーンショット 2021-03-02 13.18.41.png
おお、簡単だわ?

部品ごとにそれぞれ解説しますね。
border▶線 4px▶太さ solid▶種類 black▶色
になります。
ちなみに、線の主な種類に関しては以下になります。
solid 実線
dotted 点線
dashed 破線
double 二重線

今はすべてを囲うように設定していますが、部分的に引きたい場合などありますよね!
それではやっていきましょう!

まずは、HTMLに追加していきましょう!

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/style.css">
  <title>CSSの書き方</title>
</head>
<body>
  <section>
    <h1>CSSについて</h1>
    <p>cssの基礎</p>
  </section>
</body>
</html>

では次にCSSを追加していきましょう!

style.css
p {
  font-size: 20px;
  background-color: pink;
  margin:40px;
  padding: 10px 20px 10px 20px;
  width: 15%;
  border-top:10px solid red;
  border-bottom: 10px solid green;
}

はい!ブラウザで表示してみましょう!

スクリーンショット 2021-03-02 13.40.44.png

てな感じになります!

単語の説明として
top▶上
right▶右
bottom▶下
left▶左
となります!

これらはpadding,marginのときにも使います?

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

CSS~padding&margin~

前回の記事でCSS の記述の仕方をアウトプットしましたね。
なんの話って方は前の記事を御覧ください!
https://qiita.com/akari_0618/items/1baaebc0a4946d2fa9a6
ではでは、早速やっていきましょう☺️

paddingとは

そもそもpaddingってなんぞやって思いますよね。私も思いました。最初スルーしました。
でも意外と分かるとおもしかったので一緒に学んで行きましょう。
paddingとは簡単に言うと文字の内側の余白みたいなもんですが、語彙力が凄まじくないので、実際にやっていきましょう。
前の記事では最後こんな形になっていたと思いますので、ここからスタートしていきましょう。
スクリーンショット 2021-03-02 11.50.16.png

style.css
h1 {
  color: black;
  font-size: 40px;
  background-color: red;
  width: 15%;
  padding: 10px 20px 10px 20px;
}

少し設定を変えました。
画面上でこうなりましたか?
内側の幅を取りたい場合に使います!

スクリーンショット 2021-03-02 12.30.27.png

paddingなんとなくわかったとこで、次はmarginやっていきましょう!

marginとは

marginを学んで行きましょう!
こちらは外側の余白を取りたいときに使います!
ではでは早速やっていきましょう!

style.css
h1 {
  color: black;
  font-size: 40px;
  background-color: red;
  width: 15%;
  padding: 10px 20px 10px 20px;
  margin: 30px 20px 10px 40px;
}

こうなりましたかね!
スクリーンショット 2021-03-02 12.46.21.png

padding&marginの指定の仕方

style.css
padding:10px;
 こちらは4辺すべての指定になります
padding:10px 20px;
 こちらは10pxが上と下、20pxが左右の指定になります
padding:10px 20px 30px;
 こちらは10pxが上、20pxが左右、30pxが下の設定になります
padding:10px 20px 30px 40px;
 こちらは10pxから時計回りに設定されています

個人的にmarginのほうがわかりやすいなと思いましたが、30分前まで違いがわかんなかったのですが、すぐわかるようになったので皆さんもぜひ攻略してみましょう☺️

次は、borderについて学んでいきます?

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

【JavaScript】submitボタンをonClick()でdisabledするとonSubmit()が実行されない件【二重送信防止】

問題

どうも。みるみっとです。
フロントエンドエンジニアをやっています。

業務中にお問い合わせフォームを作っていたところ、
「できれば二重防止送信機能を作って欲しい」との要望が。

単純に「送信ボタンをクリックした後にdisabledするかぁー」と思っていたのですが、
どうやらsubmitボタンのclickイベントでdisabledにするとonSubmitが実行されないということが分かりました。

※ちなみにonSubmit内でdisabledにしてもダメでした。

別にonSubmitまでdisabledしなくても良いのに...(´ω`)

動作環境

OS: macOs 10.15.6
ブラウザ: Google Chrome ver88.0

解決方法

disabledではなく、CSSの「pointer-events:none」を使うと上手くいきました。

pointer-events:noneにすることで、ポインターイベントが無効されます。
つまり、その要素のクリック・タッチが効かなくなります
ユーザーにとっては実質disabledです。

form.html
<form name="myForm" action="" method="get" onSubmit="return submitForm()">
    <p class="title">メッセージ</p>
    <textarea id="message"></textarea>

    <input type="submit" id="submit_pointer" value="送信" onClick="buttonDisabled()">
</form>
form.js
//submitボタンのクリックイベント
function buttonDisabled(){
    //pointer-eventsをnoneに
    $('#submit_pointer').css("pointer-events", "none");

    //disabledしてるっぽい色に変更
    $('#submit_pointer').css("background", "#636363");
}

//フォームのsubmitイベント
function submitForm(){
    return true;
}

実装例

下記に、
①二重送信防止していない送信ボタン
②送信後にdisabledする送信ボタン
③送信後にpointer-events:noneする送信ボタン

の3パターンを実装した礼を載せておきます。

disabledボタンはフォームが送信されず、
pointer-eventsボタンだとフォームが送信されることが分かると思います。


See the Pen
submitボタンをdisabledするとsubmitできない件
by mykz (@mykzreas)
on CodePen.


※フォームの送信に成功すると(onSubmitが動作すると)アラートが表示されるようにしています。
※ページ遷移を防ぐためonSubmitはreturn falseしています。

終わりに

disabledするとonSubmitが動作しないのはいまいちピンと来ないですが、pointer-events:noneの方が動作的のも軽そうですね。

視覚的にdisabledっぽいボタンの色に変更するのもUX的にも良さそうです。

参考

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

CSSについて

CSSとは??

前回マークアップしたHTMLがブラウザに表示される文字ですが、それだけでは味気ないですよね??
ここで使うのがCSSです!?
お化粧みたいな感じですね!?
それでは書き方を見ていきましょう?

CSSの記述方法

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="css/style.css">
  <title>CSSの書き方</title>
</head>
<body>
  <section>
    <h1>CSSについて</h1>
  </section>
</body>
</html>


style.css
h1 {
  color: black;
  font-size: 40px;
  background-color: red;
}

と記述します!
ポイントは、HTMLのheadタグの中に リンクタグをかき忘れないことです?
そして、CSSフォルダを作り、その中にCSSファイルを作ることを忘れないでください?
これをブラウザに表示するとこうなります!

スクリーンショット 2021-03-02 11.22.30.png

ちょ、h1長くねと思った方、HTMLにはインライン要素とブロック要素がありましたね?
https://qiita.com/akari_0618/items/f3b6892932cb6080c905
その前の記事を御覧ください!

長すぎだよと思った場合は、こう入力して幅を指定してしまいましょう!

style.css
h1 {
  color: black;
  font-size: 40px;
  background-color: red;
  width: 40px;
  height: 65px;
}

(width)がついかされていますね!
40%は適当にセットしましたが指定の仕方には3つほどあります。
①auto
初期値。つまり最初の画面のまま表示されます。
②%
こちらは親要素の幅次第で変わります。
③px
こちらは親要素に関係なく指定できます。
ちなみに当たり前ですが、親要素より大きくは指定できません。
そしてくどいようですが、インライン要素には幅指定できませんので反応しない場合は要素の確認をしてみましょう☺️

(height)も追加されていますね!
こちらは高さの設定になります。ここでは背景カラーの高さの設定になります。
高さ指定には主にピクセル(px)で指定します。

スクリーンショット 2021-03-02 11.50.16.png
こうなりましたらOKです?

文字を真ん中にしたいので次はそちらをやっていきたいと思います!
おそらく初心者がつまずくpaddingとmarginですね?
(大丈夫、私もだから)

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

HTML 〜ブロック要素とインライン要素〜

ブロック要素とインライン要素

①ブロック要素

その名の通り一つのブロックのことです。見出し、段落、表などがあります。

index.html
1. <form></form>
2. <table></table>
3. <ul></ul>
4. <div></div>
5. <p><p>

などがあります。
これらは横幅と高さの指定が可能です。横幅の初期値の値は親要素の横幅と同じになります?

②インライン要素

こちらはブロッレベル要素の中身になります。
文章の中の一部として使われたりします。
例としては以下になります?

index.html
1. <a></a>
2. <b></b>
3. <input></input>
4. <textarea></textarea>
5. <span></span>
6. <img>

などがあります!
これらは横幅と高さの指定ができません!((筆者はこれを知らない状態でCSSに突っ込んでしまい、後悔することになりました(・・;)

ちなみに当たり前ですが、ブロックレベル要素の中にインライン要素を入れなくてはなりません!

index.html
<div><a href="#">こちらをクリックしてください</a></div>

ちなみにですが、aタグのときに特にリンクが無い、またはとりあえずで付ける場合は"#"をつけときます?

インライン要素とブロックレベル要素について詳しくはこちらのサイトがわかりやすかったのでご参考にしてください!
https://www.itra.co.jp/webmedia/block-inline-difference.html

それでは、CSSに入っていきます?

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