- 投稿日:2020-05-19T23:12:32+09:00
結局for文を使うのか?while文を使うのか?for文とwhile文の使い分け
※この記事はCやJavaなどCライクな構文のfor文を持つ言語向けの記事です。Python等foreachな言語は対象外です。
今更のようですが、for文とwhile文の使い分け、プログラミングを始めたての頃には誰しも疑問に思ったことでしょう。
世の中の一般的な文献には、for文は繰り返し回数が明らかなときに使用するなどと書かれていることが多いようです。
しかしながら、自分としてはこの説明があまり腑に落ちませんでした。
今日プログラムを書いていて、この違いについてやっと自分の中で一つの落としどころが見つかったので、ここに記録しておこうと思います。
以下、JavaScriptで記述します。
class Iterator { index = 0; constructor(list) { this.list = list; } next() { return this.list[this.index++]; } } const iterator = new Iterator([1, 2, 3, 4, 5]);以上のような実装の
Iterator
クラスを用意します(実際にはファイルリストなどをイメージしてもらえれば良いです)。ここで、すべての要素を出力しつつ、要素の個数を数える処理を記述したいとします。当初、私は次のようなコードを書きました1。let count = 0, item; while (item = iterator.next()) { console.log(item); count++; } console.log(`個数: ${count}`);コードをより読みやすくするため、以下のように書き換えてみます。
let count, item; for (count = 0; item = iterator.next(); count++) { console.log(item); } console.log(`個数: ${count}`);書き換えてみたのですが・・・このコード、確かに短くはなっているのですが、非常に読み辛いと感じませんか?
恐らくこの理由は、私たちが
for (A; B; C) {}という文を見たとき、無意識に
For A, while B, do C.つまりAについて、Bの間、Cしなさいと読んでいるためだと思うのです。このため、実際の式をここに当てはめたとき、文章として成り立たないと強い違和感を覚えます。
もう少し踏み込んだ表現をするのであれば、意識する必要があるのはAの文、つまり初期設定式です。「for」という単語(=~について)が使われている以上、BやC、そしてブロック内の文は嫌でもこのAの部分に束縛を受けます。
先ほどのfor文の例に違和感があったのは、初期設定式は変数
count
の初期化に使用されているにもかかわらず、継続条件式やブロック内の文がcount
と全く関係のないものだったからなのです。まとめ
while文で表現可能な繰り返しのうち、for文で表現するべきものは
- 繰り返し初期に実施すべき式が存在する
- その式の主たる対象が継続条件や再設定式、ループ内の処理においても主要な要素である
を満たすものだということができると思います。
極端な例
逆に言えば、上のルールを満たしさえしていれば、一般に言われる「繰り返し回数がわかっている」を満たさない場合においても、for文を使って書けるものが存在することになります。以下の例はどうでしょうか。
class Iterator { index = 0; constructor(list) { this.list = list; } get currentItem() { return this.list[this.index]; } next() { this.index++; } } let count = 0; for ( const iterator = new Iterator([1, 2, 3, 4, 5]); iterator.currentItem; iterator.next() ) { console.log(iterator.currentItem); count++; } console.log(`個数: ${count}`);あまり違和感はない・・・ですよね???
JavaScriptでは、配列の範囲外のインデックスにアクセスがあった場合、エラーとはならず
undefined
というfalsyな値を返します。このため、next
メソッドは実行されるたびに要素を1つずつ返却し、全て終わるとundefined
を返すという挙動を示します。 ↩
- 投稿日:2020-05-19T22:56:03+09:00
JavaScript、jQuery個人的まとめ
JavaScript
?DOMとは
HTMLを解析しデータを作成する仕組み
DOMツリーやドキュメントツリーとも言う?ノード(オブジェクト)とは
HTML1つ1つのタグがDOMツリーの中ではノードと呼ばれる
例)body, header, side_barとかjs_foundation
window.addEventListener("load", function () {処理} window.onload = function() {処理}ロード時に全てのDOM要素を取得する
let btn = document.querySelector("Button");変数btnにセレクタButton(idのやつ)を代入
(“p”)だったり(“#Button2”)とかでも書く。btn.addEventListener("click", function () {処理}btnがクリックされた時に{}内の関数を実行するイベントを追加
btn.innerHTML = “hoge”指定したセレクタにhogeというHTMLを代入
btn.classList.add(“red”)指定したセレクタにCSS要素を代入する
btn.classList.remove(“blue”)指定したセレクタからblueというクラスを削除する
js_tabの解説
let tabs = document.getElementsByClassName("menu_item"); let tabsAry = Array.prototype.slice.call(tabs); tabsAry.forEach(function (value) { value.addEventListener("click", tabSwitch); });の処理の流れを解説。
変数tabsAryにtabsの中身を配列に変換して代入する。
tabsAryをforEachでvalueという変数に代入して全て繰り返す。
valueの値がクリックされたらイベントが発火される
console.log();で配列の中身を確認したらとてもよく分かる。
他の部分はコメント解説の内容通りなので省略jQuery
?IDセレクタ
IDセレクタとは、HTML要素のid属性で指定するセレクタのことです。IDセレクタは、取得したいHTML要素のid属性の値に#(ハッシュ)を付けたものをセレクタとして利用します。
idセレクタの例
1 $("#idSelector") // idがidSelectorの要素を取得
クラスセレクタ
クラスセレクタとは、HTML要素のclass属性で指定するセレクタのことです。クラスセレクタは、取得したいHTML要素のclass属性の値に.(ドット)を付けたものをセレクタとして利用します。
クラスセレクタの例
1 $(".classSelector") // classがclassSelectorの要素をすべて取得
要素セレクタ
要素セレクタとは、h1やpのようなHTML要素を対象としたセレクタのことです。要素セレクタは取得したいHTML要素の要素名をそのままセレクタとして利用します。
要素セレクタの例
1 $("h1") // h1要素をすべて取得
属性セレクタ
HTMLのタグの属性値を指定したい場合、$("[ 属性 = '値' ]")で属性セレクタを取得できます。
属性セレクタの例
1 $("input[ type='radio' ]"); // のHTML要素を取得する?removeClass()、addClass()
クラスを追加したり消す。最初に0を指定しなくても自動的に最初の要素を指定してくれる?index()
配列に変換しなくても、集合したDOM要素から引数に指定(thisとか)したDOMと同じ要素番号を戻す?eq()
引数に要素番号を取って、集合したDOM要素から選択できる分からない事はいきなり検索しないで、紙に実装できる流れを仮説立ててから調べる!
- 投稿日:2020-05-19T22:20:32+09:00
【初心者】ChromeDevToolsを使ってJavaScriptで簡単に要素を取得する方法
はじめに
会社で毎日ポチポチ画面操作していることをJavaScriptを使って自動化することにしました。値を取得や値のセットをするために、試行錯誤していたところ、簡単に出来るやり方がわかりました。
- document.querySelector()
- document.querySelectorAll()
メソッドが簡単に要素の取得や値のセットがしやすく、
ChromeDevToolsを使うことで、更に簡単に対応することが出来ました。ChromeDevToolsでDOMノード参照
以下のサイトで使い方をgifで説明しており、一瞬で使い方がわかります。
Chrome DevTools: Generate a JavaScript expression to get a DOM node
コード
今回実際に使った使い方
// 値のセット document.querySelector("#tabTopics1 > a").value="test" // 値の取得 document.querySelector("#tabTopics1 > a").value // innerText取得 document.querySelector("#tabTopics1 > a").innerText参考
- 投稿日:2020-05-19T21:11:48+09:00
Denoとはなにか - 実際につかってみる
はじめに
Deno
というものが面白そうだったので、これを書きたいと思います。Denoとはなにか
↑かわいい
Deno(ディーノ)という名前について、聞いたことがありますでしょうか。私も最近まで知りませんでしたが、実はv1.0がリリースされたのが2020/5/13とごく最近のことです。開発自体は2年前から行われておりましたが、結構新しめの技術です。
その証拠(?)にDenoでググると担々麺ばっかりでてきます。(2019/5/18現在)結局Denoってなんなの?
Deno
は、Node.js
の製作者であるRyan Dahlによって作られた、新しいJS/TSランタイムです。すっごい雑に説明すると、Node.js
のイケてなかったところを改良したものがDeno
になります。Deno
って文字を並べ替えるとNode
になりますね。const deno = 'node'.split('').sort().join('')Denoがつくられた背景
Deno
はJSConf EU 2018でのRyan Dahlによる講演「Node.jsに関する10の反省点」において発表されました。10 Things I Regret About Node.js - Ryan Dahl - JSConf EU
Node.js における設計ミス By Ryan DahlRyan Dahlは講演の中で、自身が開発し
Node.js
における10個の後悔している点について言及しました。それらの設計ミスに基づいて開発されたのが、Deno
です。実際にDenoを使ってみる?
なにはともあれ、実際に
Deno
を使ってみてNode.js
との違いについて見ていきましょう。インストール
まずはインストールをします。私はMacを使っているので、
Homebrew
を使用してインストールしました。$ brew install deno以下のコマンドで正しくインストールされたか確認してみましょう。
$ deno -V deno 1.0.0Denoを実行する
Deno
を簡単に実行してみるために、公式のサンプルコードを利用してみます。$ deno run https://deno.land/std/examples/welcome.ts Download https://deno.land/std/examples/welcome.ts Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts Compile https://deno.land/std/examples/welcome.ts Welcome to Deno ?恐竜さんが出てきました。可愛いですね?
2回目以降の動作は、初回と変わってきます。
$ deno run https://deno.land/std/examples/welcome.ts Welcome to Deno ?
Download
やCompile
などの行がなくなっていますね。
今回のように、リモートのURLを実行した場合にはローカルにキャッシュされ2回目以降は素早く実行することができます。
これは後ほど出てくるimport
でパッケージを読み込むときと同じです。変更点1 TypeScriptをそのままサポート
先程実行したプログラム自体はとても簡単なものでしたが、早速
Node.js
との変更点が含まれています。
先程実行したプログラムhttps://deno.land/std/examples/welcome.ts
の拡張子を見ると、TypeScript
のコードであることがわかります。
従来では、TypeScript
を実行するには、npm
でインストールして、ルート配下にtsconfig.json
を設置して、コンパイルして...といった作業が必要でした。
しかし、Deno
ならそのような設定はすべて必要ありません。デフォルトでTypeScript
をサポートしているので、そのまま実行することができます。サンプルコードを見てみる
簡単なプログラムだけではつまらないので、次はローカルにサーバーを立ててみます。以下のコードは公式サイトからのコピペで持ってきました。
8000ポートでサーバを立てて、Hello Worldと表示させます。import { serve } from "https://deno.land/std@0.50.0/http/server.ts"; const s = serve({ port: 8000 }); console.log("http://localhost:8000/"); for await (const req of s) { req.respond({ body: "Hello World\n" }); }次に、下記のコードが
Node.js
で書いた同じようなコードです。const http = require('http'); const server = http.createServer((req, res) => { res.end('Hello World'); }); server.listen(8000)この2つのコードを比べていきましょう。
変更点2 npmがない
と、先にコードの方を提出しましたが、その前にやることがありましたね。
まずはnpm init
でpackage.json
を作ってそれから...えっDeno
では必要ないって?そうなんです、
Deno
はインストールさえ済ませれば先に見たようにそのままコードを実行することができます。
驚くなかれ、そもそもDeno
にはnpmがありません。
npm
がないということは当然node_modules
やpackage.json
なんてものも存在しません。
node_moduels
ってかなり巨大なファイルでしたし、こいつがなくなるだけでフォルダ構成が結構スッキリしてくるんじゃないでしょうか。
node_moduels
とpackage.json
の採用は、Node.js
の設計ミスとしても上げれていた点です。では、
npm
を使用しないとなれば、どのようにして外部モジュールを使用するのでしょうか。
その答えは、サンプルコードにもあるように、import
にURLを渡します。import { serve } from "https://deno.land/std@0.50.0/http/server.ts";これは、
Deno
で外部モジュールを使用する唯一の方法です。もうnpm install
は必要としません。
ダウンロードは実行時に行われ、結果はキャッシュされます。変更点2 requireがなくなった
関連して、今まで
Node.js
で利用されてきたrequire
が廃止されました。Node.js
const http = require('http');Deno
import { serve } from "https://deno.land/std@0.50.0/http/server.ts";CommonJAの代わりに
ES Module
(import
とexport
)をデフォルトのモジュールとシステムとして使用します。変更点3 トップレベルのawait
あ!サンプルコードのこの部分、間違ってますよ!ほら!
for await (const req of s) { req.respond({ body: "Hello World\n" }); }
await
はasync
関数の中でしか動作できないんですよー、ほらVSCode
だって怒ってる。...え、これができるようになった?
そうです、もう
await
使いたさにわざわざasync
関数で囲む必要はありません。やったね。実行してみる
コードベースでの変更点はここまでにして、実際にコードを実行してローカルサーバを立ち上げてみましょう。
deno run
で実行できます。$ deno run server $ deno run server.js Download https://deno.land/std@0.50.0/http/server.ts Compile https://deno.land/std@0.50.0/http/server.ts Download https://deno.land/std@0.50.0/encoding/utf8.ts Download https://deno.land/std@0.50.0/io/bufio.ts Download https://deno.land/std@0.50.0/testing/asserts.ts Download https://deno.land/std@0.50.0/async/mod.ts Download https://deno.land/std@0.50.0/http/_io.ts Download https://deno.land/std@0.50.0/io/util.ts Download https://deno.land/std@0.50.0/path/mod.ts Download https://deno.land/std@0.50.0/path/win32.ts Download https://deno.land/std@0.50.0/path/posix.ts Download https://deno.land/std@0.50.0/path/common.ts Download https://deno.land/std@0.50.0/path/separator.ts Download https://deno.land/std@0.50.0/path/interface.ts Download https://deno.land/std@0.50.0/path/glob.ts Download https://deno.land/std@0.50.0/path/_constants.ts Download https://deno.land/std@0.50.0/path/_util.ts Download https://deno.land/std@0.50.0/fmt/colors.ts Download https://deno.land/std@0.50.0/testing/diff.ts Download https://deno.land/std@0.50.0/path/_globrex.ts Download https://deno.land/std@0.50.0/async/deferred.ts Download https://deno.land/std@0.50.0/async/delay.ts Download https://deno.land/std@0.50.0/async/mux_async_iterator.ts Download https://deno.land/std@0.50.0/textproto/mod.ts Download https://deno.land/std@0.50.0/http/http_status.ts Download https://deno.land/std@0.50.0/bytes/mod.ts error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11) at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10) at Object.listen ($deno$/ops/net.ts:51:10) at listen ($deno$/net.ts:152:22) at serve (https://deno.land/std@0.50.0/http/server.ts:261:20) at file:///Users/asaiippei/deno-test/server.js:2:11外部モジュールをインストールするとことまでは良かったのですが、エラーが発生してしまいました。
変更点4 セキュリティルールの変更
なぜエラーが発生したのでしょうか。
実は、Deno
デフォルトでセキュアであり、明示的に有効にしない限り、ファイル、ネットワーク、環境変数等にアクセスすることができません。ネットワークを許可するには
--allow-net
フラグを付与して実行する必要があります。
もう一度やってみましょう。$ deno run --allow-net server.js http://localhost:8000/無事成功しましたね。
http://localhost:8000/
にアクセスすると次のように表示されているはずです!
変更点5 Web APIの実装によるブラウザとの互換性の向上
Web APIはWebブラウザに組み込まれている機能です。ブラウザやコンピュータの環境の情報を取得し、これを使って役に立つややこしい事を行えるようにするものです。
代表的なものでいえば、DOM
,Canvas API
,Storage
,fetch API
などがあります。これらのAPIは日常的に使用していて、JavaScriptを覚えたての頃はJavaScript標準のモノだと思いこんでしまうほどですが、
Node.js
ではこれらを使用することはできません。理由は簡単で、これらのAPIはブラウザ(Google Chrome, Firefox)で利用できるものであり、Node.js
はブラウザではないからです。Node.jsの場合
例えば、次のように
Node.js
でFetch API
を利用使用とすると失敗します。fetch('https://pokeapi.co/api/v2/pokemon/') .then(res => res.json()) .then(data => console.log(data) )$ node node-fetch.js node-fetch.js:2 fetch('https://pokeapi.co/api/v2/pokemon/1') ^ ReferenceError: fetch is not defined at Object.<anonymous> (/Users/asaiippei/deno-test/node-fetch.js:2:1) at Module._compile (internal/modules/cjs/loader.js:955:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10) at Module.load (internal/modules/cjs/loader.js:811:32) at Function.Module._load (internal/modules/cjs/loader.js:723:14) at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10) at internal/main/run_main_module.js:17:11
fetch
が定義されていないと怒られていますね。
これを解決するには、外部モジュールであるnode-fetch
をインストールする必要があります。npm i node-fetch// これを追加 const fetch = require('node-fetch') fetch('https://pokeapi.co/api/v2/pokemon/') .then(res => res.json()) .then(data => console.log(data) )$ node node-fetch.js { count: 964, next: 'https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20', previous: null, results: [ { name: 'bulbasaur', url: 'https://pokeapi.co/api/v2/pokemon/1/' }, { name: 'ivysaur', url: 'https://pokeapi.co/api/v2/pokemon/2/' }, { name: 'venusaur', url: 'https://pokeapi.co/api/v2/pokemon/3/' }, { name: 'charmander', url: 'https://pokeapi.co/api/v2/pokemon/4/' }, { name: 'charmeleon', url: 'https://pokeapi.co/api/v2/pokemon/5/' }, { name: 'charizard', url: 'https://pokeapi.co/api/v2/pokemon/6/' }, { name: 'squirtle', url: 'https://pokeapi.co/api/v2/pokemon/7/' },Denoの場合
Deno
の場合には、標準でFetch API
がサポートされているため、インストールすることなく使用することができます。const res = await fetch('https://pokeapi.co/api/v2/pokemon/1') const json = res.json() const data = await json console.log(data)おっと、実行するときには
--allow-net
フラグを渡すことを忘れないでください!$ deno run --allow-net fetch.js { count: 964, next: "https://pokeapi.co/api/v2/pokemon/?offset=20&limit=20", previous: null, results: [ { name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon/1/" }, { name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon/2/" }, { name: "venusaur", url: "https://pokeapi.co/api/v2/pokemon/3/" }, { name: "charmander", url: "https://pokeapi.co/api/v2/pokemon/4/" }, { name: "charmeleon", url: "https://pokeapi.co/api/v2/pokemon/5/" }, { name: "charizard", url: "https://pokeapi.co/api/v2/pokemon/6/" }, { name: "squirtle", url: "https://pokeapi.co/api/v2/pokemon/7/" },
fetch API
の他にも幅広いWeb APIを実装していることにより、ブラウザとの互換性を向上させました。Denoによるテスト
Deno
にはテストランナーも含まれています。
Deno.test
を呼ぶことでテストをすることができます。Deno.test("hello world", () => { const x = 1 + 2; if (x !== 3) { throw Error("x should be equal to 3"); } });標準テストモジュールから、アサーションを使用することができます。
import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; Deno.test("hello world", () => { const x = 2 + 2; assertEquals(x, 3); });テストを実行するときは、
Deno test
です。$ deno test test.js Download https://deno.land/std/testing/asserts.ts Warning Implicitly using master branch https://deno.land/std/testing/asserts.ts Compile https://deno.land/std/testing/asserts.ts Download https://deno.land/std/fmt/colors.ts Download https://deno.land/std/testing/diff.ts Warning Implicitly using master branch https://deno.land/std/testing/diff.ts Warning Implicitly using master branch https://deno.land/std/fmt/colors.ts Compile file:///Users/deno-test/.deno.test.ts running 1 tests test hello world ... FAILED (5ms) failures: hello world AssertionError: Values are not equal: [Diff] Actual / Expected - 4 + 3 at assertEquals (https://deno.land/std/testing/asserts.ts:167:9) at test.js:5:3 at asyncOpSanitizer ($deno$/testing.ts:36:11) at Object.resourceSanitizer [as fn] ($deno$/testing.ts:70:11) at TestApi.[Symbol.asyncIterator] ($deno$/testing.ts:264:22) at TestApi.next (<anonymous>) at Object.runTests ($deno$/testing.ts:346:20) failures: hello world test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (5ms)初回なのでダウンロードとコンパイルが入りますね。
テストも失敗しているので修正しておきましょう。import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; Deno.test("hello world", () => { const x = 1 + 2; assertEquals(x, 3); });2回目以降のテストはすぐに実行できます。
$ deno test test.js running 1 tests test hello world ... ok (6ms) test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (8ms)これでOKですね。
おわりに
新しいJavaScriptのランタイムである
Deno
についてざっくりと触れてみました。
いつの日か、Node.js
に取って代わる日が来るのでしょうか、とても気になりますね。
- 投稿日:2020-05-19T18:26:05+09:00
【Nuxt.js】アプリ開発実践編:Nuxt + Vuex + firebaseでログイン付きToDoリスト①
前置き
前回のTODOリストに
オプション機能をつけていきます♪
https://note.com/aliz/n/n8411db2c9a20今回はログイン機能を追加?
実際にサービスを運用するには
必須の機能ですね!?
以前の記事をやっていない方でも
仕組みと書き方が分かれば大丈夫です?♀️内容が濃いのでお知らせした通り、
有料記事になりました?【使うもの】
・Firebase Authentication
・Vuex(ログイン状態の保持)【流れ】
ボリュームがあるため2回に分けます!
・ログイン画面の作成
・新規アカウント作成画面の作成
・ログイン時とログアウト時の
表示の出し分け
・+a
メールアドレス以外のログイン
エラー時の処理や
アカウント作成時にメール送信❓公式guides, Referenceの読み方
基本的にfirebaseのreferenceは
英語の状態で表示し、
自分でgoogle翻訳で翻訳しましょう??言語を日本語にすると
古いバージョンだったりするので、
最新の英語を翻訳していくのがベスト!⭕️
ただいきなり全部英語だと
欲しい情報がどこにあるか分からないので
最初は日本語で表示させて
ある程度検討をつけてから英語にしてます?
(英語も理解できるように頑張ろう…?)Step1: firebaseAuthの準備
まずはfirebaseで既に作成したプロジェクトに
ログイン方法の設定をしていきます?
簡単にできるメールアドレスから!✉️
ログインできるかどうか判断するため
firebase上でアカウントを作成してみます??後からアカウント作成画面も作ります
?Googleアカウントでの
ログインなども追加していきます・プロジェクトの概要ページから
サイドメニューのAuthenticationを選択
ログイン方法を設定を選択・メールを選択
・メールでのログインを有効にし、保存
・usersタブに戻りユーザーを追加
登録できるとユーザー情報が表示されます?
Step2: ログイン機能の実装
- 投稿日:2020-05-19T16:06:03+09:00
自己紹介
こんにちは。初投稿です。
投稿の練習がてら自己紹介をします。私は現在高校で数学の教員をやっています。
数学の授業で使えるようなソフトやページを作っています。私がプログラミングと出会ったのは大学2年生の時に受けた授業でした。そこではRubyを扱い、全く理解できなかった私はプログラミングに興味を持つことはありませんでした。
しかし大学3年生の春、某大手通信制高校の長期インターンを始めたら、そのインターンではプログラミングを扱う機会がとても多く、扱う教材も面白く私はプログラミングへのめり込んでいきました。
インターンでは主に、HTML、CSS、JavaScript、python、Unity(C#)などを扱いました。紹介しているものも、ここら辺中心に作っています。以下にインターン時代に作ったものを載せておきます。
円周率πの近似~モンテカルロ法~(HTML、JavaScript)
教員になってから作ったものは以下のものです。
サイコロを振りまくったら本当に1/6になるのか(Unity)
数学の展開、因数分解をひたすらやるゲーム(Unity)
これはまだ制作途中なので画像だけです。
サイコロと数学のゲームに関しては別記事でもう少し詳しく紹介できたらなと思います。
コメントやアドバイスをいただけると幸いです。
- 投稿日:2020-05-19T15:55:23+09:00
JavaScript文法総復習
- 投稿日:2020-05-19T14:23:22+09:00
○未満の数値を表示する方法
備忘録のため記述します。
<script> var data = [59, 39, 100, 2, 15, 40, 84, 97]; /* 以下に課題処理を追加 */ var i =0; for (i=0; i< data.length; i++){ document.write("<div>"+data[i]+"</div>"); } var count =0; //人数の把握をします var j =0; for (j=0; j<data.length; j++) { if (data[j]< 40) { count++ } } document.write("<div>40点未満の人は"+count+"人です</div>"); </script>
- 投稿日:2020-05-19T14:12:04+09:00
JavaScriptでドラゴンボールを見つけるためにfor,if文書こう!
はじめに
- そもそもJavaScriptの動かし方
- for文
- if文
- 最後に
そもそもJavaScriptの動かし方
JavaScriptには様々な動かし方があります。私が書いている記事のようにhtmlに埋め込んで動かす方法もありますが、ただ動かして見たいだけならブラウザから直接動かしてみましょう!chromeなどのブラウザにはJavaScriptを動かす機能が元々備わっているのでちゃんと動いてくれます。試しに簡単な文章を書いて動くか見てみましょう!!まずはchromeでデベロッパーツールを選択しconsoleに記入しましょう!ここに記入しenterを押せばしっかり動きます。
console.log("hello!!")こんな感じで動いてくれます。
alertも動かしてみましょう!alert("hello!")よく見るポップアップが表示されましたね!!
for文
今回は簡単な基本文法であるfor文を紹介したいと思います。簡単とはいえよく使う便利な文法ですのでしっかり覚えましょう!
10回繰り返してconsoleするものを書いてみます。for (var i = 0; i < 10; i++) { console.log(i) }これで実行すると
こんな感じで0~9まで書き出してくれます。
これが基本的なfor文の書き方です。三つの要素は左が最初の数字、真ん中が続く条件、右が増え方です。++は一つずる増えるという意味です。ここらへんの数値をいじることで、for文の細かな設定をしていきます。if文
if文もfor文同様によく使う文法です。簡単ですが応用のきく文法ですので基本をおさえておきましょう!!
今回はhtmlに埋め込んで動かしますね。<html> <head> <meta charset="utf-8"> <title>jstest</title> </head> <body> <script> var i = 10; if (i > 10) { document.write("10より大きい") } else { document.write("10以下") } </script> </body> </html>scriptタグの中にJavaScriptを書くことで実行することができます。今回はconsoleではなくdocument.writeを使います!
このhtmlを開くと
こんな感じで表示されます!
今回はiが10だったためelseの中が作動し10以下と表示されました。この書き方意外にもelseifなどで条件を増やすことができます。最後に
いかがだったでしょうか?if文for文の基本的な書き方を紹介しました。これだけの知識だとあまり使い物になりませんが、応用させることでより複雑なプログラムを書くことができます。私が載せているgoogle maps APIでもfor,if文を活用しています。是非ご覧になってください!
https://qiita.com/Ryunosuke-watanabe/items/958ed12471effc8fd778
- 投稿日:2020-05-19T13:54:55+09:00
JavaScript 学習記録 #2 Dateオブジェクト
12時間時計にする方法
24時間表記で表示されるのは、getHoursメソッドで取得できる数字をそのまま出力しているためです。
Dateオブジェクトに12時間表記の時間を取得できるメソッドはないため、加工が必要です。15:13 を 3:13 p.m とするためには・・・?
方法はいくつかあります。
①コードの書き方はこんな感じ
date.js<script> 'use strict'; const now = new Date(); const year = now.getFullYear(); const month = now.getMonth(); const date = now.getUTCDate(); const hour = now.getHours(); const min = now.getUTCMinutes(); let ampm = ''; if(hour < 12){ ampm = 'a.m.'; }else{ ampm = 'a.m.'; } const output = `${year}/${month + 1}/${date} ${hour}:${min}`; document.getElementById('time').textContent = output; </script>②処理の流れ
24時間表記を12時間表記にするには、大きく分けて2つの処理が必要である。
1⃣ 現在時刻は午前「a.m.」なのか「p.m.」なのか判別する
プログラムの最初の部分で変数ampmを定義し、空の文字列(文字数が0個の文字列)を代入する。そして、定数hourに保存されている数値が12より小さい、現在時間が0時~11時の場合、変数ampmに「a.m.」を代入する。定数hourの値が12以上の場合は「p.m.」を代入する。
2⃣ 0~23の数字を0~11に変換する
定数outputに代入するときには、24時間表記の時間を12で割った余りを計算すれば良い。
${hour % 12 }※ 「どう処理すれば良いか」を考えることが大切
- 投稿日:2020-05-19T12:24:18+09:00
javascriptメモ2
Node.jsのステップ実行
VSCで出来る。
VS201xでも昔試した記憶あるけど何も覚えていない。。Promise
var btn_promise = cube.getButtonStatus() btn_promise.then((value) => { console.log(value); // 1 //cube.playPresetSound( 4); //console.log("btn = " , String(btn)) }, (error) => { console.error("error:", error.message); });sleep
侍エンジニア塾の最初のロゴ、すごい邪魔なんですけど(怒)
// ビジーwaitを使う方法 function sleep2(waitMsec) { var startMsec = new Date(); // 指定ミリ秒間だけループさせる(CPUは常にビジー状態) while (new Date() - startMsec < waitMsec); } function sleep(waitSec, callbackFunc) { // 経過時間(秒) var spanedSec = 0; // 1秒間隔で無名関数を実行 var id = setInterval(function () { spanedSec++; // 経過時間 >= 待機時間の場合、待機終了。 if (spanedSec >= waitSec) { // タイマー停止 clearInterval(id); // 完了時、コールバック関数を実行 if (callbackFunc) callbackFunc(); } }, 1000); }enum
JavaScriptにはない、TypeScriptにはある。
enum Color {
Red,
Green,
Blue
}
var col = Color.Red;
col = 0; // Effectively same as Color.Red
format
function test() { var str = "もじれつ"; var num = 555; var flo = 1.7320508075; console.log('Stringの出力 : %s', str); console.log('Numberの出力 : %d', num); console.log('Floatの出力 : %f', flo); console.log('複数出力 : %s %d %f',str,num,flo); }メモ
- 投稿日:2020-05-19T11:14:13+09:00
グラフとBFS(幅優先探索)・DFS(深さ優先探索)をJSで実装してみる
この記事で言うグラフは、折れ線グラフなどのグラフでは無く「データ構造」のグラフです。
ノード(頂点)群とノード間の連結関係を表すエッジ(枝)群で構成されるデータ型です。実際のコード
class Graph { constructor() { this.connectedList = {}; } addVertex(vertex) { this.connectedList[vertex] = [] } addEdge(v1, v2) { this.connectedList[v1].push(v2); this.connectedList[v2].push(v1); } removeEdge(vertex1, vertex2) { this.connectedList[vertex1] = this.connectedList[vertex1].filter( v => v !== vertex2 ); this.connectedList[vertex2] = this.connectedList[vertex2].filter( v => v !== vertex1 ); } removeVertex(vertex) { while (this.adjacencyList[vertex].length) { const adjacentVertex = this.adjacencyList[vertex].pop(); this.removeEdge(vertex, adjacentVertex); } delete this.adjacencyList[vertex]; } dfs(start) { //ノードを格納するスタック const stack = [start]; //訪れた順番を格納 const result = []; //訪れたフラグ const visited = {}; //現在のノード let currentVertex; //訪問済みフラグを立てる visited[start] = true; while (stack.length) { // stackの最後尾を取得&削除 currentVertex = stack.pop(); // resultに現在の頂点を追加 result.push(currentVertex); // 繋がっている頂点を探索して訪問済みにする // そして、stackにその頂点を追加 this.connectedList[currentVertex].forEach(neighbor => { if (!visited[neighbor]) { visited[neighbor] = true; stack.push(neighbor); } }); } return result; } bfs(start) { // これから探索する予定のものの配列 const queue = [start]; // 訪問順番の結果 const result = []; // 探索済みであるか const visited = {}; let currentVertex; visited[start] = true; while (queue.length) { // 先頭から取り出す currentVertex = queue.shift(); // 現在地点を探索済みに result.push(currentVertex); this.connectedList[currentVertex].forEach(neighbor => { if (!visited[neighbor]) { visited[neighbor] = true; queue.push(neighbor); } }); } return result; } } const graph = new Graph; // 頂点の追加 graph.addVertex(1) graph.addVertex(2) graph.addVertex(3) graph.addVertex(4) graph.addVertex(5) graph.addVertex(6) graph.addVertex(7) // エッジ(繋がり)の追加 graph.addEdge(1, 2) graph.addEdge(1, 3) graph.addEdge(2, 4) graph.addEdge(4, 6) graph.addEdge(3, 6) graph.addEdge(4, 6) graph.addEdge(4, 5) graph.addEdge(5, 7) // 幅探索を行う console.log(graph.dfs(1)) // 1, 3, 6, 4, 5, 7, 2 // 深さ探索を行う console.log(graph.bfs(1)) // 1, 2, 3, 4, 6, 5, 7使いどころ
町1から町2に道が繋がっていてお互いを行き来出来るなどといった関係性を表すのに使うやつです。
Twitterのフォローフォロワーとかもグラフみたいなものなので意外と色々なところで使われます。
- 投稿日:2020-05-19T10:23:43+09:00
GAS スプレッドシートの内容をもとにGoogleフォームのリストボックスの内容をダイナミックに更新する。
やりたいこと
GAS スプレッドシートの内容をもとにGoogleフォームのリストボックスの内容をダイナミックに更新したい、という要望がありましたので方法について検討してみました。
やろうとしたけど出来なかった
フォームのonOpenトリガーを使って、開いたときに自動更新すればいいんじゃない。
と、簡単に考えたのですが出来ないみたいです。
理由はonOpenは回答時には実行されないようです。公式に記載がありました。GAS 公式ドキュメント
https://developers.google.com/apps-script/guides/triggers/#onopene結論
結果として私がたどりついた方法は、
フォームを更新するスクリプトを分ベースのタイマーで回すというものです。
(ちょっとダサい方法なので、他にベターな方法があれば教えていただけますとうれしいです。)手順
1.スタンドアローンスクリプトを作成する
スタンドアローンスクリプトを作成します。フォームに紐づくスクリプトは時間ベーストリガーに対応していません。
2.コード書く
GASconst formId = "フォームのid" const stId = "シートのid" function formUpdate(){ var form = FormApp.openById(formId) //リストボックスタイプのフォームアイテムを取得する。 var items = form.getItems(FormApp.ItemType.LIST); //対象のスプレッドシート開く var st = SpreadsheetApp.openById(stId).getSheetByName("シート名"); var maxrow = st.getLastRow(); //①リストアイテムに追加したい列のデータを取得する。 var data = st.getRange(1, 10 , maxrow , 1).getValues(); //①で取得したデータは2次元配列なのでそのままリストアイテムに代入できないので1次元配列にする。 var listitems = []; for (i = 0 ; i < data.length ; i ++ ){ listitems.push(data[i][0]); } //リストアイテムに追加する。 //リストボックスタイプのフォームアイテムがフォーム内に複数ある場合は、 //items[0]のインデックス番号を適切に変更してください。 items[0].asListItem().setChoiceValues(listitems); }3.トリガーを作成する
1分間隔でトリガーを設定します。
「現在のプロジェクトのトリガー」→ 「トリガーを追加」→「分ベースのタイマー」
4.おわり
参考にしました
Google Apps Script試行錯誤Blog
https://www.pre-practice.net/2019/09/google-formonopen.html
- 投稿日:2020-05-19T07:49:23+09:00
Reactでメディアクエリを良い感じに処理する
Reactでメディアクエリ
メディアクエリを良い感じにしてくれるreact-responsiveなる物が存在するが、微妙になんか使いにくい。
もっとなんか良い感じに使えるようにラッパーした物を定義してみる。定数定義
なんか良い感じに使えるようにまず良い感じに定数定義をしておく。
constants.tsxexport const BreakPoint = { sm: 640, md: 768, lg: 1024, xl: 1280, } as const; export type BreakPoint = typeof BreakPoint[keyof typeof BreakPoint]; export const WidthCriteria = { max: 'max-width', min: 'min-width', } as const; export type WidthCriteria = typeof WidthCriteria[keyof typeof WidthCriteria];
Criteriaってワードなんか微妙な感じがするけどまぁ。。。いいか。。。良い感じな奴を定義
定数を引数に取る良い感じの関数を再定義する。
useMediaQuery.tsximport { useMediaQuery } from 'react-responsive' import { BreakPoint, WidthCriteria } from "constants"; export default (breakpoint: BreakPoint, criteria: WidthCriteria): boolean => { const emSize = breakpoint / 16; return useMediaQuery({ query: `(${criteria}: ${emSize}em)` }); };使い方はこんな感じ
import React from 'react'; import { BreakPoint, WidthCriteria } from 'constants'; import useMediaQuery from 'useMediaQuery'; const Component: React.FC = () => { const isMobile = useMediaQuery(BreakPoint.sm, WidthCriteria.max); return ( <div> {isMobile ? 'mobile' : 'desktop'} </div> ); }; export default Component;これでなんかもっと良い感じに使えるようになった。
だがまだ良い感じには程遠い
Styled-Componentsでこんな感じに使えるようにしたいが、世の中そんなに甘くない。
Hooksの外でuseを使うなってガチギレされる。import { BreakPoint, WidthCriteria } from 'constants'; import useMediaQuery from 'useMediaQuery'; const Wrapper = styled.div` #{useMediaQuery(BreakPoint.md, WidthCriteria.min) && ` background-color: red; `}; #{useMediaQuery(BreakPoint.lg, WidthCriteria.min) && ` background-color: blue; `}; `; const Component: React.FC = () => { return ( <Wrapper> responsive </Wrapper> ); };Styled-Components用に良い感じな奴を定義
良い感じにメディアクエリを処理できるMixin的な物を定義する。
mediaQuery.tsximport { css, FlattenSimpleInterpolation } from "styled-components"; import { BreakPoint, WidthCriteria } from "constants"; export default (breakpoint: BreakPoint, criteria: WidthCriteria) => { const emSize = breakpoint / 16; return (style: FlattenSimpleInterpolation) => css` @media (${criteria}: ${emSize}em) { ${style}; }; `; };使い方はこんな感じ
import mq from 'mediaQuery'; const Wrapper = styled.div` ${mq(BreakPoint.md, WidthCriteria.min)(css` background-color: red; `)}; ${mq(BreakPoint.lg, WidthCriteria.min)(css` background-color: blue; `)}; `; const Component: React.FC = () => { return ( <Wrapper> responsive </Wrapper> ); };おわり
コード全文 https://gist.github.com/Karibash/15bfc974a76bca4ad6e69dfe6fc8f2c7
良い感じにメディアクエリを処理できる物が完成したが、
React初めて1週間くらいなんで、ぶっちゃけこれが正解なのか良くわからない。
マサカリ大歓迎です、待ってます。
- 投稿日:2020-05-19T07:20:00+09:00
PHPとJavaScriptの違いまとめ(主要項目の対比表)
PHPとJavaScriptの違いまとめ(主要項目の対比表)
PHPとJacaScriptのメソッドなど主要項目の違いまとめ。
どっちがどっちかわからくなるの防止。「←」はPHPの記述と同じ。
項目 PHP JavaScript 変数 *1 $変数名 var/let/const 変数名 関数 function 関数名(){} function 関数名(){}; アロー関数 *2 fn()=>処理 ()=>{}; 引数 $仮引数名 仮引数名 処理の終わり ; ← コメントアウト // or /* */ ← クラス定義 class クラス名{} ← コンストラクタ アクセス権 function __construct(){} constructor(){} インスタンス new クラス名() ← プロパティ アクセス権 $プロパティ名 const オブジェクト名 = {プロパティ名:値} プロパティの呼び出し インスタンス->プロパティ名 オブジェクト.プロパティ名 プロパティに関数をセット なし {プロパティ名:()=>{処理}}; メソッド アクセス権 function メソッド名() メソッド名(){} インスタンス自身(メソッドのみ) $this this 自身のプロパティ呼び出し $this->プロパティ名 this.プロパティ名 メソッド呼び出し インスタンス->メソッド名() インスタンス.メソッド名() 継承 class クラス名 extends 親クラス名{} ← クラスの使用許可 不要 export default クラス名 クラス読込み require_once('ファイル名.拡張子') import クラス名 from "./ファイル名" コンストラクタのオーバーライド *3 parent::__construct(); super() 出力 echo/print console.log() 配列の要素数 count(配列) 配列.length 配列 array() [] キーあり配列 array(キー名=>値) {キー名:値} キーあり配列の値取得 *4 配列[キー名] 配列.キー名 キーあり配列呼び名 連想配列 オブジェクト for文 for($変数=初期値: 条件式: ステップ){} ← 配列からひとつずつ抜き出す foreach($変数名 as 配列) 配列.forEach((変数名)=> {処理}); if文 if(条件式){} ← else if elseif (条件式){} else if (条件式){} switch文 switch(){case 条件: 処理; break;,,, default:} ← 変数展開 *5 "${変数}" `${変数}` and &&/and ← or パイプ2本/or ← 等しい == ===/== 異なる != !==/!= インクリメント演算子 ++ ← デクリメント演算子 -- ← 整数型に変換 intval() perseInt()/Number() 文字列型に変換*6 strval() String()/ .toString() / +'' 小数点に型変換 floatval() parseFloat() 3桁区切り number_format() 数値.toLocaleString() *1. let:再宣言NG、const:定数(再宣言・再代入NG)
*2. PHP:アロー関数は1行のみ。
JS:複数行OK。代入した変数が関数名になる(phpも)。
*3. JS:super()の引数は親クラスのコンストラクタの引数と合わせる
*4. JS:プロパティと呼ぶ
*5. PHP:シングルクオテーションだと文字列として出力
JS:バッククオート(shift+@)
*6. JS:空の文字列を足すと自動で文字列型に変換JSはES6からクラスが使えるようになった。PHPと同じ処理で設定されている(クラスの生成、クラスの継承)。
PHPとJSは、PHPとPythonよりも似ている部分が多い。その分ちょっとした違いに注意が必要。(elseif と else ifとか)
- 投稿日:2020-05-19T06:23:16+09:00
2ステップで実装!Next.js初心者のための画面遷移
1.はじめに
Next.jsを使い始めると「画面遷移処理ってどうするん?」って思って手が止まる人が多いのではないでしょうか?
なのでこの記事はNextの画面遷移がしっかり扱えるようにまとめておきました。2.なぜNext.jsで画面遷移を設定するのか?
まず初めにNextでなぜ画面遷移を設定するのでしょうか?
別に「aタグで記述しておけば、画面遷移するでしょう!」って考える人もいると思いますが実は違いがあるのです。aタグはHTMLファイルを取得して全画面を表示していますが、Nextは前の画面と比較して異なる部分だけを入れ替えています。
そのため、Nextの画面遷移のほうが軽く、動きが滑らかに感じます。3.Next.jsで画面遷移する方法
それでは具体的にNextで画面遷移する方法を見ていきましょう!
Nextで画面遷移する方法は2種類あります。
1. Linkコンポーネントを使う
2. Router.pushを使う
Linkコンポーネント
はJSXでHTMLのように記述する方法でRouter.push
はイベントハンドラーなどの処理の中で設定する方法です。
JSXを使うかどうかで使い分けることができ、JSXを使う場合はLinkコンポーネント
、イベントハンドラの場合はRouter.push
を使います。
- JSXの場合:Linkコンポーネント
- イベントハンドラの場合:Router.push
3-1.Linkコンポーネント
Linkコンポーネントはaタグをラップすることで使うことができ、特徴はJSXでタグとして扱えることです。
Linkコンポーネントは2ステップで実装できます。
- Linkコンポーネントのインポート
- Linkコンポーネントでaタグを包む
次のソースは、
/
から/NextPage
に遷移する方法ですLinkコンポーネントでの画面遷移//①Linkコンポーネントのインポート import Link from "next/link"; export default function Index() ( <div style={{textAlign: "center"}}> <h1>遷移元</h1> {/* ②Linkコンポーネントでaタグを包む */} <Link href="/NextPage"> <a>次のページへ進む</a> </Link> </div> );①でLinkコンポーネントを使うために必要なモジュールを取り込み、②でaタグをLinkコンポーネントでラップして遷移先を設定するだけの処理です。
この2ステップでNextでの画面遷移を実装できます。ちなみにリンクにCSSクラスなどのオプションを設定する場合はaタグに設定します。
例えば、別のタブで画面を開きたいときはtaget
属性をaタグに設定します。
aタグにオプションを設定<Link href="/NextPage"> <a target="_blank">新しいページを開く</a> </Link>3-2.Router.push
次はRouter.pushで遷移する方法です。
Router.pushは処理の中に埋め込めるので柔軟なページ遷移が可能です。
イベントハンドラなどに実装できるのが特徴で、Router.pushでの実装も2ステップで設定できます。
- Routerオブジェクトのインポート
- 遷移先の設定
次のソースは
/NextPage
から/
に遷移するプログラムです。Router.pushでの画面遷移//①Routerオブジェクトのインポート import Router from 'next/router' export default function NextPage() { function clickHandler() { //②遷移先の設定 Router.push('/') return } return ( <div style={{textAlign: "center"}}> <h1>遷移先</h1> <button onClick={clickHandler}>前のページへ戻る</button> </div> ); }①でRouterオブジェクトをインポートして、②のpushメソッドで遷移するパスを設定しています。
Next.jsのindex.jsは特殊なページで/index
でなくて/
でも遷移できます。
また、Pagesフォルダーを基準にパスを設定するので今回の場合だとpagesフォルダーの直下にあるindex.jsファイルのコンポーネントに遷移しています。4.まとめ
この記事ではNextで画面遷移する方法を2種類解説しました
・JSXでの画面遷移はLinkコンポーネント
・イベントハンドラーでの画面遷移はRouter.push画面遷移はNext.jsでもよく使う機能なので覚えていて損はないです。
5.参考文献
- 投稿日:2020-05-19T03:58:13+09:00
Rails で HTTP DELETE メソッドを使える条件
はじめに
Rails では RESTful な設計とするために各種 HTTP リクエストメソッドを使い分けていて、
config/routes.rb
では当たり前に DELETE メソッドを定義すると思います。が、このルーティング、正しく機能するためには条件があります。その条件を満たしていないと正しく動作しません。
結論
jquery-ujs.js
もしくはrails-ujs.js
が読み込まれていることが条件です。これら JavaScript がトリックによって DELETE をエミュレートしています。トリックの正体と有効/無効
一般的にブラウザでは GET と POST しか使えません。DELETE リクエストは送信されないので、当該ルートが発現することはありません。例えば
link_to method: :delete
と書いたとしてもブラウザの素の能力では GET が送信されてしまい、最悪誤動作を引き起こします。そこで前述 JavaScript が上手いことやって「DELETE のつもりでリクエストするんだぜ」というのを伝えることで、DELETE メソッドではないものの DELETE ルートを発現させています。具体的には form オブジェクトを作って「本来の意図は DELETE だよ」というパラメータを添えて POST しています。
そしてこのトリックは普通に
rails new
すれば自動的にお膳立てされ有効になります。が、
rails new --skip-javascript
すると無効になります。JavaScript に依存しているんだから当たり前ですね。そして前述のようにlink_to method: :delete
は GET になってしまうのです。手作業でトリックを有効にする方法
何らかの事情で
rails new --skip-javascript
しなければならない場合に手作業でトリックを有効にする方法は、下記です。各ファイルに各行を追記します。app/assets/javascripts/application.js//= require rails-ujs
app/views/layouts/application.html.erb<%= javascript_include_tag 'application' %>別法あります
ここまでは前置きです。
ここからが本題です。JavaScript を使わなくても DELETE ルートを使うことは出来ます。
button_to method: :delete
です。JavaScript が生成している form を静的に生成すればいいわけです。
より link_to ぽく
button_to では
input type='submit'
が1つ(とinput type='hidden'
が幾つか)の form が生成されますが、class='button_to'
になっています。さらに例えばbutton_to class: :anchor
とするとinput type='submit' class='anchor'
になります。生成される.html<form class="button_to" method="post" action="/logout"> <input type="hidden" name="_method" value="delete" /> <input type="hidden" name="authenticity_token" value="ナイショ" /> <input class="anchor" type="submit" value="LOGOUT" /> </form>なので、下記のような CSS (SCSS) を書いてやれば、機能も見た目も link_to の代わりに使うことが可能です。
app/assets/stylesheets/custom.scssform.button_to { display: inline; input.anchor[type='submit'] { | border-style: none; padding: 0; font-size: 1em; cursor: pointer; background-color: $bg-color; color: $link-color; } }終わりに
もともと --skip-javascript なんて使ってなかったんですが、Rails 6 が Webpacker で yarn や node_modules 必須になってたものの取り急ぎ小さく new したかったので --skip-javascript したら一旦良さそうだったけど logout 出来ず「!?」となって、、、ここに至りました。
静的最高♪
- 投稿日:2020-05-19T00:59:37+09:00
シンプルなプログレスバーを作成してみた
簡素な物ですが、
シンプルなプログレスバーのCSSスニペットを作ってみたので投稿。プログレスバーとは?
プログレスバー(英: Progress Bar)とは、長時間かかるタスクの進捗状況がどの程度完了したのかを視覚的・直感的に表示するもので、グラフィカルユーザインタフェースの要素(ウィジェット)の一つである。(Wikipediaより)
youtubeの再生時間を表示しているバー、ファイルのダウンロード中の「~%完了」のバー等が代表的ですね!
今回はjQueryを使用せずにページ全体のフォームの入力状態の進捗を表す、入力フォーム用のプログレスバーを作成してみました。作成したCSSスニペットのサンプル
下部のタブから表示を「0.5x」(スマホの場合は横画面にすると表示されると思います)に小さくしてサンプルの入力欄に文字を入力してみて下さい。
See the Pen
Simple ProgressBar by torajiro_u (@torajiro_u)
on CodePen.
文字を入力すると、上部のバーが動きフォームの入力の進捗度合を示してくれます。
これが今回作成した機能となります。
また、上のサンプルから全体のソースの確認が可能です。HTML部分機能内容
Javascriptのファイルを読み込ませ、「body」に「onload="taisyou()"」を設定するのみです。
「body」が読み込まれると自動でプログレスバーの動作に必要な処理が行われます。
CSSスニペットとして、導入を簡単にすることを意識して作成しました。CSS部分機能内容
下の部分がプログレスバーに関係するcssです。
.css/* progressbar部分 -------------------------------*/ body { margin: 0px; } .app { width: 100%; padding: 0px; background-color: white; } .progress { width: 100%; height: 10px; background-color: #F5F5F5; border-radius: 4px; box-shadow: inset 0 1px 2px rgba(0,0,0,.1); } .progress-bar { transition: width 0.5s linear; height: 100%; background-color: #337AB7; }■「.app」がプログレスバーを配置する場所
■「.progress」がプログレスバーを表示する為の枠部分
・背景が白のページなので色をホワイトスモークに設定しています。■「.progress-bar」が動作するバー部分
・transitionがバーが伸び縮みする際のアニメーションの設定です。
・フォーム入力時のjsの処理の結果、ここにwidthの%を設定することでバーを伸び縮みさせていますJS部分機能内容
処理部分です。
.jsvar step; var forms = document.querySelectorAll("form"); var allinp = 0; var p; function taisyou(){ p = new Progress(0); for(var i = forms.length;i--;){ var inp = forms[i].querySelectorAll("input[type='text'],textarea,select"); allinp += inp.length; //プログレスバーの進捗の対象を数える for(var j = inp.length;j--;){ inp[j].setAttribute("onChange","koushin(this)"); } } step = 100/allinp;//プログレスバーが一度の進捗で進む% } function koushin($this){//入力内容が更新されるたびにプログレスバーの進捗の状態を再計算する var elem = $this; if($this.value){ var text = $this.value; elem.className = 'up';//入力内容がnullではない場合にクラス名を変更 }else{ elem.className = ''; } var nowUp = document.getElementsByClassName('up');//変更したクラス名の数を計算 var status = allinp - (allinp - nowUp.length); p = status*step; new Progress(p);//バーに反映させるファンクションを呼び出す } var Progress = (function () { function Progress (p) { this.bar = document.querySelectorAll('#prog-bar > .progress-bar')[0]; this.p = p; this.update(); }; Progress.prototype.update = function () { this.bar.style.width = this.p + '%'; }; return Progress; }());■「taisyou()」ファンクション
・bodyが読み込まれると同時に処理が走ります。
・バーの進捗を初期化(0%)します。
・form配下のinput等バーの進捗に影響を与えさせる要素の数を算出します。
・100をバーの進捗に影響を与える要素の数で割り1進捗で何%進むか設定します。
・バーの進捗に影響を与える要素に「onChange="koushin(this)"」イベントを設定します。■「koushin($this)」ファンクション
・onChangeイベントが設定された箇所に入力が行われる度に処理を実行し入力
内容を確認します。
・入力内容がnullではない時にクラス名を「up」に変更します。
・ページ内の「up」と名前のついたクラスの数を確認し、その時バーは何%の進捗か計算します。
・バーに進捗を反映させるファンクションに算出した%を渡します。■「Progress(p)」ファンクション
・「koushin($this)」ファンクションで算出したバーの進捗率(p%)を「.progress-bar」のwidthに設定することでバーを動作させます。最後に
今回作成した機能はとてもシンプルかつ、ほぼ最低限度動作するだけのものなので
入力の進捗率によってバーの色を変えてみたり等色々改修を加えていくのも面白そうだなと思いました。
- 投稿日:2020-05-19T00:37:37+09:00
【html】共通パーツを別ファイル化してjQueryで読み出し+パーツにjsを効かせる方法
はじめに
htmlでヘッダーやフッターを共通パーツ化する方法
こうしたことは最近ではVue.jsなどでラクに実現できてしまいますが、今回はプログラマじゃなくても保守できるように。。ということが推奨されたため、できるだけ簡素な方法で実装しました。
そして、ヘッダー部分で必要なjsが何故か読み込めず相当ハマってしまったのでその解決法もあわせて記述します。手順
以下の方の記事が一番わかりやすく実行しやすかったです。
https://qiita.com/sho11hei12-1998/items/e9c81db697fb5d51e2af切り分けた先の共通パーツでは、
id
をあらためて指定しなくてもindex.html
内で指定しておけばいい感じに読み込んでくれるようです。
header内のmenuWrap
部分をクリックすることで、メニュー(panel
内の部分)を開閉できるようにしたい、というのが主に実現したいことです。
index.html<!DOCTYPE HTML> <head> <link rel="stylesheet" media="all" href="css/style.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script> <script src="js/script.js"></script> </head> <html> <body> <!-- header.html --> <header id="header"></header> <div> <h1>中身(コンテンツ)</h1> </div> <!-- footer.html 今回は使いません --> <footer id="footer"></footer> </body> </html>header.html<!-- header共通ファイル --> <div id="headerWrap"> <h1><a href="index.html"><img src="images/logo.png" width="284" height="160" alt="logo"></a></h1> <nav id="mainnav"> <p id="menuWrap"> <a id="menu"><span id="menuBtn"></span></a> </p> <div class="panel"> <ul> <li><to><a href="index.html">トップページ"</a></to></li> <li><to><a href="about-us.html">ご挨拶</a></to></li> <li><to><a href="archives.html">業績</a></to></li> <li><to><a href="contact.html">お問い合わせ</a></to></li> </ul> </div> </nav> </div>style.css.panel { width: 100%; display: none; overflow: hidden; position: relative; left: 0; top: 0; z-index: 100; } #menuBtn { display: block; position: absolute; top: 60%; left: 50%; width: 18px; height: 2px; margin: -1px 0 0 -7px; background: #000; transition: .2s; } #menuBtn:before, #menuBtn:after { display: block; content: ""; position: absolute; top: 50%; left: 0; width: 18px; height: 2px; background: #000; transition: .3s; } a#menu .close { background: transparent; } a#menu .close:before, a#menu .close:after{ margin-top: 0; } a#menu .close:before { transform: rotate(-45deg); -webkit-transform: rotate(-45deg); } a#menu .close:after { transform: rotate(-135deg); -webkit-transform: rotate(-135deg); }script.js$(function(){ // html 共通部分読み込み $("#header").load("header.html"); $("#footer").load("footer.html"); // 中略 $('#menuWrap').on('click', function() { $(this).next().slideToggle(); $('#menuBtn').toggleClass('close'); }, function() { $(this).next().slideToggle(); $('#menuBtn').removeClass('close'); }); });上記では概ね必要最低限のソースのみ記述していますが、画面右側に開閉できるハンバーガーメニューのついたヘッダーを生成しました。いや、そのつもりでした。
さて、パーツ切り分けはできたけど
jsが効かなくなってしまった
ここまで書いたところでメニューの開閉が出来なくなってしまいました。あらやだ!
headerファイルを切り分ける前は正常にscript.jsを読み込み動いており、パーツを切り分けて$("#header").load("header.html");
を追記した部分も正常に動いてくれるので、js全体を読み込んでいないわけではなさそう。作業途中でjQueryのバージョンを変えた(1.8.0->1.9.1)こともあり、廃止メソッドのせいかな?と思い色々試してみるも効果なし。
あと何故かブラウザのデバッグにも引っかからず(理由はわかりません)解決
https://webdesign-abc.com/tech/easy-edit/
大元のhtmlで使用しているjsの機能を使いたい場合は、共通パーツ内の最初に、必要なjsファイルを記述する必要があります。
大元のhtmlで読み込んでいるjsはheaderでは読み込んでくれないようです。
cssは何もしなくても正常に読み込んでくれるのでjsもそんなかんじとうっかり思い込んでました……。jsを直接記述する
header.html<!DOCTYPE HTML> <!-- header共通ファイル --> <script> $('#menuWrap').on('click', function() { $(this).next().slideToggle(); $('#menuBtn').toggleClass('close'); }, function() { $(this).next().slideToggle(); $('#menuBtn').removeClass('close'); }); </script> <div id="headerWrap"> <h1><a href="index.html"><img src="images/logo.png" width="284" height="160" alt="logo"></a></h1> <nav id="mainnav"> <p id="menuWrap"><a id="menu"><span id="menuBtn"></span></a></p> <div class="panel"> <ul> <li><to><a href="index.html"><img src="images/toppage.png" width="130" alt="トップページ"></a></to></li> <li><to><a href="about-us.html"><img src="images/introduce.png" width="130" alt="楽団紹介"></a></to></li> <li><to><a href="archives.html"><img src="images/archives.png" width="130" alt="過去の演奏会"></a></to></li> <li><to><a href="contact.html"><img src="images/inquiry.png" width="130" alt="お問い合わせ"></a></to></li> </ul> </div> </nav> </div>開閉できた!
所感
今回のようにファイル切り分けてjs読み込むとか、DOM操作して生み出したパーツにjsを当てるときの特殊なお作法とか、js(およびjQuery)はわりと引っかかりやすいポイントありますね……。
慣れなのかな。
- 投稿日:2020-05-19T00:13:04+09:00
AnalyserNodeのサンプルを動かしてみた
MDN の AnalyserNode のサンプルコードは入力の部分が省略されていたため、マイクから音を拾うようにして動かしました。
埋め込みだとマイクがうまく動かないので、動作確認は CodePen を開いてください。
【追記】 同時に
getByteFrequencyData
による周波数分析を行うサンプルを作成しました。概要
MDN に AnalyserNode のサンプルコードが掲載されています。
var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); var analyser = audioCtx.createAnalyser(); ... analyser.fftSize = 2048; var bufferLength = analyser.frequencyBinCount; var dataArray = new Uint8Array(bufferLength); analyser.getByteTimeDomainData(dataArray); (略)Voice-change-O-matic デモからの引用だと記載されていますが、残念ながらそのデモは使い方が分かりませんでした。
【追記】 MDN 日本語版の情報が古いようです。英語版からリンクされている https の方は動きました。
そこで
...
の部分を補って動くコードにします。【追記】 少し違う API ですが、英語版に完全な形でのサンプルがありました。MP3 を読み込む仕様です。
追加箇所
Canvas とボタンとエラーメッセージ用の span を用意します。
<canvas id="canvas" width="500" height="200" style="border:1px solid #000000;"></canvas><br> <button id="startButton">Start</button> <span id="errorMessage"></span>Canvas 関係の変数と、ボタンをクリックするとマイクから入力を開始するコードを補います。
let canvasCtx = canvas.getContext("2d"); let WIDTH = canvas.width; let HEIGHT = canvas.height; let stream; startButton.onclick = async function () { if (stream) return; try { stream = await navigator.mediaDevices.getUserMedia({ audio: true }); audioCtx.createMediaStreamSource(stream).connect(analyser); } catch (err) { errorMessage.textContent = err.toString(); } };これでとりあえず動くようになりました。
参考
同じ MDN を参照している記事を参考にしました。
API の変更に伴い、以下の個所を修正する必要がありました。
//様々なブラウザでマイクへのアクセス権を取得する navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;【参考】 「MediaDevices.getUserMedia() 」について
以下の個所で別の API を呼んでいるため、表示される波形が別の形になります。
analyser.getByteFrequencyData(data);描画の度にバッファを確保していたため、メモリ使用量がどんどん増加しました。
var bufLen = analyser.frequencyBinCount; var data = new Uint8Array(bufLen);マイクからの入力がそのまま出力に接続されているため、自分の声がそのまま再生されてハウリングの原因になっていました。
analyser.connect(audioCtx.destination);この部分を外しても動作しました。
1つのAnalyzerNodeは必ず1つの入力と出力を持ちます。出力先がなくてもAnalyzerNodeは問題ありません。
色々と書きましたが、まず動くコードが欲しかったので、非常に助かりました。
Python
今回はブラウザで JavaScript を使いましたが、方法を調査しているときに Python を使った記事を見掛けたので、メモしておきます。
- 投稿日:2020-05-19T00:05:16+09:00
Laravel Telescopeのタイムゾーンを強制的に日本時間にする
LaravelのTelescopeにおいて、タイムゾーンを指定してるにもかかわらず日本時間表示ができなかったので、強制的に変えてみました!
localTime()を下記のように修正
vendor/laravel/telescope/resources/js/base.jslocalTime(time) { return moment.tz(time,'Asia/Tokyo') .format('YYYY-MM-DD HH:mm:ss'); },cd /LARAVEL_PATH/vendor/telescope npm run prod cd /LARAVEL_PATH php artisan telescope:publish --forcecross-envをインストールする必要あり
ない場合はnpm install cross-env以上です(^^)