- 投稿日:2019-10-04T23:04:58+09:00
MDNチュートリアル 課題 image garary
...html
<!DOCTYPE html>
Function library example
<h1>Image gallary example</h1> <div class="full-img"> <div id="bg"> <img id="displayed-img"> </div> <button class="dark">Darken</button> <button class="lighten" id="lighten">Lighten</button> </div> <div class="thumbnail-bar"> <ul> </ul> </div>
...javascript
'use strict';{
var images = [ 'img/pic00.png', 'img/pic01.png', 'img/pic02.png', 'img/pic03.png', 'img/pic04.png', ]; // full-imgの現時点の表示インデックス番号 let currentNum = 0; // full-imgの中のimgを取得 var fullImg = document.getElementById('displayed-img'); fullImg.src = images[currentNum]; // setFullImg()関数の定義 function setFullImg(value){ document.getElementById('displayed-img').src = value; } // currentクラスを外す関数 function removeCurrentClass(){ document.querySelectorAll('li')[currentNum].classList.remove('current'); } // currentクラスを新たに付ける関数 function addCurrentClass(){ document.querySelectorAll('li')[currentNum].classList.add('current'); } // thumbnail-barクラスの取得 var thumbnailBar = document.querySelector('.thumbnail-bar'); var ul = document.querySelector('.thumbnail-bar ul'); thumbnailBar.appendChild(ul); images.forEach((value, index) => { const li = document.createElement('li'); if(index === currentNum){ li.classList.add('current'); } li.addEventListener('click', () => { setFullImg(value); removeCurrentClass(); currentNum = index; addCurrentClass(); }); const img = document.createElement('img'); img.src = value; ul.appendChild(li); li.appendChild(img); }); // buttonタグの取得(ボタンをクリックしたら表示画像が暗くなるやつ) var btn = document.querySelector('button'); var bgId = document.getElementById('bg'); var ligBtn = document.querySelector('button.lighten'); btn.addEventListener('click', () => { // 背景色を暗くしたクラスをつける bgId.classList.add('bg'); // Darkenボタンを消す btn.style.display = 'none'; // Lightenボタンのdisplay=noneをなくして新たにボタンを表示させる ligBtn.classList.remove('lighten'); }); ligBtn.addEventListener('click', () => { // bgクラスを外して(暗くしたクラスを外して) bgId.classList.remove('bg'); // Darkenボタンを表示させる btn.style.display = 'block'; // Lightenボタンのdisplay=noneをもつクラスをつけてLightenボタンを非表示にする ligBtn.classList.add('lighten'); });}
...css
body{
user-select: none;
padding: 0;
margin: 0;
text-align: center;
}
.full-img{
display: block;
margin: 0 auto;
position: relative;
width: 600px;
height: 400px;
}
.bg{
background: #000;
}
.bg img{
display: block;
opacity: .7;
/* vertical-align: bottom; */
height: 400px;
}
button.dark, button#lighten{
position: absolute;
top: 0;
left: 0;
cursor: pointer;
}
button.lighten{
display: none;
}
.thumbnail-bar ul{
list-style: none;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
}
.thumbnail-bar ul li:not(:last-child){
margin-right: 5px;
}
.thumbnail-bar ul li{
opacity: .4;
}
.thumbnail-bar ul li.current{
opacity: 1;
}
.thumbnail-bar ul li:hover{
opacity: 1;
}
.thumbnail-bar ul li img{
margin-top: 5px;
width: 116px;
vertical-align: bottom;
cursor: pointer;
user-select: none;
}
- 投稿日:2019-10-04T22:53:41+09:00
Cloud CDN 署名付き URL を作るプログラムの Node.js 向けサンプル
概要
https://cloud.google.com/cdn/docs/using-signed-urls?hl=ja の"署名付き URL をプログラムで作成する" のところに Node.js のサンプルプログラムがないので作ってみた。
準備
$ npm i -S urlsafe-base64 $ npm i -S crypto $ npm i -S momentサンプルプログラム
const URLSafeBase64 = require("urlsafe-base64") const crypto = require("crypto") function signUrl(url, expiration, keyName, key) { const decodedKey = URLSafeBase64.decode(key) const sep = url.indexOf("?") != -1 ? "&" : "?" const signingUrl = `${url}${sep}Expires=${expiration}&KeyName=${keyName}` const signature = crypto.createHmac("sha1", decodedKey).update(signingUrl).digest() const encoded = URLSafeBase64.encode(signature) return `${signingUrl}&Signature=${encoded}` }使い方例
引数 key は、この例のように BASE64 エンコードされたものです。これは Cloud DNS の URL 署名鍵で自動生成されたものを使うことができたり、自分で作ったものを使うことができます。しかし、その署名鍵は安全に保管してください。
誤ってGitHubの公開リポジトリーに公開するとか、Webで公開してしまうとかいったことがないようにしてください。const moment = require("moment") const url = signUrl("https://myhost/path/to/image.jpg", moment().add(1, "hours").unix(), "my-key", "YmFzZTY0ZW5jb2RlZAo=")
- 投稿日:2019-10-04T22:51:12+09:00
turbolinksをfalseのページとtrueのページに分ける
こんばんは!
ポートフォリオ作成中にハマったエラーの簡単な解決方法を備忘録として。いいね機能をremote: trueで動かす
railsチュートリアルにて学習した
remote: true
を使ったajax通信。jsが苦手な私にぴったり!turbolinksが必要みたい
Uncaught ReferenceError: Turbolinks is not defined
application.js/=require turbolinks動きます。
次はこっちが動かないのね
<%= link_to "新規投稿", new_meal_path, class:'hoge'%>
に遷移してfile_field
に画像添付したらimageがpreview表示されなくなったリロードすれば正常に動作します
解決方法
index.html.erb<%= link_to "新規投稿", new_meal_path, class:'hoge',data: {"turbolinks"=>false} %>
data: {“turbolinks" => false}
は遷移先ページのみturbolinksを切ることが出来ますまとめ
jsファイルにajax通信を記述すればturbolinksがtrueでも問題ないみたいです
remote: true
を使ったajax通信とjsイベントを両方実装している時にどちらかのイベント発火しない場合があればdata: {"turbolinks"=>false}
が役立ちます終わり
- 投稿日:2019-10-04T22:45:34+09:00
Cloud CDN 署名付き URL を作るプログラムの Node.js 向けサンプル
概要
https://cloud.google.com/cdn/docs/using-signed-urls?hl=ja の"署名付き URL をプログラムで作成する" のところに Node.js のサンプルプログラムがないので作ってみた。
準備
$ npm i -S urlsafe-base64 $ npm i -S crypto $ npm i -S momentサンプルプログラム
const URLSafeBase64 = require("urlsafe-base64") const crypto = require("crypto") function signUrl(url, expiration, keyName, key) { const decodedKey = URLSafeBase64.decode(key) const sep = url.indexOf("?") != -1 ? "&" : "?" const signingUrl = `${url}${sep}Expires=${expiration}&KeyName=${keyName}` const signature = crypto.createHmac("sha1", decodedKey).update(signingUrl).digest() const encoded = URLSafeBase64.encode(signature) return `${signingUrl}&Signature=${encoded}` }使い方
const moment = require("moment") const url = signUrl("https://myhost/path/to/image.jpg", moment().add(1, "hours").unix(), "my-key", "zPPWQcAfNkFdNU0jnY0n3g==")
- 投稿日:2019-10-04T22:04:02+09:00
JSで配列をn個ずつに分割
- 投稿日:2019-10-04T21:58:30+09:00
JavaScriptの暗黙の型変換(小ネタ)
暗黙の型変換
JavaScriptの暗黙の型変換によるちょっと不思議な動きを以下に記載しました。
const array = ['Alice', 'Bob']; const greeting = `Hello ${array}`;
greeting
をコンソールに出力すると、"Hello Alice,Bob"
が出力されます。文字列+配列(オブジェクト)を行う際、オブジェクトが文字列に変換されることでこのような動作をするとかなんとか。
最後に
仕事中にたまたま見つけた挙動ですが、こんな動きするとは思いませんでした。
まだまだ勉強不足だなと思った次第です。(他の言語でもこのような動きするものあるんですかね…?)JavaScriptで文字列結合するときは、結合元にどんな値が入っているか確認してから行わないと意図しない文字列になったりするので、気をつけたいところです。
- 投稿日:2019-10-04T21:13:57+09:00
YYTypeScript#3「VueをTSで書いて良かったこと、大変だったことを教えて!」「React Hooksの最適な粒度って?」「クライアントサイドDDD」「皆さん、decorator自作してますか?」「Node.jsゼロインストールのメリットって何?」
これは2019年10月4日に開催したTypeScriptイベントYYTypeScript#3のイベントレポートです。
YYTypeScriptは一言で「TypeScripterの部室」です。発表者の話を聞く「一方向的な勉強会」とは真逆で、TypeScriptについて、雑に・ゆるく・ワイワイ話しながらTypeScripter同士の交流を深める「双方向的な座談会」の形式になります。集まった人たちで「今日話たいこと」「聞きたいこと」をいくつか挙げていき、それをテーマに雑談していきます。
今回の配信動画
今日のYYTypeScriptの収録をアップしました!https://t.co/qDy7W8y8ux
— suin❄️TypeScriptが好き (@suin) October 4, 2019過去回の配信動画 → YouTubeプレイリスト「YYTypeScript」
前回 → YYTypeScript#2「トランスパイル後のJSのパフォーマンス」「npmモジュールの信頼性、どう担保してる?」「コンパイルが遅い」「みんなのtslintの設定とかTipsを教えて」「オブジェクトの構築と実行について」 - Qiita雑談
Vue.jsをTypeScriptで書いて良かったこと・大変だったことを聞きたい (にしかわ)
- メリット
- 型の情報が手に入る
- propsでバリデーションは定義できるが、いちいち定義まで戻らなくてもstringなのか、numberなのかIDE/editorで分かる。
- JSからTSに移行することのメリットと一致すると思う。
- 大変だったこと
- Vue.jsとTSの相性があんまりよくない。
- HTMLテンプレート内で型チェックもIDEの型補完が効かない。
- VS Codeではプラグインありませんでしたっけ?
- まだ対応しているプラグインはないと思います。
- WebStormも無理でした。
- Reactは全部JSなので、このへんは羨ましい。
・・・
- 良かったこと
- ドキュメントの代わりになる
- 大変だったこと
- Nuxtまわりで苦労した
- Vuexが面倒だったので、observableでやった
- Vuexとは?
- Fluxアーキテクチャ、unidirectional data flowを実現するフレームワーク。
- ビュークスと読む。
- TSを使うならフレームワークと疎結合にすることだと思って、設計を考えた。
- React
・・・
- 良かったこと
- ktsn/vuex-smart-module: Type safe Vuex module with powerful module featuresを使うと、Vuexで冗長な型情報を書かなくてよくなる
・・・
- 型のメリットを得られることも、得られないことも。
- 頑張らないTypeScriptで始めるのもあり
- TypeScript再入門「がんばらないTypeScript」で、JavaScriptを“柔らかい”静的型付き言語に(gfx執筆) - エンジニアHub|若手Webエンジニアのキャリアを考える!
- コンパイラ設定はキツ過ぎず、緩すぎないの加減が難しいっす。
- 昔のTSはもっと厳しくて挫折した記憶あり
- コンパイラの設定がある程度キツいと、困ったときに、どうすればいいのかわからないとかあるのかも
- 慣れてると、どこにエラーが出てるかとか見ると、どこを修正すればいいかわかるけど、エラーが大量に出るようなケースだと、初学者は悩むかも
- エラーが連鎖するようなやつとか)
React Custom hooksのどの粒度で切ればいいか、設計について聞きたい (ドラレプ)
hooksとは?
- もともと、Reactはclassでコンポーネントを書く
- その後、function componentという関数で書けるコンポーネントも出てきた。
- ステートレスの流れで。
- function component(React.FC)に状態を入れられるようになった。
- 正確にいうと、function componentじゃないと動かない(クラス型だとだめ)
- 状態を入れられる機能がhooks。
どういう課題があるのか?
- Hooksは(カスタムフックとかも含めて)めちゃくちゃ自由度が高い
- これは、設計をクリーンにするっていう方向性に持って行ける利点がある
- ベタにコンポーネントを書くと、コンポーネントがアホみたいに肥大化する(1関数に全部ぶち込む感じ)
- function componentに直接コードを書くのはアンチパターン
- useEffectとかのコールバック経由で書く必要がある(考え方を少し変える必要あり)
erukiti式
- まずはベタにコンポーネントを書く
- で、カスタムフックに外だしできるものを外だしする
- 切り分けは、責務とか意味で切り分けるといいかも
- あ、あとカスタムフックは、unit test できるので、テストしやすい作り方を考慮するといいかも
実際、React Hooksは、デザインパターンなり、ある程度フックスの書き方指針は必要だなーと常々思ってます
クライアントサイドDDDってどんなの? (すいん)
- やろうとしたが断念した。
- 純粋に自分の中で正解が見つからないまま時間がたったので。
- 得られたこと
- インフラ層のDIPすると、GraphQLから別のにできるのはフロントエンドでも良さそう
- TS/JSでDIってどうやってる?
- DIコンテナ何使ってる?
- InversifyJS a powerful IoC container for JavaScript apps powered by TypeScriptってのもあるよ。
- DIは考えるんじゃなくて感じるんだ!!!!
- 先週張った https://github.com/noxtjs/gateway はそれやるライブラリです
- クライアントサイドでドメインをと考えると、画面固有のDDDになりそう
- Humble Object Pattern 重要(プレゼンテーションとビューを分ける。テスタブルなのをpresentationに)
- クライアントサイドの関心は画面なので。
- DDD/The Clean Arcthiecture は、ユースケースから考えると良いです
- TypeScript 必須(と思う)
- interface or type を切ったり、DIPを工夫したりが必須
- 知識を分離するのがミソですね
- 画面側はClean Architectureで感がたほうがすっきりしそうな気がする
decorator自作していますか?使っているとしたらどんな機能を作ったのか聞きたい。(ましろ)
- decoratorって?
- デコレータ | TypeScript 日本語ハンドブック | js STUDIO
- インターフェイスを変えずに機能を追加できる
- デコレータパターンを言語仕様に取り込んだものよね
@foo class Bar { }
- decoratorはexperimentalな機能ではあるが、結構使われている
- アスペクト指向的なやつを作ってみたいかな。
- Railsのdelegate的なdecoratorを書いたことある
- TypeScript: デコレーターで実行時もイミュータブルなクラスを実現する - Qiita
- 使い方が自分でなかなか思いつかないんですよね。
- デコレータパターンから考えたほうがいいかも。
- Decorator
「Node.jsでゼロインストール」のユースケースって? (すいん)
- 元ネタ
- https://yosuke-furukawa.hatenablog.com/entry/2019/06/10/113111
- npm tink や yarn v2 (berry)のような、次世代パッケージマネージャに入る予定の機能
- 今回やったやつは実験目的ではあるんだけど、基本的にはゼロインストールの方向性は今後のびると思ってたり
- デプロイするときは、普通に install すればいいと思う
- 想定ユースケース
- 実験的に動かしたい時に、いちいちnode_modulesが肥え太るとめんどい!!!!!(サイズとか)
- つまり、雑に動かしたいときに使う! & 開発者に優しい
- プロダクションだともう、普通に install しちゃえばいいと思う
- ブログにも書いてるけど、git とかから引っ張ってきて、インストールせずに動く
- 起動に何分も待ちたくないとき
- ちなみに軽いモノを動かす程度なら時間は掛からない(fetch すぐ)
- どう次世代か?
- 結構ハックが必要なので、時間がかかりそうなので次世代かなー感
- native module とか presintall scripts とかの対処も面倒(課題解決待ちなところあるとは思う)
- あと、deno がパッケージシステムを完全否定してるので、時代の流れ??
- パッケージって、Node.js固有なのでブラウザとの互換性が気になる人たちもいる感じ(denoもブラウザとの互換性を大切にしてる)
- あと、ゼロなんとかが流行り
- ゼロコンフィグ(ParcelとかWebpack v4とかNext/Nuxtとか)
- 遅延インストールみたいな感じ?なんでしょうか
- かなー?キャッシュがあればキャッシュから引っ張ってくるし
- 前回 npm-package のセキュリティどうなの?みたいのあったけど影響無いですかね?
- いちおうハッシュ値とってたりするので、そこらへんで確認ですかね
'localhost'と127.0.0.1の違いって何? (かきうち)
- localhost vs 127.0.0.1
- localhostの参照先は
/etc/hosts
に記述されている- localhostの名前解決→IPアドレス分かる→そのIPアドレスに繋ぐ。
- MySQLの場合の違い
- localhostだとunix domain socketがあればそれでつなぎにいく。
開始前の雑談
- philomagiさんがゆめみさんのイベントでしたLTの話
- v-if便利だけど、else-ifが重なってきたり、条件が複雑になってくると大変。
- 複雑なv-ifに負けないために - Speaker Deck
- ↑の発表内で公開したサンプルアプリです
おすすめほん
- 【冊子・PDF】TypeScript CompilerAPI - 創出の落書帳 - - takepepe - BOOTH
- 【PDF】TypeScript CompilerAPI - 創出の落書帳 - - takepepe - BOOTH
・・・
- そういや、これがとても良かったです(TS compiler API でメタプロするやつ)
- babel で無理矢理TSメタプロするよりは良さそう・・・
- そういえば、この本にも、Vuexの型付けの話、載ってましたね!
・・・
- TypeScript compilerAPI 使うと、型情報取ったりとかで遊べます!
- Vuexとかで悩んでる人の救世主になるかも!
- 定義生成で、いうと gRPCとかGraphQLとかと合わせて何か遊べるかも
参加してよかったこと(参加者の感想)
- このyy形式が凄く面白い。
- 聞いたことない単語を聞けたこと
- localhost 127.0.0.1 の違いがふわっとわかった
- ずっとVue.jsを書いてたので、Reactの情報が聞けて良かったです。
- 色々助けてくれそうなライブラリ/ツールの存在を知ることが出来た
- 改めて知らなかったことがたくさんあるなーと感じて、今後色々と触ってみたいものが増えました!
YYTypeScriptは毎週やってます
YYTypeScriptについてワイワイ話したい方は、YYTypeScriptのイベント情報をチェックしてみて下さい。
以上、YYTypeScriptのレポートでした。次回もワイワイやっていきたいと思います! では、また来週!
- 投稿日:2019-10-04T20:19:28+09:00
Ajaxの説明とJQueryによる簡易実装
初めに
前の座席の同僚に「お前、Ajaxって知ってる?」と言われたことが悲しくて執筆に至ります。
本記事はAjaxに関する簡単な説明と処理の実装を目的としています。Ajaxとは
Ajaxとは、「Asynchronous JavaScript + XML」の略です。
直訳すると、「非同期のJavaScriptとXML」となります。
そもそも非同期とは何のことでしょうか。同期通信と非同期通信
まず初めにブラウザとサーバのHTTP通信の基本的な流れについて説明します。
- ブラウザ:サーバに対してリクエストを送信
例:Google検索窓に「小松菜奈」と入力してクリック- サーバ:ブラウザからのリクエストを処理
例:「小松菜奈」に関するデータを抽出し、良い具合に加工- サーバ:2の処理完了後、ブラウザにレスポンスを送信
例:加工済み「小松菜奈」データを送信- ブラウザはレスポンスに基づき画面を描画す 例:「小松菜奈」に関する検索結果が表示
以上のように、ブラウザとサーバ間ではリクエストとレスポンスのやり取りがされます。
1~4を一連の流れとしたとき、
4まで完了しないと1の操作が不可能なものが同期処理、
4まで完了していなくても(任意のタイミングで)1の操作が可能なものが非同期処理
です。より簡単に言うと、
・同期通信:通信が完了するまで次の処理を行うことができない通信、
・非同期通信:通信の途中でも他の処理を行うことができる通信
となります。XML
ところで「Asynchronous JavaScript + XML」のXMLとは一体何のことでしょうか。
XMLは、「Extensible Markup Language」の略で、文章の意味や内容、構造をタグを用いて整理するマークアップ言語の一つです。他の代表的なマークアップ言語にはHTMLがあります。
Webページの見た目を整えるHTMLに対し、XMLは、機械に対して情報を伝達するのに長けていると言われています。
また、W3C(World Wide Web Consortium)によるオープンな規格であることから、多くのシステムに対する汎用性もあり、注目度の高い言語となっています。ここまでのまとめ
Ajaxとは、
1. JavaScriptを用いて、
2. XML形式のデータを、
3. 非同期に通信する
技術だと理解しておけばよいでしょう。Ajaxの実装例
環境
- macOS High Sierra 10.13.6
- JQuery 3.4.1
- PHP 7.1.16
それではAjaxを用いた簡単な処理を実装していきます。
まずはHTMLファイルから。index.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <!-- 今回はJQueryを用いてAjax通信を実現するため、GoogleのCDN経由でJQueryを読み込む --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <title>世界一美しいのは誰か</title> </head> <body> <form method="post"> <p>世界で一番美しい人物の名前を答えなさい</p> <p>あなたの答え:<input type="text" name="answer" id="answer"></p> </form> <button id="ajax">Ajax通信</button> <div class="result"></div> <script> $(function(){ // 「Ajax通信」ボタンをクリックしたら発動 $('#ajax').on('click',function(){ $.ajax({ url:'./nana.php', type:'POST', data:{ 'answer':$('#answer').val() } }) // Ajax通信が成功したら発動 .done( (data) => { $('.result').html(data); }) // Ajax通信が失敗したら発動 .fail( (jqXHR, textStatus, errorThrown) => { alert('Ajax通信に失敗しました。'); console.log("jqXHR : " + jqXHR.status); // HTTPステータスを表示 console.log("textStatus : " + textStatus); // タイムアウト、パースエラーなどのエラー情報を表示 console.log("errorThrown : " + errorThrown.message); // 例外情報を表示 }) // Ajax通信が成功・失敗のどちらでも発動 .always( (data) => { if($('#answer').val() == '小松菜奈'){ console.log('あなたは正しい'); }else{ console.log('あなたは間違っている'); } }); }); }); </script> </body> </html>ソースコードのコメントをお読みいただくと理解が深まるかと思います。
console.logはよくデバッグに用いられるので、開発中にどの処理を通過しているのかを探るときに便利です。次にPHPファイルです。
nana.php<?php header('Content-type: text/plain; charset= UTF-8'); if(!empty($_POST['answer'])){ $answer = $_POST['answer']; if($answer == '小松菜奈'){ $result = $answer."は世界一美しい"; }else{ $result = $answer."は世界一美しいわけではない"; } echo $result; }else{ echo '文字を入力してください'; } ?>中身の処理はシンプルで、Ajaxで送信されたinput要素の値を$_POST['answer']で取得し、その値によって返すデータを変えています。
全体の流れ
ローカルサーバとしてPHPのビルトインサーバを用いました。
PHPがインストールされていれば、php -S localhost:ポート番号
で立てることができます。
以下、通信が成功した例を示します。
1. ~/index.htmlをブラウザで表示すると以下のようになる。
2. フォームに文字を入力し「Ajax通信」ボタンを押下。
ここで、入力した値がブラウザからサーバへ送信される。
3. 送信された値がnana.phpファイル内で処理され、加工された値が返却される。
※このnana.phpファイルはサーバ内に存在。
4. 返却された値をブラウザが受け取り、.doneの処理を実行し、描画。
また、上図のようにコンソールに出力がある。これは、通信成功と失敗に関わらず以下の処理が実行されたためである。
上記の1~4の手順において、ページの切り替えが生じないこともAjaxの利便性としてよく挙げられる。
終わりに
浅学ながらフロント開発には欠かせないAjaxの基本について執筆させていただきました。
誤りがありましたらコメントにてご指摘いただけると幸いです。参考文献
- 投稿日:2019-10-04T19:14:43+09:00
ボタン連打、連続クリックを止める
更新ボタンを連打されAjaxの処理を重複させない為に、処理中にボタンを無効にしたい。
無効時はボタンの色を薄くして、わかるようにする。処理概要
①フラグとなる適当な変数を定義。
ここでは「cancelFlag」とする。②クリック時にボタンを無効にし色を変更。フラグを立てる。
③クリック時に行いたい処理を書く(書き換え、送信処理など)。
ここではAjaxの処理の入った「refreshTableファンクション」を呼んでいる。コードは割愛。④処理完了後、指定時間後にボタンを有効にし色を戻す。
その後、フラグを元に戻す。
ここでは、仮に処理が1秒程かかるとして、1秒間だけ無効にする。補足
●disabled
無効化。if文で無効/解除を切り替えられる。●addClass( )
既存の CSS クラスを追加する場合に使用●removeClass( )
既存の CSS クラスを削除する場合に使用a.html<script> //フラグとなる変数を定義 var cancelFlag = false; //更新ボタン $('#refresh').click(function(event){ //連打防止設定 if( cancelFlag == false ){ $('#refresh').prop('disabled', false).addClass('sending'); cancelFlag = true; //処理内容 refreshTable(function(){});//これは例 //処理完了後 setTimeout(function(){ $('#refresh').prop('disabled', true).removeClass('sending'); cancelFlag = false; },1000); } }); </script> <span id="refresh" class="btnst">更新</span>b.css.btnst { background-color: #red; /*ボタン無効時の色を設定。色は適当*/ .sending { background-color: #pink;
- 投稿日:2019-10-04T18:31:11+09:00
javascriptで日時のタイムスタンプ文字列を生成する
JavaScriptだけでDateをフォーマットするのは面倒です(0埋めが必要だったり、getMonthが0-11を返すとか・・・)
moment.jsを使うがお勧めですが、手元でちょいとフォーマットしたい的な際のサンプルです。
// 現在日時からタイムスタンプのファイル名を生成 const d = new Date(); // Today const DateTimeFormat = 'YYYYMMDD_hhmiss'; // "2019/10/04 12:34:56" -> "20191004_123456" let toFileName = DateTimeFormat .replace(/YYYY/g, String(d.getFullYear())) .replace(/MM/g, ('0' + (d.getMonth() + 1)).slice(-2)) .replace(/DD/g, ('0' + d.getDate()).slice(-2)) .replace(/hh/g, ('0' + d.getHours()).slice(-2)) .replace(/mi/g, ('0' + d.getMinutes()).slice(-2)) .replace(/ss/g, ('0' + d.getSeconds()).slice(-2));DateTimeFormat文字列を変更すれば、お好きな形式に整形できます。
const DateTimeFormat = 'YYYY/MM/DD hh:mi:ss'; // "2019/10/04 12:34:56" -> "2019/10/04 12:34:56"
- 投稿日:2019-10-04T18:18:41+09:00
React Map<K,V>型でループしてコンポーネントを返したい。
表記のとおり、Map型でループしてコンポーネントを返したい場合、
function Qiita(props: { chikyuwaMawaruMap: Map<Date, Unit> }) { return ( //NG Map<>型でループできる方探してたらforEach があったのでreturn returnで返るのかなと憶測で考えていたけどだめでした。Object.entries() する必要があるみたいです。 return ( {props.chikyuwaMawaruMap.forEach((value, index) => { return(<JikkoWaSarerukedoReturnSarenai />) }} ) //OK {Array.from(props.chikyuwaMawaruMap.entries()).map((entry, index) => { Return (<SampleComponent />); }} //FYI interface Map<K, V> { clear(): void; delete(key: K): boolean; forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void; get(key: K): V | undefined; has(key: K): boolean; set(key: K, value: V): this; readonly size: number; }
- 投稿日:2019-10-04T17:11:52+09:00
俺は "楽して" Reactを "試して" みたいんだよ!
Reactを触ってみたいけど、
- ちょっと敷居高そうだな~
- 環境作るのめんどくさそうだな~
と思っているあなたへ。
ちょっと試してみたいだけなら、とても簡単に環境を用意できます。
以下のコードをHTMLファイルとして保存し、ブラウザで表示してみてください。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>easy react</title> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel"> class HelloWorld extends React.Component { render() { return ( <h1> {this.props.text} </h1> ) } } ReactDOM.render( <HelloWorld text="HelloWorld!!" />, document.getElementById("root") ); </script> </body> </html>
HelloWorld!!
と表示されたと思います。
簡単ですね。
ちょっと試してみたいだけなら、これでも十分です。しかし、このままではVSCodeでオートフォーマットが効きません。
<script type="text/babel">
を<script type="text/javascript">
に書き換えることで、オートフォーマットが効くようになります。
コードを書いているときはtext/javascript
、実行するときはtext/babel
といった具合に使い分けましょう。興味が湧いたら、ぜひ公式へ!
React 公式ページ
- 投稿日:2019-10-04T16:19:05+09:00
[JavaScript] console.time() で処理時間を計測する
- 投稿日:2019-10-04T16:00:27+09:00
ExpressでさらっとAPI
まずは読み込み
const app = new (require('express'))() const port = 3000 const bodyParser = require('body-parser') const mysql = require('mysql')dbの設定(localhost)
const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'ぱすわーど', database: 'でーたべーすめい' });dockerを使う場合は
host: 'localhost'
をDockerのコンテナに合わせて変える。
bodyPaserの設定
app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json());hogeテーブルの一覧を表示
app.get('/hoge',(req,res) => { connection.query('select * from hoge_table', function (error, results, fields) { if (error) throw error; res.send(results); }); })hogeテーブルにデータを追加
app.post('/hoge',(req,res) => { const fuga = req.body.fuga; connection.query('INSERT INTO hoge_table SET ?', { fuga: fuga }, (err, result) => { if (err) throw err; res.send(result); }) })hogeのidで返す
app.get('/hoge/:id',(req,res) => { const id = req.params.id res.send({'id': id}) })サーバーを呼ぶ
app.listen(port, error => { if (error) { console.error(error); } else { console.info('listen: ', port); } });オワオワリ
- 投稿日:2019-10-04T13:28:08+09:00
JSON.parse()でSyntaxErrorが出続けるときの対策
1. 状況
pythonから出力したjson文字列を変数としてhtmlに貼り付けして,JSON.parse()したのちDatatablesを利用しようとしたところ,jsonの構文に誤りがないにもかかわらず下記のエラーが出た.
Uncaught SyntaxError: Unexpected token in JSON at position 3今回はconsole.log()した時点で\u0008に相当する「」(←多分表示されない)が見えたが,特殊文字の中にはconsole.log()で表示される特殊文字と出ないものがあるので注意する.
2.対策コード
stackoverflowに対策コードがあった.JSON.parse()でjsonの構文に誤りがないのにエラーが出る場合,とりあえずこれ貼っておけば良さそう.
// preserve newlines, etc - use valid JSON s = s.replace(/\\n/g, "\\n") .replace(/\\'/g, "\\'") .replace(/\\"/g, '\\"') .replace(/\\&/g, "\\&") .replace(/\\r/g, "\\r") .replace(/\\t/g, "\\t") .replace(/\\b/g, "\\b") .replace(/\\f/g, "\\f"); // remove non-printable and other non-valid JSON chars s = s.replace(/[\u0000-\u0019]+/g,"");3.参考
https://stackoverflow.com/questions/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse
https://qiita.com/qwq00/items/9cd8b8e095bea0633a88
- 投稿日:2019-10-04T13:23:35+09:00
JavaScirpt オブジェクト配列のコールバック処理サンプル
JavaScriptの配列で、コールバック関数を使って処理するサンプルです。
数値配列のサンプルは多いのですが、オブジェクトの配列を処理するサンプルが少ない気がしたので。
var list = [ { id: "A01", name: "yama" }, { id: "B02", name: "matu" }, { id: "C03", name: "moto" }, { id: "D04", name: "sato" }, ]; console.log(`${list.length} Members`); // "4 Members" // find let m; m = list.find(function (x) { return x.id == "C03"; }); console.log(`${m.id} is ${m.name}.`); // "C03 is moto." // 簡略形式(上記と同じ) m = list.find(x => x.id == "C03"); console.log(`${m.id} is ${m.name}.`); // "C03 is moto." // 全件処理(forEach) list.forEach(x => console.log(`- ${x.id} : ${x.name}`)); // - A01 : yama // - B02 : matu // - C03 : moto // - D04 : sato // 加工した別配列を作る(map) let nameList = list.map(x => x.name.toUpperCase()); console.log(nameList); // [ 'YAMA', 'MATU', 'MOTO', 'SATO' ] // 配列を1つにまとめる(reduce) let title = list.reduce((a, b) => { return a += b.name[0].toUpperCase(); // nameの最初の一文字を取得し大文字に }, ""); console.log(title); // "YMMS" // IDが一番大きい人は? let maxIdMember = list.reduce((a, b) => { return a.id > b.id ? a : b; }); console.log(maxIdMember); // { id: 'D04', name: 'sato' } // filter console.log(list.filter(x => x.name[0] == "m")); // [ { id: 'B02', name: 'matu' }, { id: 'C03', name: 'moto' } ] // sort list.sort((a, b) => a.name > b.name); // sort()は、配列を変更する。 console.log(list); // [ { id: 'B02', name: 'matu' }, { id: 'C03', name: 'moto' }, { id: 'D04', name: 'sato' }, { id: 'A01', name: 'yama' } ]
- 投稿日:2019-10-04T11:32:03+09:00
RxJSを使用せずにswitchMap(flatMapLatest)を実現する
APIにリクエストした時に最後のリクエスト結果だけを取得したいと思う時があり、RxJSのswitchMapに頼ることがあったけど、少し考えてみればなんてことのない処理で実現できた。
最新のPromiseの結果だけを実行する関数function createPromiseLatest(callback) { let latestPromise = null; // 最後に実行したいPromiseを管理 return function promiseLatest(promise) { latestPromise = promise; // 追加されたPromiseを取得 promise.then((value) => { // 最後に実行したいPromiseと追加されたPromiseが一致したら実行 if (latestPromise === promise) { callback(value); } }); } }使い方function sleep(ms, value) { return new Promise((resolve) => setTimeout(() => {resolve(value);}, ms)); } const callback = (value) => { console.log('Hello ' + value); } const promiseLatest = createPromiseLatest(callback); // 1件目、2件目は処理されるが出力対象にはならない promiseLatest(sleep(1000, "Mike")); promiseLatest(sleep(2000, "Henry")); promiseLatest(sleep(3000, "Bob")); // console log: Hello Bobちなみに最初のPromiseだけ処理したい場合なら下記でできる。
最初のPromiseの結果だけ実行する関数function createPromiseFirst(callback) { let firstPromise = null; // 最初に実行したいPromiseを管理 return function promiseFirst(promise) { if (firstPromise !== null) return; // Promiseがすでにあるなら処理しない firstPromise = promise; promise.then((value) => { callback(value); }); } }使い方function sleep(ms, value) { return new Promise((resolve) => setTimeout(() => {resolve(value);}, ms)); } const callback = (value) => { console.log('Hello ' + value); } const promiseFirst = createPromiseFirst(callback); // 2件目、3件目は処理されるが出力対象にはならない promiseFirst(sleep(1000, "Mike")); promiseFirst(sleep(2000, "Henry")); promiseFirst(sleep(3000, "Bob")); // console log: Hello Mike便利なものを知りすぎると、すぐにそれにばっかり頼ってしまうので、気をつけたい?
- 投稿日:2019-10-04T11:12:53+09:00
v-bind:disabledで配列構文が書けなかった話
はじめに
2回目の投稿です。
分からないことだらけで勉強中なので、アウトプットの練習にQiitaで投稿しています。
何か間違いなどあれば教えてください。やろうとしたこと
Vueでフォームのバリデーションを作りたかった。
- 名前に禁止文字(ゼロ幅スペースとか)が含まれているか確認するnameValid
- 名前欄を含む入力項目に不備があるか確認するvalid
という、二種類のバリデーションをcomputedに作り、1に引っかかった場合はフォーム下に「登録できない文字が入っています」といった警告文を出し、1と2いずれかに引っかかっている時は「登録」のボタンが押せないようにしようとした。
タイトルの通り、登録ボタンのところでv-bind:disabled
で配列構文を用いて以下のように書こうとしたところ、上手くいかず。v-bind:disabled="[!valid, !nameValid]"原因
必要なデータがbooleanだから。
boolean型について
trueまたはfalseのどちらかのデータが必ず入ることが決まっているデータ型のこと。
改善案
論理演算子を使う。
v-bind:disabled="!valid || !nameValid"→今度は上手くいったー
おわりに
そもそもVueのドキュメントに「v-bind:style 向けの配列構文は、同じ要素に複数のスタイルオブジェクトを適用することができます」としか書いてないんですよね…
そりゃあ上手くいかないわけです。boolean型についても全然理解できていませんでした。
もっと勉強します。参考
【Java入門】booleanとBooleanの使い方(初期値も解説) https://www.sejuku.net/blog/41241
論理演算子 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators
- 投稿日:2019-10-04T10:59:34+09:00
Videojs 7 + RTMP の使用法
はじめに
こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.htmlObjective・目的
Learning how to use videojs + RTMP through a simple example.
videojs + RTMP through の簡単な例を学ぶこと。A simple implementation ・ 簡単な実装
<!DOCTYPE html> <html> <head> <title>Videojs 7 + RTMP (flash)</title> <meta charset="utf-8"> <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/video.js/7.6.5/video-js.min.css" /> <script src="//cdnjs.cloudflare.com/ajax/libs/video.js/7.6.5/video.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/videojs-flash/2.1.2/videojs-flash.min.js"></script> <script src="//cdn.jsdelivr.net/npm/videojs-flashls-source-handler@1.1.2/dist/videojs-flashls-source-handler.min.js"></script> </head> <body> <video class="video-js vjs-default-skin" id="video-container" controls muted autoplay > <source src="rtmp://fms.105.net/live/rmc1" type="rtmp/mp4"> </video> </body> <script> var options = { flash: { swf: '//cdnjs.cloudflare.com/ajax/libs/videojs-swf/5.4.2/video-js.swf' }, fluid: true }; var player = videojs('video-container', options); </script> </html>Compatibility ・ウェブブラウザの互換性
Browser Compatibility Safari 12 Desktop YES Firefox 69 Desktop YES Chrome 74 Desktop YES Information sources ・ 情報源
https://www.wowza.com/community/questions/50896/live-247-rtmp-stream-demo-url.html
https://github.com/videojs/video.js
- 投稿日:2019-10-04T10:57:14+09:00
JavaScript 覚えておくべき注意点!(2)条件分岐について if文で条件分岐 例・ピザ屋注文
if文は条件文の基本
if文は「もし~ならば~する」で、基本文です。「~ならば」という部分を「条件式」と言います。
if.jsvar budget = 2000; if (budget >= 1500) { alert('ピザを注文します'); // budgetは2000で、1500以上なのでこの行は実行されます。 } /* 上の文は、「所持金:budget」は2000ですと、宣言し。 「if(もし)」「budgetが1500以上(ならば)」、「alert('ピザを注文します')」 という意味を表わしています。 */条件式の結果は「true」か「false」になります。
条件式の基本は、左辺と右辺の比較です。
if (budget >= 1500) { }
例えば上記の >= が比較演算子といいます。
下記は比較演算子一覧です。hikaku.js=== // 厳密に等しい == // 等しい !== // 厳密に等しくない != // 等しくない > // ~より大きい >= // ~以上 < // ~より小さい <= // 以下所持金に応じて注文結果を分岐させてみる
入力ダイアログボックスで受け取ったデータは全て文字列です。
そのため正しい計算が出来ない場合があります。
こうした場合、データ型を変換する便利な関数があります。
a = parseFloat(a); です。app.jsvar budget = prompt('所持金を数字で入力してください'); budget = parseFloat(budget); if (budget >= 1500) { alert('ピザを注文しました'); }if文の応用的な書き方を学びましょう
「if~else文」「if~else if文」「if文の組み合わせ」
if-else.js// 「if ~ else 文」 if (条件式) { 条件式が真のとき行う処理 } else { 条件式が偽の時に行う処理 } // 「if ~ else if 文」 if (条件式1) { 条件式が1のときに行う処理 } else if (条件式2) { 条件式が1で偽で、条件式2が真のとき行う処理 ⋮ } // 「if文の組み合わせ」 if (条件式1) { 条件式1が真のときに行う処理 if (条件式2) { 条件式1~2真のときに行う処理 } else if(条件式3) { 条件式2が偽で、条件式1、3が真のときに行う処理 } else { 条件式2~3が偽で、条件式1が真のときに行う処理 } }ケースごとに条件を分けてみる
pizza.jsvar budget = prompt('所持金を数字で入力してください'); budget = parseFloat(budget); if (budget >= 1500) { alert('ピザを注文しました'); } else if (budget >= 500) { alert('ポテトを注文しました'); } else { alert('節約、節約...'); }