20191004のJavaScriptに関する記事は20件です。

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;
}

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

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=")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

turbolinksをfalseのページとtrueのページに分ける

こんばんは!
ポートフォリオ作成中にハマったエラーの簡単な解決方法を備忘録として。

いいね機能をremote: trueで動かす

railsチュートリアルにて学習したremote: trueを使ったajax通信。jsが苦手な私にぴったり!

turbolinksが必要みたい

Uncaught ReferenceError: Turbolinks is not defined

application.js
/=require turbolinks

demo

動きます。

次はこっちが動かないのね

<%= link_to "新規投稿", new_meal_path, class:'hoge'%>に遷移してfile_fieldに画像添付したらimageがpreview表示されなくなった

リロードすれば正常に動作します

demo

解決方法

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}が役立ちます

終わり

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

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==")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JSで配列をn個ずつに分割

何気にいろんなとこで使うのでメモしてると思っていたが、なかったのでメモ。

コード

const split = (array, n) => array.reduce((a, c, i) => i % n == 0 ? [...a, [c]] : [...a.slice(0, -1), [...a[a.length - 1], c]], [])

使い方

split([1, 2, 3, 4], 2) // -> [[1, 2], [3, 4]]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptの暗黙の型変換(小ネタ)

暗黙の型変換

JavaScriptの暗黙の型変換によるちょっと不思議な動きを以下に記載しました。

const array = ['Alice', 'Bob'];
const greeting = `Hello ${array}`;

greetingをコンソールに出力すると、"Hello Alice,Bob"が出力されます。

文字列+配列(オブジェクト)を行う際、オブジェクトが文字列に変換されることでこのような動作をするとかなんとか。

最後に

仕事中にたまたま見つけた挙動ですが、こんな動きするとは思いませんでした。
まだまだ勉強不足だなと思った次第です。(他の言語でもこのような動きするものあるんですかね…?)

JavaScriptで文字列結合するときは、結合元にどんな値が入っているか確認してから行わないと意図しない文字列になったりするので、気をつけたいところです。

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

YYTypeScript#3「VueをTSで書いて良かったこと、大変だったことを教えて!」「React Hooksの最適な粒度って?」「クライアントサイドDDD」「皆さん、decorator自作してますか?」「Node.jsゼロインストールのメリットって何?」

これは2019年10月4日に開催したTypeScriptイベントYYTypeScript#3のイベントレポートです。

YYTypeScriptは一言で「TypeScripterの部室」です。発表者の話を聞く「一方向的な勉強会」とは真逆で、TypeScriptについて、雑に・ゆるく・ワイワイ話しながらTypeScripter同士の交流を深める「双方向的な座談会」の形式になります。集まった人たちで「今日話たいこと」「聞きたいこと」をいくつか挙げていき、それをテーマに雑談していきます。

今回の配信動画

過去回の配信動画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

・・・

・・・

React Custom hooksのどの粒度で切ればいいか、設計について聞きたい (ドラレプ)

  • hooksとは?

    • もともと、Reactはclassでコンポーネントを書く
    • その後、function componentという関数で書けるコンポーネントも出てきた。
      • ステートレスの流れで。
    • function component(React.FC)に状態を入れられるようになった。
      • 正確にいうと、function componentじゃないと動かない(クラス型だとだめ)
    • 状態を入れられる機能がhooks。
  • どういう課題があるのか?

    • Hooksは(カスタムフックとかも含めて)めちゃくちゃ自由度が高い
      • これは、設計をクリーンにするっていう方向性に持って行ける利点がある
    • ベタにコンポーネントを書くと、コンポーネントがアホみたいに肥大化する(1関数に全部ぶち込む感じ)
    • function componentに直接コードを書くのはアンチパターン
      • useEffectとかのコールバック経由で書く必要がある(考え方を少し変える必要あり)
  • erukiti式

    • まずはベタにコンポーネントを書く
    • で、カスタムフックに外だしできるものを外だしする
    • 切り分けは、責務とか意味で切り分けるといいかも
    • あ、あとカスタムフックは、unit test できるので、テストしやすい作り方を考慮するといいかも
  • Essential React Hooks Design Patterns - ITNEXT

  • 実際、React Hooksは、デザインパターンなり、ある程度フックスの書き方指針は必要だなーと常々思ってます

クライアントサイドDDDってどんなの? (すいん)

  • やろうとしたが断念した。
    • 純粋に自分の中で正解が見つからないまま時間がたったので。
    • 得られたこと
      • インフラ層のDIPすると、GraphQLから別のにできるのはフロントエンドでも良さそう
  • TS/JSでDIってどうやってる?
  • クライアントサイドでドメインをと考えると、画面固有のDDDになりそう
    • Humble Object Pattern 重要(プレゼンテーションとビューを分ける。テスタブルなのをpresentationに)
    • クライアントサイドの関心は画面なので。
    • DDD/The Clean Arcthiecture は、ユースケースから考えると良いです
  • TypeScript 必須(と思う)
    • interface or type を切ったり、DIPを工夫したりが必須
    • 知識を分離するのがミソですね
  • 画面側はClean Architectureで感がたほうがすっきりしそうな気がする

decorator自作していますか?使っているとしたらどんな機能を作ったのか聞きたい。(ましろ)

@foo
class Bar {

}

「Node.jsでゼロインストール」のユースケースって? (すいん)

Node.jsでゼロインストールを実現する - Qiita

  • 元ネタ
  • 今回やったやつは実験目的ではあるんだけど、基本的にはゼロインストールの方向性は今後のびると思ってたり
    • デプロイするときは、普通に 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があればそれでつなぎにいく。

開始前の雑談

おすすめほん

・・・

  • そういや、これがとても良かったです(TS compiler API でメタプロするやつ)
  • babel で無理矢理TSメタプロするよりは良さそう・・・
  • そういえば、この本にも、Vuexの型付けの話、載ってましたね!

・・・

  • TypeScript compilerAPI 使うと、型情報取ったりとかで遊べます!
  • Vuexとかで悩んでる人の救世主になるかも!
  • 定義生成で、いうと gRPCとかGraphQLとかと合わせて何か遊べるかも

参加してよかったこと(参加者の感想)

  • このyy形式が凄く面白い。
  • 聞いたことない単語を聞けたこと
  • localhost 127.0.0.1 の違いがふわっとわかった
  • ずっとVue.jsを書いてたので、Reactの情報が聞けて良かったです。
  • 色々助けてくれそうなライブラリ/ツールの存在を知ることが出来た
  • 改めて知らなかったことがたくさんあるなーと感じて、今後色々と触ってみたいものが増えました!

YYTypeScriptは毎週やってます

YYTypeScriptについてワイワイ話したい方は、YYTypeScriptのイベント情報をチェックしてみて下さい。

以上、YYTypeScriptのレポートでした。次回もワイワイやっていきたいと思います! では、また来週!

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

Ajaxの説明とJQueryによる簡易実装

初めに

前の座席の同僚に「お前、Ajaxって知ってる?」と言われたことが悲しくて執筆に至ります。
本記事はAjaxに関する簡単な説明と処理の実装を目的としています。

Ajaxとは

Ajaxとは、「Asynchronous JavaScript + XML」の略です。
直訳すると、「非同期のJavaScriptとXML」となります。
そもそも非同期とは何のことでしょうか。

同期通信と非同期通信

まず初めにブラウザとサーバのHTTP通信の基本的な流れについて説明します。

  1. ブラウザ:サーバに対してリクエストを送信
    例:Google検索窓に「小松菜奈」と入力してクリック
  2. サーバ:ブラウザからのリクエストを処理
    例:「小松菜奈」に関するデータを抽出し、良い具合に加工
  3. サーバ:2の処理完了後、ブラウザにレスポンスを送信
    例:加工済み「小松菜奈」データを送信
  4. ブラウザはレスポンスに基づき画面を描画す 例:「小松菜奈」に関する検索結果が表示

以上のように、ブラウザとサーバ間ではリクエストとレスポンスのやり取りがされます。

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をブラウザで表示すると以下のようになる。
スクリーンショット 2019-10-04 18.59.36.png

2. フォームに文字を入力し「Ajax通信」ボタンを押下。
ここで、入力した値がブラウザからサーバへ送信される。
スクリーンショット 2019-10-04 19.08.22.png

3. 送信された値がnana.phpファイル内で処理され、加工された値が返却される。
※このnana.phpファイルはサーバ内に存在。

4. 返却された値をブラウザが受け取り、.doneの処理を実行し、描画。
スクリーンショット 2019-10-04 19.24.18.png

スクリーンショット 2019-10-04 19.27.05.png

また、上図のようにコンソールに出力がある。これは、通信成功と失敗に関わらず以下の処理が実行されたためである。
スクリーンショット 2019-10-04 19.48.14.png

上記の1~4の手順において、ページの切り替えが生じないこともAjaxの利便性としてよく挙げられる。

終わりに

浅学ながらフロント開発には欠かせないAjaxの基本について執筆させていただきました。
誤りがありましたらコメントにてご指摘いただけると幸いです。

参考文献

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

ボタン連打、連続クリックを止める

更新ボタンを連打され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;

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

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"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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;
 }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

俺は "楽して" 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 公式ページ

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

[JavaScript] console.time() で処理時間を計測する

方法

// delay ミリ秒だけ待機するスリープ関数
let sleep = async delay => new Promise(resolve => setTimeout(resolve, delay));

console.time('タイマー');
await sleep(5000);
console.timeEnd('タイマー');
// タイマー: 5313.85595703125ms

参考

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

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);
    }
});

オワオワリ

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

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

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

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' } ]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

便利なものを知りすぎると、すぐにそれにばっかり頼ってしまうので、気をつけたい?

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

v-bind:disabledで配列構文が書けなかった話

はじめに

2回目の投稿です。
分からないことだらけで勉強中なので、アウトプットの練習にQiitaで投稿しています。
何か間違いなどあれば教えてください。

やろうとしたこと

Vueでフォームのバリデーションを作りたかった。

  1. 名前に禁止文字(ゼロ幅スペースとか)が含まれているか確認するnameValid
  2. 名前欄を含む入力項目に不備があるか確認する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

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

Videojs 7 + RTMP の使用法

はじめに

こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html

Screen Shot 2019-10-04 at 10.39.38.png

Screen Shot 2019-10-04 at 10.52.22.png

Screen Shot 2019-10-04 at 10.51.41.png

Objective・目的

Learning how to use videojs + RTMP through a simple example.
videojs + RTMP through の簡単な例を学ぶこと。

A simple implementation ・ 簡単な実装

Screen Shot 2019-10-04 at 10.40.15.png

<!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

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

JavaScript 覚えておくべき注意点!(2)条件分岐について if文で条件分岐 例・ピザ屋注文

if文は条件文の基本

if文は「もし~ならば~する」で、基本文です。「~ならば」という部分を「条件式」と言います。

if.js
var 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.js
var 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.js
var budget = prompt('所持金を数字で入力してください');
budget = parseFloat(budget);
if (budget >= 1500) {
    alert('ピザを注文しました');
} else if (budget >= 500) {
    alert('ポテトを注文しました');
} else {
    alert('節約、節約...');
}

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