20210507のJavaScriptに関する記事は26件です。

「浮動小数点型に整数を代入した時は仮数部のビット数に入る数迄は絶対に誤差は出ないんだって!」の検証

はじめに 記事のタイトルにある通りのことを友人に言ったのですが、信じてもらえませんでした=< ちゃんと証明しようと思います。 そう考える理由 まず、 JavaScript では、ちゃんとそういう仕様になっています。 MDNによるドキュメントやQiita のこの記事など見て貰えば分かるのですが、 倍精度浮動小数点数(主に double 型) を用いています。 コンピュータで整数型は簡単に表せられますが、 JavaScript の場合はその表現に double を用いているのです。 面白いことに、その安全な範囲は─── あ、やっぱこれ以上は上に貼ったページを読んでください。長くなってしまうのでね。 で、 C++ の double も JavaScript の Number と同じ形式になっています(殆どの環境で)。なので、 C++ でも同じ様に処理する筈なのです(仮説1)。わざわざ表せられる範囲の整数を複雑に表現するメリットは無いですから。まあ環境によるかもしれないですけどね。 検証1:仮説1の通りになる(整数を正確に表すことができる)か 上記のソレは C++ でのお話なので、 C++ で検証します。 JavaScript の方は省略します。ちゃんと連番で整数が出力されます。 環境は Windows 10 Pro x64 + Visual Studio 2019 になります。 VC++ソースコード(長いので折りたたみ) main.cpp #include <iostream> #include <string> #include <iomanip> using std::cout; using std::endl; std::string printBinary(int num); std::string printBinary(float num); std::string printBinary(double num); int main() { for (double i = 0.0; i < 1024.0; i += 1.0) { cout << "number: " << std::fixed << std::setprecision(8) << i << endl; cout << "binary: " << printBinary(i) << endl; cout << endl; } } // int を2進数ビット列の文字列にする std::string printBinary(int num) { std::string str = ""; for (int i = sizeof(int) * 8 - 1; 0 <= i; --i) { // 一番上の桁から表示 str += ((num >> i) & 0x1) ? '1' : '0' ; } return str; } // float を2進数ビット列の文字列にする std::string printBinary(float num) { std::string str = ""; std::int32_t &pNum = *(std::int32_t *)(&num); for (int i = sizeof(float) * 8 - 1; 0 <= i; --i) { // 一番上の桁から表示 str += ((pNum >> i) & 0x1) ? '1' : '0' ; } return str; } // double を2進数ビット列の文字列にする std::string printBinary(double num) { std::string str = ""; std::int64_t &pNum = *(std::int64_t *)(&num); for (int i = sizeof(double) * 8 - 1; 0 <= i; --i) { // 一番上の桁から表示 str += ((pNum >> i) & 0x1) ? '1' : '0' ; } return str; } 実行結果 number: 0.00000000 binary: 0000000000000000000000000000000000000000000000000000000000000000 number: 1.00000000 binary: 0011111111110000000000000000000000000000000000000000000000000000 number: 2.00000000 binary: 0100000000000000000000000000000000000000000000000000000000000000 number: 3.00000000 binary: 0100000000001000000000000000000000000000000000000000000000000000  ( 中略 ) number: 1020.00000000 binary: 0100000010001111111000000000000000000000000000000000000000000000 number: 1021.00000000 binary: 0100000010001111111010000000000000000000000000000000000000000000 number: 1022.00000000 binary: 0100000010001111111100000000000000000000000000000000000000000000 number: 1023.00000000 binary: 0100000010001111111110000000000000000000000000000000000000000000 ほら!やっぱり! 勿論 float でも同じ様な結果になります。違いといえば binary の方に並ぶ 0 の数が減る程度です。 気になるのはビットの使い方です。そもそもが整数とは違いますが、それでも仮数部を用いて 3.0 = 00000000...00000011 となると思っていたのですが、どうやらそうでも無い様です。 (詳細については知るべきならちゃんと調べようと思っています。) 検証2: JavaScript と同じだけ表せられるか タイトルには整数を表せられることに加え、もう1つ「仮数部のビット数に入る数迄」は表現できるという仮説があります。 同じ使い方をするならば、 JavaScript の Number.MAX_SAFE_INTEGER は安全に正確に表現できる筈です。 main.cpp(変更部分ハイライト) // ( 省略 ) #include <iomanip> #include <bitset> #include <cmath> using std::cout; using std::endl; // ( 省略 ) int main() { int cnt = 0; for (double i = std::pow(2, 53) - 50.0; cnt < 100; i += 1.0f, ++cnt) { cout << "number: " << std::fixed << std::setprecision(8) << i << endl; // ( 省略 ) 実行結果 number: 9007199254740942.00000000 binary: 0100001100111111111111111111111111111111111111111111111111001110 number: 9007199254740943.00000000 binary: 0100001100111111111111111111111111111111111111111111111111001111  ( 中略 ) number: 9007199254740989.00000000 binary: 0100001100111111111111111111111111111111111111111111111111111101 number: 9007199254740990.00000000 binary: 0100001100111111111111111111111111111111111111111111111111111110 number: 9007199254740991.00000000 binary: 0100001100111111111111111111111111111111111111111111111111111111 number: 9007199254740992.00000000 binary: 0100001101000000000000000000000000000000000000000000000000000000 number: 9007199254740992.00000000 binary: 0100001101000000000000000000000000000000000000000000000000000000  ( 中略 ) number: 9007199254740992.00000000 binary: 0100001101000000000000000000000000000000000000000000000000000000 number: 9007199254740992.00000000 binary: 0100001101000000000000000000000000000000000000000000000000000000 仮説通り、9007199254740991 が最大で、それ以降はぶっ壊れました。 なお、どちらの検証も、マイナスでも同じ様に正確に表現されます。 まとめ キャストコストを恐れず整数は整数型で使おう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

僕がWeb開発の道に進もうと思った2つのきっかけ

初めに 皆さんはどんな感じでプログラミングを始めましたか? 大半の方が ・稼ぎたい ・こんなものを作りたい のどちらかだと思いますが僕は最初はロボットを作りたいと思っていたのですが、当時プログラミング言語の違いなどあまり知らず適当にプログラミング言語の本を買ったらRailsの本でそのままweb開発の道に進むことになりました。 そんな薄っぺらい事情で始めた僕がWebプログラマーになろうと決心した二つのきっかけを紹介します。 1.Reddit Place Reddit Placeというサイト(プロジェクト)知った時は本当に鳥肌たちました。。 Reddit Placeは巨大な白紙データに、参加者が1ピクセルずつ好きな絵を描いていくというものなんですけど その時に掲示板上で「みんなでこの絵書こうぜ!」とか「みんなで一面黒に染めてやろうぜ!」とか 違う目的を持った二つの集団がぶつかり合ったりするドラマがあって 72時間の間に、こんな絵が描かれたんですよ。。 まじですごくないですか?顔も名前も知らない人たちが何百人単位で集まって協力して何か成し遂げさせるサイトって。。。 僕も人と人とが繋がり合って奇跡・ドラマが起こるようなサイト(アプリ)作りたいなぁと思ってweb開発が更に好きになりました。 そんな72時間のドラマを4:30にまとめたタイムラプス動画があるのでそちらもぜひ 詳しい記事 2.Facebook創設者 天才ザックバーグはこうして育てられた もう一つ感銘を受けたのがこの動画です。プログラマーは全員見たほうがいいです。 Facebook創設者マークザッカーバーグの育てられ方で父の「大事なのは人と人との繋がりなんだ」って言葉を聞いてまた鳥肌立ちました。 Reddit Placeもそうですが人が最も影響を受けるものって人なんですね 自分もオリジナルのSNSを作りたいと思うようになりました。 僕もこんな人生歩みたいなぁ まとめ もうまとめです。この記事を書いて分かったことはあんまり文章で感動って伝わらないんですね。。。 この二つを見たときはまじで震えたんですけどね。文章力鍛えます( ;∀;) 僕のAmmotアカウント 僕のツイッターアカウント https://twitter.com/yamada1531
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

neovim + vim-lsp-settings で flow + flow-typedのjavascript環境構築

TL;DR flow-typedを使った設定だと :LspInstall flow しただけだとflowが起動しない lspのインストール先にflow-typedを追加でインストールする lspの起動スクリプトを修正してnpxで起動するようにする 環境 Mac OSX neovim 0.5.0 vim-lsp + vim-lsp-settings 手順 ※vim-lsp と vim-lsp-settingsの設定予め済んでいる前提 flowをインストール 適当なjsファイルを開いてneovimで :LspInstallServer flow を実行する。 flow-typedを追加 vim-lsp-settingsのサーバーのインストール先に移動してflow-typedを追加する $ cd ~/.local/share/vim-lsp-settings/servers/flow $ npm install flow-typed --save 起動スクリプトを置く デフォルトだと node_modules/.bin/flow へのリンクが配置してあるので npxで起動するようなスクリプトを置いておく。 #!/bin/bash npx flow lsp --from vim-lsp 以上 もっといいやり方あるかも。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Boothの検索画面がイケてないのでいじってみた

前置き Boothって除外検索できないよね~っていう話をしてたのでぱぱっと作ってみました TL;DR Chrome専用 Tampermonkeyという拡張機能を入れていることが前提です これをインストールする おわり 使い方 簡単! 検索ボックスの隣にignore...と書かれたボックスが現れるので除外したい単語を入れてチェックを付けるだけです ?? Tanpermonkeyって何? とあるページに自分のスクリプトを介入させることのできるすげーやつ Scriptのお話 単純に検索結果のアイテムを総なめして除外しているだけです RegExpにぶち込んでるので正規表現で除外もできるぞ テキストフォームは隣の検索ボックスからパクってきました // ==UserScript== // @name Booth Ignore Search // @namespace http://tampermonkey.net/ // @version 0.1.6 // @description Boothの検索結果から特定のキーワードを除外します(正規表現可能) // @author Angeart // @match https://booth.pm/* // @icon https://www.google.com/s2/favicons?domain=booth.pm // @grant none // ==/UserScript== (function() { 'use strict'; const ignoreSearchBox = ` <div class="item-search-box"> <form class="item-search"> <input name="utf8" type="hidden" value="✓"> <span class="twitter-typeahead" style="position: relative; display: inline-block; direction: ltr;"> <input type="search" value="" autocomplete="off" class="ac-tags item-search-input tt-hint" readonly="" spellcheck="false" tabindex="-1" style="position: absolute; top: 0px; left: 0px; border-color: transparent; box-shadow: none; opacity: 1; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255);"> <input type="search" name="query" id="ignore-query" value="" placeholder="ignore..." autocomplete="off" class="ac-tags item-search-input tt-input" spellcheck="false" dir="auto" style="position: relative; vertical-align: top; background-color: transparent;"> <pre aria-hidden="true" style="position: absolute; visibility: hidden; white-space: pre; font-family: Arial; font-size: 13.3333px; font-style: normal; font-variant: normal; font-weight: 400; word-spacing: 0px; letter-spacing: 0px; text-indent: 0px; text-rendering: auto; text-transform: none;"></pre> <span class="tt-dropdown-menu" style="position: absolute; top: 100%; left: 0px; z-index: 100; display: none; right: auto;"> <div class="tt-dataset-0"></div> </span> </span> <input id="exec-ignore" type="checkbox" class="btn search"> </form> </div> `; document.querySelector('.global-nav').insertAdjacentHTML('beforeend', ignoreSearchBox); const ignoreSearchBoxEl = document.querySelector('#ignore-query'); ignoreSearchBoxEl.value = sessionStorage.ignoreQuery ?? ""; const ignoreExec = document.querySelector("#exec-ignore"); ignoreExec.checked = (sessionStorage.execIgnore === 'true') ?? false; const exec = function() { const ignoreSearchBoxEl = document.querySelector('#ignore-query'); [...document.querySelectorAll('.item-card')].forEach(v => v.style.display = 'inline-block'); if (ignoreExec.checked && ignoreSearchBoxEl.value !== '') { let matchRegex = null; try { matchRegex = new RegExp(ignoreSearchBoxEl.value, "ig"); } catch { return; } const matchedEl = [...document.querySelectorAll('.item-card')].filter(v => v.querySelector('.item-card__title > a').text.match(matchRegex)) ?? []; matchedEl.forEach(v => v.style.display = 'none'); window.matchedEl = matchedEl; } else if (window.matchedEl != null) { window.matchedEl.forEach(v => v.style.display = 'inline-block'); } } ignoreSearchBoxEl.addEventListener('input', function() { sessionStorage.ignoreQuery = this.value; exec(); }); if (document.readyState == "complete" || document.readyState == "loaded" || document.readyState == "interactive") { exec(); } else { document.addEventListener("DOMContentLoaded", function(event) { exec(); }); } ignoreExec.addEventListener("change", function () { exec(); sessionStorage.execIgnore = this.checked; }); })(); 余談 BoothはどうやらjQuery使ってるみたいだけどnativeオンリーで書きました。 5分くらいで書いたのでバグってたりしたら教えて頂けると助かります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pinterest風なGridレイアウトをforeachの順序を崩さずに実現するまで【JS|意外とかんたん】

今回実現すること フロントエンドをされている方なら1度は憧れる(?) Pinterest風なGridレイアウトを ライブラリを使わず、かんたんなJSで実現したので 過程と解説を書いていきたいと思います。 既に個人開発でつくったWebアプリには実装していて 問題なく動いてます。 実際に実装した画面がこちらです。 チャットライクな寄書きWebサービス Cheers Box もし実装する機会があれば、参考にしていただけれ幸いです。 まずは調査しました 今回、Pinterest風なGridレイアウトを作る上で、 foreachの順序を崩さずに、画面上から下へcreated_atの降順になるようにする という仕様がありました。 順序を表すとこう言う感じです。 ① ② ③ ④ ⑤ ⑥ まず見つけた記事 【WordPress】cssの追記のみでPinterest風のグリッドデザイン 順序はこのようになってしまいます。 ① ④ ② ⑤ ③ ⑥ 次に見つけた記事 Masonryレイアウトをたった3行のシンプルなCSS Gridで簡単に実装できるようになります めちゃくちゃ簡単そうですが まだブラウザ互換的に使い物になりません。 ライブラリも発見 Pinterest風なGridレイアウトを簡単に作れるライブラリもあるようです。 driveway|http://jh3y.github.io/driveway/ Masonry|https://masonry.desandro.com/index.html しかし 「たかだか1画面のレイアウトのためにライブラリいれるのもなあ…」 ということで自作することにしました Pinterest風なGridレイアウトの原理 自作する前に、Pinterestが実際どのように実現しているかを調べてみました。 ソースコードを見るとおそらく どうにかしてJSで各要素にstyleを書き込んでいるということが予想できます。 そこで、それを真似することにしました。 やることは、 要素のサイズや要素同士の余白計算して、 計算結果を次の要素のstyle transformに設定する ということだけです。 いたってシンプルですね。 コードと解説 簡易的にhtmlをこういうものだとします。(実際のWebアプリにはhtml使ってませんが) index.html <div class="card-wrapper"> <!-- Gridレイアウトしたい親要素 --> <div class="card"> <!-- Gridレイアウトしたい要素 --> <img src="img01.png"> </div> <div class="cardr"> <img src="img02.png"> </div> <div class="card"> <img src="img03.png"> </div> <div class="card"> <img src="img04.png"> </div> <div class="card-"> <img src="img05.png"> </div> <div class="card"> <img src="img06.png"> </div> </div> 今回Pinterest風なGridレイアウトで表示したい要素には 画像が含まれています。 そこでまずは、画像が全て読み込まれたかどうかを判定します。 index.js const images = document.querySelectorAll('img'); let loadCnt = 0; if (images.length > 0) { for (const img of images) { let image = new Image(); image.src = img.src; image.addEventListener('load', () => { loadCnt++; if (loadCnt == images.length) { // 画像が全部読み込まれたか判定しています makePageCardGridLayout(); // この後、このメソッドの中身を書きます } }) } } ここまでで、ページないの画像全て読み込んだら、makePageCardGridLayout() というメソッドが呼ばれるところまできました。 次にmakePageCardGridLayout() でPinterest風なGridレイアウトを実現していきます。 index.js makePageCardGridLayout() { const cards = document.getElementsByClassName('card'); if(cards.length > 0) { let evenPosX = 0; let evenPosY = 0; let oddPosY = 0; let gridWindow; let sh; for (let i = 0; i < cards.length; i++) { const oddPosX = cards[0].clientWidth; i == 0 ? gridWindow = cards[0].closest('.card-wrapper') : i; // Gridの親要素を取得します if (i % 2 == 0) { // Gridに配置される偶数番目の要素に対する処理 cards[i].setAttribute("style", "transform: translateX("+ evenPosX +"px) translateY(" + evenPosY + "px)");  // スタイルに配置したい位置を記述します evenPosY = evenPosY + cards[i].clientHeight;  // 今のY軸の位置に要素の高さを加算 } else if (i % 2 != 0) {  // Gridに配置される奇数番目の要素に対する処理 cards[i].setAttribute("style", "transform: translateX(" + oddPosX + "px) translateY(" + oddPosY + "px)");  // スタイルに配置したい位置を記述します oddPosY = oddPosY + cards[i].clientHeight;  // 今のY軸の位置に要素の高さを加算 } } evenPosY > oddPosY ? sh = evenPosY + 150 : sh = oddPosY + 150; // 全部の要素が配置し終わったら、親要素の高さを設定するために計算します gridWindow.style.height = sh+'px'; // 計算した高さを親要素に指定します } } このように配置したい要素(.card)を取得して、forで1つずつ配置する場所を指定してあげています。 (なんでforなのかは覚えていません。笑 for ofでもいけるはずです) ① ② ③ ④ ⑤ ⑥ 奇数番目の要素は、1つ前の奇数番目の要素の位置とサイズから配置位置を計算 偶数番目の要素も、1つ前の偶数番目の要素の位置とサイズから配置位置を計算しています。 transform: translateで子要素の位置を指定しているので、 親要素の.card-wrapper は高さが0の状態になっています。 そこで最後に、奇数番目か偶数番目で下側にある要素から、150px加算して親要素の高さに指定しています。 コードは以上です。 レスポンシブを実現するのも、 画面サイズによって、makePageCardGridLayout()を流用したメソッドを呼び出せば スムーズに実現できると思います。 結果、意外とかんたんにできた 「え、もうおわり?」 「思ったよりコード量少ないな」 と思われた方も多いんじゃないでしょうか。 実はこちらのWebアプリには、ライブラリを使用せずに JSで実装した挙動が他にもいくつかあります。 チャットライクな寄書きWebサービス Cheers Box たとえば、 寄書き作成時に、生のJSなのにSPAのようなプレビュー機能がある 寄書きは、メッセージがチャットのように1つずつ時間差で表示される 下記の画像下部の部分はメニューで、画面全体がメニュー連動のカルーセルになっている などです。 それらもなるべくシンプルに実装してみたので また実装方法を記事にできたらと思います。 より良い実装、おすすめのライブラリがあれば、ぜひご教授ください。 最後までご覧いただいてありがとうございました?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

discord.js を使用して気軽に日程調整の Discord Bot を作成する

はじめに 最近、友人とゲームをすることが増えたのですが 社会人がほとんどのため、みんなの都合を合わせるのが大変だったりします。 今回は簡易的に日程調整を行えるような Bot を作成したので共有します。 一応 GitHub でコードは管理していますが、簡単に作成できるのでみなさん気軽にやってみてください! よろしくお願いします ??‍♂️ 流れ Discord 上で動く Bot を作成する メンションされたら Bot が日程を提示するように実装する Bot を永続化する Discord 上で動く Bot を作成する 誰でも作れる!Discord Bot(基礎編)- https://note.com/exteoi/n/nf1c37cb26c41 を参考に進めました。 とてもわかりやすく説明されており、こちらの説明を読めば Bot の作成はできると思うので コード部分以外は割愛します。 また、普段から JavaScript に触れているのでそのまま Discord.js を使用します。 メンションされたら Bot が日程を提示するように実装する コード全文 import http from "http"; import {Client} from "discord.js"; import dotenv from "dotenv"; import dayjs from "dayjs"; import "dayjs/locale/ja"; /******************** Discord Bot ********************/ const client = new Client({disableEveryone: true}); dotenv.config(); dayjs.locale("ja"); const connectDiscord = () => client.login(process.env.DISCORD_BOT_TOKEN); const toNextWeekends = () => { const japanNowDate = dayjs(); const weekends = [5, 6, 7]; return weekends.map((d, n) => { // 日曜日だったら次の週末を提示する const diffDay = d - japanNowDate.day(); const targetDate = japanNowDate.add(diffDay, "day"); return `${n + 1}: ${targetDate.format("YYYY/MM/DD(ddd)")}`; }).join("\n"); }; if (process.env.DISCORD_BOT_TOKEN === undefined) { console.log("DISCORD_BOT_TOKEN does not exist."); process.exit(0); } else { connectDiscord(); } client.once("ready", () => { console.log("This bot is running..."); // Bot オンラインであれば、「Bot をプレイ中と表示される」 client.user.setPresence({activity: {name: "Bot"}}); }); client.on("message", async (message) => { // 自分のメッセージには反応しないようにする if (message.author.bot) { return; } // メンションされる & @everyone や @here ではない & 単独メンションのときに動作する if ((message.mentions.users.find((e) => e.username === client.user.username) && message.mentions.users.array().length === 1) || (message.mentions.roles.find((e) => e.name === client.user.username) && message.mentions.roles.array().length === 1)) { const sentMessage = await message.channel.send(`@everyone \n${toNextWeekends()}`); try { await sentMessage.react("1️⃣"); await sentMessage.react("2️⃣"); await sentMessage.react("3️⃣"); await sentMessage.react("❌"); } catch (err) { console.error(err); } } }); /******************** Node Server ********************/ const httpServer = http.createServer(); httpServer.on("request", (request, response) => { connectDiscord(); response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Discord bot is active now \n"); }); httpServer.listen(3000); まず、メンションされたら動作するように実装します。 client.on("message", async (message) => { ... // メンションされる & @everyone や @here ではない & 単独メンションのときに動作する if ((message.mentions.users.find((e) => e.username === client.user.username) && message.mentions.users.array().length === 1) || (message.mentions.roles.find((e) => e.name === client.user.username) && message.mentions.roles.array().length === 1)) { const sentMessage = await message.channel.send(`@everyone \n${toNextWeekends()}`); try { await sentMessage.react("1️⃣"); await sentMessage.react("2️⃣"); await sentMessage.react("3️⃣"); await sentMessage.react("❌"); } catch (err) { console.error(err); } } }); client.on("message", ...) でメッセージが送信されたイベントを監視できます。(返り値として MessageMentions が返ってきます) MessageMentions - discord.js を見ると、message.mentions.users と message.mentions.roles でユーザが誰にメンションをしたかを確認できそうです。 通常のメンションとロールでのメンションを想定して両方で動作できるように実装します。 もう少し綺麗にチェックする方法はありそうですが、ひとまず動作することを最優先にしていたためこのような実装にしました。 その後、全体メンションで日付を表示してリアクションが行えるように発言を行うことで Bot の役目を全うします。 toNextWeekends() では以下のように実装を行って週末を逆算し、表示するように実装しています。 const toNextWeekends = () => { const japanNowDate = dayjs(); const weekends = [5, 6, 7]; return weekends.map((d, n) => { // 日曜日だったら次の週末を提示する const diffDay = d - japanNowDate.day(); const targetDate = japanNowDate.add(diffDay, "day"); return `${n + 1}: ${targetDate.format("YYYY/MM/DD(ddd)")}`; }).join("\n"); }; dayjs といった node.js で日付を簡単に扱える npm モジュールが存在しているのでそれを使用します。 日付は 5(金)、6(土)、7(日) で扱われているので、差分を計算して週末を出します。 dayjs().add(指定した日付との差分, "day") で指定の曜日を出してくれるのでとても便利です。 最終的に .map() で生成した配列を .join("\n") で改行を行いつつ文字列に変換することでテンプレート文字列の中で使用できるようにしています。 Bot を永続化する 今回、Bot は Glitch というサービスを使用しています。 Glitch は無料枠だと 5分に1回サービスが落ちるので Google Apps Script を使用して定期的に起動させる必要があります。 const wakeGlitch = () => { const GLITCH_URL = "YOUR GLITCH URL"; const json = { "type": "wake" }; const params = { "contentType": "application/json; charset=utf-8", "method": "post", "payload": json, "headers": json, "muteHttpExceptions": true }; response = UrlFetchApp.fetch(GLITCH_URL, params); }; これを定期的に実行するように Google Apps Script で設定します。 詳しくは前述した 誰でも作れる!Discord Bot(基礎編)- https://note.com/exteoi/n/nf1c37cb26c41 を参考にお願いします。 結果 まだまだ改良の余地はありますが、とりあえず Bot を作成して簡易的なスケジュール管理を行うといった目標は達成できました。 おわりに Bot を無料で作成して運用まで簡単に作成できますね。皆さんも何か作ってみてはいかがでしょうか。 機械学習を組み合わせて画像で遊べる Bot とかを作っても良いかもしれないですね。 この記事では Discord.js を使用していますが、他の言語でも実装可能です。 最後まで読んでいただき、ありがとうございました ??‍♂️
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】繰り返し処理を利用し、九九を作成せよ。

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>九九</title> </head> <body> <script> var i = 0; var j = 0; var k; while (j < 9) { document.write("</br>"); j++; i = 0; while (i < 9) { i++; k = j * i if ( k <= 9 ) { document.write( i + '✕' + j + '=' + '0' + k + ' ' ); }else { document.write( i + '✕' + j + '=' + k + ' '); } } } </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js の out of memory エラーが起きそうになったら例外を投げて通知する

はじめに Node.jsのバッチを保守していると、データ増加に伴いメモリー不足で処理が落ちてしまうことがありました。 エラー発生時にはChatworkに通知が飛ぶようにしていたのですが、そのときは通知が飛びませんでした。 そこで、メモリー不足で処理が落ちる前に、ある程度やばそうな量のメモリーを使っている時点で、警告を飛ばすようにしてみました。 処理内容 プログラムは次のような状態でした。 yabaiyo.js var メモリーを圧迫する変数 = [] function すごく繰り返す処理 (繰り返す回数) { for (var i = 0; i < 繰り返す回数; i++) { メモリーを圧迫する変数.push(new Array(10000)) } } try { すごく繰り返す処理(1000000) } catch (e) { チャットワークに警告を送信('やばいよ') } function チャットワークに警告を送信 (メッセージ) { console.log(メッセージ + 'をチャットワークに通知しました。') } これを実行すると、下記のようなログが出て処理が止まります。 <--- Last few GCs ---> [5414:0x100000000] 4874 ms: Mark-sweep 1824.4 (2051.4) -> 1824.4 (2044.9) MB, 692.6 / 0.0 ms (average mu = 0.075, current mu = 0.014) allocation failure GC in old space requested <--- JS stacktrace ---> ==== JS stack trace ========================================= (省略) FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory (省略) zsh: abort node yabaiyo.js やばいのにChatworkに通知が飛びません。 改善 これを防ぐために、次のような関数を用意しました。 多分ほぼアウトオブメモリー.js var v8 = require('v8') function 多分ほぼアウトオブメモリー () { var stats = v8.getHeapStatistics() var 五百メガバイト = 500 * 1024 * 1024 var ここを超えるとやばそう = stats.heap_size_limit - 五百メガバイト return stats.total_heap_size > ここを超えるとやばそう } 「すごく繰り返す処理」の中に、「多分ほぼアウトオブメモリー」を判定する条件文を入れて、やばそうだったら例外を投げて「チャットワークに警告を送信」するようにしました。 function すごく繰り返す処理 (繰り返す回数) { for (var i = 0; i < 繰り返す回数; i++) { メモリーを圧迫する変数.push(new Array(10000)) // ↓ ここに追加 if (多分ほぼアウトオブメモリー()) { throw new Error('多分ほぼアウトオブメモリー') } } } ファイルの全体像は下記になります。 yabaiyo.js var v8 = require('v8') function 多分ほぼアウトオブメモリー () { var stats = v8.getHeapStatistics() var 五百メガバイト = 500 * 1024 * 1024 var ここを超えるとやばそう = stats.heap_size_limit - 五百メガバイト return stats.total_heap_size > ここを超えるとやばそう } var メモリーを圧迫する変数 = [] function すごく繰り返す処理 (繰り返す回数) { for (var i = 0; i < 繰り返す回数; i++) { メモリーを圧迫する変数.push(new Array(10000)) if (多分ほぼアウトオブメモリー()) { throw new Error('多分ほぼアウトオブメモリー') } } } try { すごく繰り返す処理(1000000) } catch (e) { チャットワークに警告を送信('やばいよ') } function チャットワークに警告を送信 (メッセージ) { console.log(メッセージ + 'をチャットワークに通知しました。') } こうすることで、実行したときに次のように出力されます。 $ node yabaiyo.js やばいよをチャットワークに通知しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

eslint-config-* の比較表

以下の4つの config の比較表です。 eslint:recommended eslint-config-standard eslint-config-airbnb-base eslint-config-google フレームワークを依らないルールについて比較したいので eslint-config-airbnb から React 関係の plugin を除外した eslint-config-airbnb-base を使用します。 バージョン情報 使用する各パッケージのバージョンは下記の通りです。 eslint: 7.25.0 eslint-config-standard: 16.0.2 eslint-config-airbnb-base: 14.2.1 eslint-config-google: 0.14.0 eslint-plugin-import: 2.22.1 eslint-plugin-node: 11.1.0 eslint-plugin-promise: 4.3.1 簡易版 (off, warn, error のみ) Possible Errors Rule eslint:recommended standard airbnb-base google for-direction error error getter-return error error no-async-promise-executor error error error no-await-in-loop error no-compare-neg-zero error error error no-cond-assign error error error off no-console warn no-constant-condition error error warn no-control-regex error error error no-debugger error error error no-dupe-args error error error no-dupe-else-if error off no-dupe-keys error error error no-duplicate-case error error error no-empty error error error no-empty-character-class error error error no-ex-assign error error error no-extra-boolean-cast error error error no-extra-parens error off no-extra-semi error error no-func-assign error error error no-import-assign error error off no-inner-declarations error error no-invalid-regexp error error error no-irregular-whitespace error error error error no-loss-of-precision error off no-misleading-character-class error error error no-obj-calls error error error no-promise-executor-return off no-prototype-builtins error error error no-regex-spaces error error error no-setter-return error off no-sparse-arrays error error error no-template-curly-in-string error error no-unexpected-multiline error error error error no-unreachable error error error no-unreachable-loop error off no-unsafe-finally error error error no-unsafe-negation error error error no-unsafe-optional-chaining no-useless-backreference error off require-atomic-updates off use-isnan error error error valid-typeof error error error Best Practices Rule eslint:recommended standard airbnb-base google accessor-pairs error off array-callback-return error error block-scoped-var error class-methods-use-this error complexity off consistent-return error curly error error error default-case error default-case-last error off default-param-last off dot-location error error dot-notation error error eqeqeq error error grouped-accessor-pairs off guard-for-in error error max-classes-per-file error no-alert warn no-caller error error error no-case-declarations error error error no-constructor-return off no-div-regex off no-else-return error no-empty-function error no-empty-pattern error error error no-eq-null off no-eval error error no-extend-native error error error no-extra-bind error error error no-extra-label error no-fallthrough error error error no-floating-decimal error error no-global-assign error error error no-implicit-coercion off no-implicit-globals off no-implied-eval error error no-invalid-this off error no-iterator error error no-labels error error no-lone-blocks error error no-loop-func error no-magic-numbers off no-multi-spaces error error error no-multi-str error error error no-new error error no-new-func error error no-new-wrappers error error error no-nonoctal-decimal-escape no-octal error error error no-octal-escape error error no-param-reassign error no-proto error error no-redeclare error error error no-restricted-properties error no-return-assign error error no-return-await error no-script-url error no-self-assign error error error no-self-compare error error no-sequences error error no-throw-literal error error error no-unmodified-loop-condition error off no-unused-expressions error error no-unused-labels error error no-useless-call error off no-useless-catch error error error no-useless-concat error no-useless-escape error error error no-useless-return error error no-void error error no-warning-comments off no-with error error error error prefer-named-capture-group off prefer-promise-reject-errors error error error prefer-regex-literals error off radix error require-await off require-unicode-regexp off vars-on-top error wrap-iife error error yoda error error Strict Mode Rule eslint:recommended standard airbnb-base google strict error Variables Rule eslint:recommended standard airbnb-base google init-declarations off no-delete-var error error error no-label-var error no-restricted-globals error no-shadow error no-shadow-restricted-names error error error no-undef error error error no-undef-init error error no-undefined off no-unused-vars error error error error no-use-before-define error error Stylistic Issues Rule eslint:recommended standard airbnb-base google array-bracket-newline off off array-bracket-spacing error error error array-element-newline off off block-spacing error error error brace-style error error error camelcase error error error capitalized-comments off comma-dangle error error error comma-spacing error error error comma-style error error error computed-property-spacing error error error consistent-this off eol-last error error error func-call-spacing error error error func-name-matching off func-names warn func-style off function-call-argument-newline off function-paren-newline error id-denylist off id-length off id-match off implicit-arrow-linebreak error indent error error error jsx-quotes off key-spacing error error error keyword-spacing error error error line-comment-position off linebreak-style error error lines-around-comment off lines-between-class-members error error max-depth off max-len error error max-lines off max-lines-per-function off max-nested-callbacks off max-params off max-statements off max-statements-per-line off multiline-comment-style off multiline-ternary error off new-cap error error error new-parens error error newline-per-chained-call error no-array-constructor error error error no-bitwise error no-continue error no-inline-comments off no-lonely-if error no-mixed-operators error error no-mixed-spaces-and-tabs error error error error no-multi-assign error no-multiple-empty-lines error error error no-negated-condition off no-nested-ternary error no-new-object error error error no-plusplus error no-restricted-syntax error no-tabs error error error no-ternary off no-trailing-spaces error error error no-underscore-dangle error no-unneeded-ternary error error no-whitespace-before-property error error nonblock-statement-body-position error object-curly-newline error error object-curly-spacing error error error object-property-newline error error one-var error error error one-var-declaration-per-line error operator-assignment error operator-linebreak error error error padded-blocks error error error padding-line-between-statements off prefer-exponentiation-operator off prefer-object-spread error quote-props error error error quotes error error error semi error error error semi-spacing error error error semi-style error sort-keys off sort-vars off space-before-blocks error error error space-before-function-paren error error error space-in-parens error error space-infix-ops error error space-unary-ops error error spaced-comment error error error switch-colon-spacing error error template-tag-spacing error error unicode-bom error error wrap-regex off ECMAScript 6 Rule eslint:recommended standard airbnb-base google arrow-body-style error arrow-parens error error arrow-spacing error error constructor-super error error error error generator-star-spacing error error error no-class-assign error error error no-confusing-arrow error no-const-assign error error error no-dupe-class-members error error error no-duplicate-imports off no-new-symbol error error error error no-restricted-exports off no-restricted-imports off no-this-before-super error error error error no-useless-computed-key error error no-useless-constructor error error no-useless-rename error error no-var warn error error object-shorthand error prefer-arrow-callback error prefer-const error error error prefer-destructuring error prefer-numeric-literals error prefer-rest-params error error prefer-spread error error prefer-template error require-yield error error rest-spread-spacing error error error sort-imports off symbol-description error error template-curly-spacing error error yield-star-spacing error error error 詳細版 Possible Errors Rule eslint:recommended standard airbnb-base google for-direction error error getter-return error [  "error",  {    "allowImplicit": true  }] no-async-promise-executor error error error no-await-in-loop error no-compare-neg-zero error error error no-cond-assign error error [  "error",  "always"] off no-console warn no-constant-condition error [  "error",  {    "checkLoops": false  }] warn no-control-regex error error error no-debugger error error error no-dupe-args error error error no-dupe-else-if error off no-dupe-keys error error error no-duplicate-case error error error no-empty error [  "error",  {    "allowEmptyCatch": true  }] error no-empty-character-class error error error no-ex-assign error error error no-extra-boolean-cast error error error no-extra-parens [  "error",  "functions"] [  "off",  "all",  {    "conditionalAssign": true,    "nestedBinaryExpressions": false,    "returnAssign": false,    "ignoreJSX": "all",    "enforceForArrowConditionals": false  }] no-extra-semi error error no-func-assign error error error no-import-assign error error off no-inner-declarations error error no-invalid-regexp error error error no-irregular-whitespace error error error error no-loss-of-precision error off no-misleading-character-class error error error no-obj-calls error error error no-promise-executor-return off no-prototype-builtins error error error no-regex-spaces error error error no-setter-return error off no-sparse-arrays error error error no-template-curly-in-string error error no-unexpected-multiline error error error error no-unreachable error error error no-unreachable-loop error [  "off",  {    "ignore": []  }] no-unsafe-finally error error error no-unsafe-negation error error error no-unsafe-optional-chaining no-useless-backreference error off require-atomic-updates off use-isnan error [  "error",  {    "enforceForSwitchCase": true,    "enforceForIndexOf": true  }] error valid-typeof error [  "error",  {    "requireStringLiterals": true  }] [  "error",  {    "requireStringLiterals": true  }] Best Practices Rule eslint:recommended standard airbnb-base google accessor-pairs [  "error",  {    "setWithoutGet": true,    "enforceForClassMembers": true,    "getWithoutSet": false  }] off array-callback-return [  "error",  {    "allowImplicit": false,    "checkForEach": false  }] [  "error",  {    "allowImplicit": true,    "checkForEach": false  }] block-scoped-var error class-methods-use-this [  "error",  {    "exceptMethods": []  }] complexity [  "off",  11] consistent-return error curly [  "error",  "multi-line"] [  "error",  "multi-line"] [  "error",  "multi-line"] default-case [  "error",  {    "commentPattern": "^no default$"  }] default-case-last error off default-param-last off dot-location [  "error",  "property"] [  "error",  "property"] dot-notation [  "error",  {    "allowKeywords": true,    "allowPattern": ""  }] [  "error",  {    "allowKeywords": true,    "allowPattern": ""  }] eqeqeq [  "error",  "always",  {    "null": "ignore"  }] [  "error",  "always",  {    "null": "ignore"  }] grouped-accessor-pairs off guard-for-in error error max-classes-per-file [  "error",  1] no-alert warn no-caller error error error no-case-declarations error error error no-constructor-return off no-div-regex off no-else-return [  "error",  {    "allowElseIf": false  }] no-empty-function [  "error",  {    "allow": [      "arrowFunctions",      "functions",      "methods"    ]  }] no-empty-pattern error error error no-eq-null off no-eval error error no-extend-native error error error no-extra-bind error error error no-extra-label error no-fallthrough error error error no-floating-decimal error error no-global-assign error error [  "error",  {    "exceptions": []  }] no-implicit-coercion [  "off",  {    "boolean": false,    "number": true,    "string": true,    "allow": []  }] no-implicit-globals off no-implied-eval error error no-invalid-this off error no-iterator error error no-labels [  "error",  {    "allowLoop": false,    "allowSwitch": false  }] [  "error",  {    "allowLoop": false,    "allowSwitch": false  }] no-lone-blocks error error no-loop-func error no-magic-numbers [  "off",  {    "ignore": [],    "ignoreArrayIndexes": true,    "enforceConst": true,    "detectObjects": false  }] no-multi-spaces error [  "error",  {    "ignoreEOLComments": false  }] error no-multi-str error error error no-new error error no-new-func error error no-new-wrappers error error error no-nonoctal-decimal-escape no-octal error error error no-octal-escape error error no-param-reassign [  "error",  {    "props": true,    "ignorePropertyModificationsFor": [      "acc",      "accumulator",      "e",      "ctx",      "context",      "req",      "request",      "res",      "response",      "$scope",      "staticContext"    ]  }] no-proto error error no-redeclare error [  "error",  {    "builtinGlobals": false  }] error no-restricted-properties [  "error",  {    "object": "arguments",    "property": "callee",    "message": "arguments.callee is deprecated"  },  {    "object": "global",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "self",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "window",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "global",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "object": "self",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "object": "window",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "property": "&lowbar;&lowbar;defineGetter&lowbar;&lowbar;",    "message": "Please use Object.defineProperty instead."  },  {    "property": "&lowbar;&lowbar;defineSetter&lowbar;&lowbar;",    "message": "Please use Object.defineProperty instead."  },  {    "object": "Math",    "property": "pow",    "message": "Use the exponentiation operator (**) instead."  }] no-return-assign [  "error",  "except-parens"] [  "error",  "always"] no-return-await error no-script-url error no-self-assign error [  "error",  {    "props": true  }] [  "error",  {    "props": true  }] no-self-compare error error no-sequences error error no-throw-literal error error error no-unmodified-loop-condition error off no-unused-expressions [  "error",  {    "allowShortCircuit": true,    "allowTernary": true,    "allowTaggedTemplates": true,    "enforceForJSX": false  }] [  "error",  {    "allowShortCircuit": false,    "allowTernary": false,    "allowTaggedTemplates": false,    "enforceForJSX": false  }] no-unused-labels error error no-useless-call error off no-useless-catch error error error no-useless-concat error no-useless-escape error error error no-useless-return error error no-void error error no-warning-comments [  "off",  {    "terms": [      "todo",      "fixme",      "xxx"    ],    "location": "start"  }] no-with error error error error prefer-named-capture-group off prefer-promise-reject-errors error [  "error",  {    "allowEmptyReject": true  }] error prefer-regex-literals [  "error",  {    "disallowRedundantWrapping": true  }] off radix error require-await off require-unicode-regexp off vars-on-top error wrap-iife [  "error",  "any",  {    "functionPrototypeMethods": true  }] [  "error",  "outside",  {    "functionPrototypeMethods": false  }] yoda [  "error",  "never"] error Strict Mode Rule eslint:recommended standard airbnb-base google strict [  "error",  "never"] Variables Rule eslint:recommended standard airbnb-base google init-declarations off no-delete-var error error error no-label-var error no-restricted-globals [  "error",  {    "name": "isFinite",    "message": "Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite";  },  {    "name": "isNaN",    "message": "Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan";  },  "addEventListener",  "blur",  "close",  "closed",  "confirm",  "defaultStatus",  "defaultstatus",  "event",  "external",  "find",  "focus",  "frameElement",  "frames",  "history",  "innerHeight",  "innerWidth",  "length",  "location",  "locationbar",  "menubar",  "moveBy",  "moveTo",  "name",  "onblur",  "onerror",  "onfocus",  "onload",  "onresize",  "onunload",  "open",  "opener",  "opera",  "outerHeight",  "outerWidth",  "pageXOffset",  "pageYOffset",  "parent",  "print",  "removeEventListener",  "resizeBy",  "resizeTo",  "screen",  "screenLeft",  "screenTop",  "screenX",  "screenY",  "scroll",  "scrollbars",  "scrollBy",  "scrollTo",  "scrollX",  "scrollY",  "self",  "status",  "statusbar",  "stop",  "toolbar",  "top"] no-shadow error no-shadow-restricted-names error error error no-undef error error error no-undef-init error error no-undefined off no-unused-vars error [  "error",  {    "args": "none",    "caughtErrors": "none",    "ignoreRestSiblings": true,    "vars": "all"  }] [  "error",  {    "vars": "all",    "args": "after-used",    "ignoreRestSiblings": true  }] [  "error",  {    "args": "none"  }] no-use-before-define [  "error",  {    "functions": false,    "classes": false,    "variables": false  }] [  "error",  {    "functions": true,    "classes": true,    "variables": true  }] Stylistic Issues Rule eslint:recommended standard airbnb-base google array-bracket-newline [  "off",  "consistent"] off array-bracket-spacing [  "error",  "never"] [  "error",  "never"] [  "error",  "never"] array-element-newline [  "off",  {    "multiline": true,    "minItems": 3  }] off block-spacing [  "error",  "always"] [  "error",  "always"] [  "error",  "never"] brace-style [  "error",  "1tbs",  {    "allowSingleLine": true  }] [  "error",  "1tbs",  {    "allowSingleLine": true  }] error camelcase [  "error",  {    "allow": [      "^UNSAFE&lowbar;"    ],    "properties": "never",    "ignoreGlobals": true,    "ignoreDestructuring": false,    "ignoreImports": false  }] [  "error",  {    "properties": "never",    "ignoreDestructuring": false,    "ignoreImports": false,    "ignoreGlobals": false  }] [  "error",  {    "properties": "never",    "ignoreDestructuring": false,    "ignoreImports": false,    "ignoreGlobals": false  }] capitalized-comments [  "off",  "never",  {    "line": {      "ignorePattern": ".",      "ignoreInlineComments": true,      "ignoreConsecutiveComments": true    },    "block": {      "ignorePattern": ".",      "ignoreInlineComments": true,      "ignoreConsecutiveComments": true    }  }] comma-dangle [  "error",  {    "arrays": "never",    "objects": "never",    "imports": "never",    "exports": "never",    "functions": "never"  }] [  "error",  {    "arrays": "always-multiline",    "objects": "always-multiline",    "imports": "always-multiline",    "exports": "always-multiline",    "functions": "always-multiline"  }] [  "error",  "always-multiline"] comma-spacing [  "error",  {    "before": false,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] error comma-style [  "error",  "last"] [  "error",  "last",  {    "exceptions": {      "ArrayExpression": false,      "ArrayPattern": false,      "ArrowFunctionExpression": false,      "CallExpression": false,      "FunctionDeclaration": false,      "FunctionExpression": false,      "ImportDeclaration": false,      "ObjectExpression": false,      "ObjectPattern": false,      "VariableDeclaration": false,      "NewExpression": false    }  }] error computed-property-spacing [  "error",  "never",  {    "enforceForClassMembers": true  }] [  "error",  "never"] error consistent-this off eol-last error [  "error",  "always"] error func-call-spacing [  "error",  "never"] [  "error",  "never"] error func-name-matching [  "off",  "always",  {    "includeCommonJSModuleExports": false,    "considerPropertyDescriptor": true  }] func-names warn func-style [  "off",  "expression"] function-call-argument-newline [  "off",  "consistent"] function-paren-newline [  "error",  "consistent"] id-denylist off id-length off id-match off implicit-arrow-linebreak [  "error",  "beside"] indent [  "error",  2,  {    "SwitchCase": 1,    "VariableDeclarator": 1,    "outerIIFEBody": 1,    "MemberExpression": 1,    "FunctionDeclaration": {      "parameters": 1,      "body": 1    },    "FunctionExpression": {      "parameters": 1,      "body": 1    },    "CallExpression": {      "arguments": 1    },    "ArrayExpression": 1,    "ObjectExpression": 1,    "ImportDeclaration": 1,    "flatTernaryExpressions": false,    "ignoreComments": false,    "ignoredNodes": [      "TemplateLiteral ",      "JSXElement",      "JSXElement > ",      "JSXAttribute",      "JSXIdentifier",      "JSXNamespacedName",      "JSXMemberExpression",      "JSXSpreadAttribute",      "JSXExpressionContainer",      "JSXOpeningElement",      "JSXClosingElement",      "JSXFragment",      "JSXOpeningFragment",      "JSXClosingFragment",      "JSXText",      "JSXEmptyExpression",      "JSXSpreadChild"    ],    "offsetTernaryExpressions": true  }] [  "error",  2,  {    "SwitchCase": 1,    "VariableDeclarator": 1,    "outerIIFEBody": 1,    "FunctionDeclaration": {      "parameters": 1,      "body": 1    },    "FunctionExpression": {      "parameters": 1,      "body": 1    },    "CallExpression": {      "arguments": 1    },    "ArrayExpression": 1,    "ObjectExpression": 1,    "ImportDeclaration": 1,    "flatTernaryExpressions": false,    "ignoredNodes": [      "JSXElement",      "JSXElement > *",      "JSXAttribute",      "JSXIdentifier",      "JSXNamespacedName",      "JSXMemberExpression",      "JSXSpreadAttribute",      "JSXExpressionContainer",      "JSXOpeningElement",      "JSXClosingElement",      "JSXFragment",      "JSXOpeningFragment",      "JSXClosingFragment",      "JSXText",      "JSXEmptyExpression",      "JSXSpreadChild"    ],    "ignoreComments": false,    "offsetTernaryExpressions": false  }] [  "error",  2,  {    "CallExpression": {      "arguments": 2    },    "FunctionDeclaration": {      "body": 1,      "parameters": 2    },    "FunctionExpression": {      "body": 1,      "parameters": 2    },    "MemberExpression": 2,    "ObjectExpression": 1,    "SwitchCase": 1,    "ignoredNodes": [      "ConditionalExpression"    ],    "flatTernaryExpressions": false,    "offsetTernaryExpressions": false,    "ignoreComments": false  }] jsx-quotes [  "off",  "prefer-double"] key-spacing [  "error",  {    "beforeColon": false,    "afterColon": true  }] [  "error",  {    "beforeColon": false,    "afterColon": true  }] error keyword-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": true,    "after": true,    "overrides": {      "return": {        "after": true      },      "throw": {        "after": true      },      "case": {        "after": true      }    }  }] error line-comment-position [  "off",  {    "position": "above",    "ignorePattern": "",    "applyDefaultPatterns": true  }] linebreak-style [  "error",  "unix"] error lines-around-comment off lines-between-class-members [  "error",  "always",  {    "exceptAfterSingleLine": true  }] [  "error",  "always",  {    "exceptAfterSingleLine": false  }] max-depth [  "off",  4] max-len [  "error",  100,  2,  {    "ignoreUrls": true,    "ignoreComments": false,    "ignoreRegExpLiterals": true,    "ignoreStrings": true,    "ignoreTemplateLiterals": true  }] [  "error",  {    "code": 80,    "tabWidth": 2,    "ignoreUrls": true,    "ignorePattern": "goog.(module&verbar;require)"  }] max-lines [  "off",  {    "max": 300,    "skipBlankLines": true,    "skipComments": true  }] max-lines-per-function [  "off",  {    "max": 50,    "skipBlankLines": true,    "skipComments": true,    "IIFEs": true  }] max-nested-callbacks off max-params [  "off",  3] max-statements [  "off",  10] max-statements-per-line [  "off",  {    "max": 1  }] multiline-comment-style [  "off",  "starred-block"] multiline-ternary [  "error",  "always-multiline"] [  "off",  "never"] new-cap [  "error",  {    "newIsCap": true,    "capIsNew": false,    "properties": true  }] [  "error",  {    "newIsCap": true,    "newIsCapExceptions": [],    "capIsNew": false,    "capIsNewExceptions": [      "Immutable.Map",      "Immutable.Set",      "Immutable.List"    ],    "properties": true  }] error new-parens error error newline-per-chained-call [  "error",  {    "ignoreChainWithDepth": 4  }] no-array-constructor error error error no-bitwise error no-continue error no-inline-comments off no-lonely-if error no-mixed-operators [  "error",  {    "groups": [      [        "==",        "!=",        "===",        "!==",        ">",        ">=",        "<",        "<="      ],      [        "&&",        "&verbar;&verbar;"      ],      [        "in",        "instanceof"      ]    ],    "allowSamePrecedence": true  }] [  "error",  {    "groups": [      [        "%",        "*"      ],      [        "%",        "+"      ],      [        "%",        "-"      ],      [        "%",        ""      ],      [        "%",        "/"      ],      [        "/",        "*"      ],      [        "&",        "&verbar;",        "<<",        ">>",        ">>>"      ],      [        "==",        "!=",        "===",        "!=="      ],      [        "&&",        "&verbar;&verbar;"      ]    ],    "allowSamePrecedence": false  }] no-mixed-spaces-and-tabs error error error error no-multi-assign error no-multiple-empty-lines [  "error",  {    "max": 1,    "maxEOF": 0  }] [  "error",  {    "max": 1,    "maxBOF": 0,    "maxEOF": 0  }] [  "error",  {    "max": 2  }] no-negated-condition off no-nested-ternary error no-new-object error error error no-plusplus error no-restricted-syntax [  "error",  {    "selector": "ForInStatement",    "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array."  },  {    "selector": "ForOfStatement",    "message": "iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations."  },  {    "selector": "LabeledStatement",    "message": "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand."  },  {    "selector": "WithStatement",    "message": "`with` is disallowed in strict mode because it makes code impossible to predict and optimize."  }] no-tabs error error error no-ternary off no-trailing-spaces error [  "error",  {    "skipBlankLines": false,    "ignoreComments": false  }] error no-underscore-dangle [  "error",  {    "allow": [],    "allowAfterThis": false,    "allowAfterSuper": false,    "enforceInMethodNames": true,    "allowAfterThisConstructor": false,    "allowFunctionParams": true  }] no-unneeded-ternary [  "error",  {    "defaultAssignment": false  }] [  "error",  {    "defaultAssignment": false  }] no-whitespace-before-property error error nonblock-statement-body-position [  "error",  "beside",  {    "overrides": {}  }] object-curly-newline [  "error",  {    "multiline": true,    "consistent": true  }] [  "error",  {    "ObjectExpression": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ObjectPattern": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ImportDeclaration": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ExportDeclaration": {      "minProperties": 4,      "multiline": true,      "consistent": true    }  }] object-curly-spacing [  "error",  "always"] [  "error",  "always"] error object-property-newline [  "error",  {    "allowMultiplePropertiesPerLine": true,    "allowAllPropertiesOnSameLine": false  }] [  "error",  {    "allowAllPropertiesOnSameLine": true,    "allowMultiplePropertiesPerLine": false  }] one-var [  "error",  {    "initialized": "never"  }] [  "error",  "never"] [  "error",  {    "var": "never",    "let": "never",    "const": "never"  }] one-var-declaration-per-line [  "error",  "always"] operator-assignment [  "error",  "always"] operator-linebreak [  "error",  "after",  {    "overrides": {      "?": "before",      ":": "before",      "&verbar;>": "before"    }  }] [  "error",  "before",  {    "overrides": {      "=": "none"    }  }] [  "error",  "after"] padded-blocks [  "error",  {    "blocks": "never",    "switches": "never",    "classes": "never"  }] [  "error",  {    "blocks": "never",    "classes": "never",    "switches": "never"  },  {    "allowSingleLineBlocks": true  }] [  "error",  "never"] padding-line-between-statements off prefer-exponentiation-operator off prefer-object-spread error quote-props [  "error",  "as-needed"] [  "error",  "as-needed",  {    "keywords": false,    "unnecessary": true,    "numbers": false  }] [  "error",  "consistent"] quotes [  "error",  "single",  {    "avoidEscape": true,    "allowTemplateLiterals": false  }] [  "error",  "single",  {    "avoidEscape": true  }] [  "error",  "single",  {    "allowTemplateLiterals": true  }] semi [  "error",  "never"] [  "error",  "always"] error semi-spacing [  "error",  {    "before": false,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] error semi-style [  "error",  "last"] sort-keys [  "off",  "asc",  {    "caseSensitive": false,    "natural": true  }] sort-vars off space-before-blocks [  "error",  "always"] error error space-before-function-paren [  "error",  "always"] [  "error",  {    "anonymous": "always",    "named": "never",    "asyncArrow": "always"  }] [  "error",  {    "asyncArrow": "always",    "anonymous": "never",    "named": "never"  }] space-in-parens [  "error",  "never"] [  "error",  "never"] space-infix-ops error error space-unary-ops [  "error",  {    "words": true,    "nonwords": false  }] [  "error",  {    "words": true,    "nonwords": false,    "overrides": {}  }] spaced-comment [  "error",  "always",  {    "line": {      "markers": [        "package",        "!",        "/",        ",",        "="      ]    },    "block": {      "balanced": true,      "markers": [        "*package",        "!",        ",",        ":",        "::",        "flow-include"      ],      "exceptions": [        ""      ]    }  }] [  "error",  "always",  {    "line": {      "exceptions": [        "-",        "+"      ],      "markers": [        "=",        "!",        "/"      ]    },    "block": {      "exceptions": [        "-",        "+"      ],      "markers": [        "=",        "!",        ":",        "::"      ],      "balanced": true    }  }] [  "error",  "always"] switch-colon-spacing [  "error",  {    "after": true,    "before": false  }] error template-tag-spacing [  "error",  "never"] [  "error",  "never"] unicode-bom [  "error",  "never"] [  "error",  "never"] wrap-regex off ECMAScript 6 Rule eslint:recommended standard airbnb-base google arrow-body-style [  "error",  "as-needed",  {    "requireReturnForObjectLiteral": false  }] arrow-parens [  "error",  "always"] [  "error",  "always"] arrow-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": true,    "after": true  }] constructor-super error error error error generator-star-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] [  "error",  "after"] no-class-assign error error error no-confusing-arrow [  "error",  {    "allowParens": true  }] no-const-assign error error error no-dupe-class-members error error error no-duplicate-imports off no-new-symbol error error error error no-restricted-exports [  "off",  {    "restrictedNamedExports": [      "default",      "then"    ]  }] no-restricted-imports [  "off",  {    "paths": [],    "patterns": []  }] no-this-before-super error error error error no-useless-computed-key error error no-useless-constructor error error no-useless-rename error [  "error",  {    "ignoreDestructuring": false,    "ignoreImport": false,    "ignoreExport": false  }] no-var warn error error object-shorthand [  "error",  "always",  {    "ignoreConstructors": false,    "avoidQuotes": true  }] prefer-arrow-callback [  "error",  {    "allowNamedFunctions": false,    "allowUnboundThis": true  }] prefer-const [  "error",  {    "destructuring": "all",    "ignoreReadBeforeAssign": false  }] [  "error",  {    "destructuring": "any",    "ignoreReadBeforeAssign": true  }] [  "error",  {    "destructuring": "all",    "ignoreReadBeforeAssign": false  }] prefer-destructuring [  "error",  {    "VariableDeclarator": {      "array": false,      "object": true    },    "AssignmentExpression": {      "array": true,      "object": false    }  },  {    "enforceForRenamedProperties": false  }] prefer-numeric-literals error prefer-rest-params error error prefer-spread error error prefer-template error require-yield error error rest-spread-spacing [  "error",  "never"] [  "error",  "never"] error sort-imports [  "off",  {    "ignoreCase": false,    "ignoreDeclarationSort": false,    "ignoreMemberSort": false,    "memberSyntaxSortOrder": [      "none",      "all",      "multiple",      "single"    ]  }] symbol-description error error template-curly-spacing [  "error",  "never"] error yield-star-spacing [  "error",  "both"] [  "error",  "after"] [  "error",  "after"]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

eslint-config-○○の比較表

以下の4つの config の比較表です。 eslint:recommended eslint-config-standard eslint-config-airbnb-base eslint-config-google フレームワークを依らないルールについて比較したいので eslint-config-airbnb から React 関係の plugin を除外した eslint-config-airbnb-base を使用します。 バージョン情報 使用する各パッケージのバージョンは下記の通りです。 eslint: 7.25.0 eslint-config-standard: 16.0.2 eslint-config-airbnb-base: 14.2.1 eslint-config-google: 0.14.0 eslint-plugin-import: 2.22.1 eslint-plugin-node: 11.1.0 eslint-plugin-promise: 4.3.1 簡易版 (off, warn, error のみ) Possible Errors Rule eslint:recommended standard airbnb-base google for-direction error error getter-return error error no-async-promise-executor error error error no-await-in-loop error no-compare-neg-zero error error error no-cond-assign error error error off no-console warn no-constant-condition error error warn no-control-regex error error error no-debugger error error error no-dupe-args error error error no-dupe-else-if error off no-dupe-keys error error error no-duplicate-case error error error no-empty error error error no-empty-character-class error error error no-ex-assign error error error no-extra-boolean-cast error error error no-extra-parens error off no-extra-semi error error no-func-assign error error error no-import-assign error error off no-inner-declarations error error no-invalid-regexp error error error no-irregular-whitespace error error error error no-loss-of-precision error off no-misleading-character-class error error error no-obj-calls error error error no-promise-executor-return off no-prototype-builtins error error error no-regex-spaces error error error no-setter-return error off no-sparse-arrays error error error no-template-curly-in-string error error no-unexpected-multiline error error error error no-unreachable error error error no-unreachable-loop error off no-unsafe-finally error error error no-unsafe-negation error error error no-unsafe-optional-chaining no-useless-backreference error off require-atomic-updates off use-isnan error error error valid-typeof error error error Best Practices Rule eslint:recommended standard airbnb-base google accessor-pairs error off array-callback-return error error block-scoped-var error class-methods-use-this error complexity off consistent-return error curly error error error default-case error default-case-last error off default-param-last off dot-location error error dot-notation error error eqeqeq error error grouped-accessor-pairs off guard-for-in error error max-classes-per-file error no-alert warn no-caller error error error no-case-declarations error error error no-constructor-return off no-div-regex off no-else-return error no-empty-function error no-empty-pattern error error error no-eq-null off no-eval error error no-extend-native error error error no-extra-bind error error error no-extra-label error no-fallthrough error error error no-floating-decimal error error no-global-assign error error error no-implicit-coercion off no-implicit-globals off no-implied-eval error error no-invalid-this off error no-iterator error error no-labels error error no-lone-blocks error error no-loop-func error no-magic-numbers off no-multi-spaces error error error no-multi-str error error error no-new error error no-new-func error error no-new-wrappers error error error no-nonoctal-decimal-escape no-octal error error error no-octal-escape error error no-param-reassign error no-proto error error no-redeclare error error error no-restricted-properties error no-return-assign error error no-return-await error no-script-url error no-self-assign error error error no-self-compare error error no-sequences error error no-throw-literal error error error no-unmodified-loop-condition error off no-unused-expressions error error no-unused-labels error error no-useless-call error off no-useless-catch error error error no-useless-concat error no-useless-escape error error error no-useless-return error error no-void error error no-warning-comments off no-with error error error error prefer-named-capture-group off prefer-promise-reject-errors error error error prefer-regex-literals error off radix error require-await off require-unicode-regexp off vars-on-top error wrap-iife error error yoda error error Strict Mode Rule eslint:recommended standard airbnb-base google strict error Variables Rule eslint:recommended standard airbnb-base google init-declarations off no-delete-var error error error no-label-var error no-restricted-globals error no-shadow error no-shadow-restricted-names error error error no-undef error error error no-undef-init error error no-undefined off no-unused-vars error error error error no-use-before-define error error Stylistic Issues Rule eslint:recommended standard airbnb-base google array-bracket-newline off off array-bracket-spacing error error error array-element-newline off off block-spacing error error error brace-style error error error camelcase error error error capitalized-comments off comma-dangle error error error comma-spacing error error error comma-style error error error computed-property-spacing error error error consistent-this off eol-last error error error func-call-spacing error error error func-name-matching off func-names warn func-style off function-call-argument-newline off function-paren-newline error id-denylist off id-length off id-match off implicit-arrow-linebreak error indent error error error jsx-quotes off key-spacing error error error keyword-spacing error error error line-comment-position off linebreak-style error error lines-around-comment off lines-between-class-members error error max-depth off max-len error error max-lines off max-lines-per-function off max-nested-callbacks off max-params off max-statements off max-statements-per-line off multiline-comment-style off multiline-ternary error off new-cap error error error new-parens error error newline-per-chained-call error no-array-constructor error error error no-bitwise error no-continue error no-inline-comments off no-lonely-if error no-mixed-operators error error no-mixed-spaces-and-tabs error error error error no-multi-assign error no-multiple-empty-lines error error error no-negated-condition off no-nested-ternary error no-new-object error error error no-plusplus error no-restricted-syntax error no-tabs error error error no-ternary off no-trailing-spaces error error error no-underscore-dangle error no-unneeded-ternary error error no-whitespace-before-property error error nonblock-statement-body-position error object-curly-newline error error object-curly-spacing error error error object-property-newline error error one-var error error error one-var-declaration-per-line error operator-assignment error operator-linebreak error error error padded-blocks error error error padding-line-between-statements off prefer-exponentiation-operator off prefer-object-spread error quote-props error error error quotes error error error semi error error error semi-spacing error error error semi-style error sort-keys off sort-vars off space-before-blocks error error error space-before-function-paren error error error space-in-parens error error space-infix-ops error error space-unary-ops error error spaced-comment error error error switch-colon-spacing error error template-tag-spacing error error unicode-bom error error wrap-regex off ECMAScript 6 Rule eslint:recommended standard airbnb-base google arrow-body-style error arrow-parens error error arrow-spacing error error constructor-super error error error error generator-star-spacing error error error no-class-assign error error error no-confusing-arrow error no-const-assign error error error no-dupe-class-members error error error no-duplicate-imports off no-new-symbol error error error error no-restricted-exports off no-restricted-imports off no-this-before-super error error error error no-useless-computed-key error error no-useless-constructor error error no-useless-rename error error no-var warn error error object-shorthand error prefer-arrow-callback error prefer-const error error error prefer-destructuring error prefer-numeric-literals error prefer-rest-params error error prefer-spread error error prefer-template error require-yield error error rest-spread-spacing error error error sort-imports off symbol-description error error template-curly-spacing error error yield-star-spacing error error error 詳細版 Possible Errors Rule eslint:recommended standard airbnb-base google for-direction error error getter-return error [  "error",  {    "allowImplicit": true  }] no-async-promise-executor error error error no-await-in-loop error no-compare-neg-zero error error error no-cond-assign error error [  "error",  "always"] off no-console warn no-constant-condition error [  "error",  {    "checkLoops": false  }] warn no-control-regex error error error no-debugger error error error no-dupe-args error error error no-dupe-else-if error off no-dupe-keys error error error no-duplicate-case error error error no-empty error [  "error",  {    "allowEmptyCatch": true  }] error no-empty-character-class error error error no-ex-assign error error error no-extra-boolean-cast error error error no-extra-parens [  "error",  "functions"] [  "off",  "all",  {    "conditionalAssign": true,    "nestedBinaryExpressions": false,    "returnAssign": false,    "ignoreJSX": "all",    "enforceForArrowConditionals": false  }] no-extra-semi error error no-func-assign error error error no-import-assign error error off no-inner-declarations error error no-invalid-regexp error error error no-irregular-whitespace error error error error no-loss-of-precision error off no-misleading-character-class error error error no-obj-calls error error error no-promise-executor-return off no-prototype-builtins error error error no-regex-spaces error error error no-setter-return error off no-sparse-arrays error error error no-template-curly-in-string error error no-unexpected-multiline error error error error no-unreachable error error error no-unreachable-loop error [  "off",  {    "ignore": []  }] no-unsafe-finally error error error no-unsafe-negation error error error no-unsafe-optional-chaining no-useless-backreference error off require-atomic-updates off use-isnan error [  "error",  {    "enforceForSwitchCase": true,    "enforceForIndexOf": true  }] error valid-typeof error [  "error",  {    "requireStringLiterals": true  }] [  "error",  {    "requireStringLiterals": true  }] Best Practices Rule eslint:recommended standard airbnb-base google accessor-pairs [  "error",  {    "setWithoutGet": true,    "enforceForClassMembers": true,    "getWithoutSet": false  }] off array-callback-return [  "error",  {    "allowImplicit": false,    "checkForEach": false  }] [  "error",  {    "allowImplicit": true,    "checkForEach": false  }] block-scoped-var error class-methods-use-this [  "error",  {    "exceptMethods": []  }] complexity [  "off",  11] consistent-return error curly [  "error",  "multi-line"] [  "error",  "multi-line"] [  "error",  "multi-line"] default-case [  "error",  {    "commentPattern": "^no default$"  }] default-case-last error off default-param-last off dot-location [  "error",  "property"] [  "error",  "property"] dot-notation [  "error",  {    "allowKeywords": true,    "allowPattern": ""  }] [  "error",  {    "allowKeywords": true,    "allowPattern": ""  }] eqeqeq [  "error",  "always",  {    "null": "ignore"  }] [  "error",  "always",  {    "null": "ignore"  }] grouped-accessor-pairs off guard-for-in error error max-classes-per-file [  "error",  1] no-alert warn no-caller error error error no-case-declarations error error error no-constructor-return off no-div-regex off no-else-return [  "error",  {    "allowElseIf": false  }] no-empty-function [  "error",  {    "allow": [      "arrowFunctions",      "functions",      "methods"    ]  }] no-empty-pattern error error error no-eq-null off no-eval error error no-extend-native error error error no-extra-bind error error error no-extra-label error no-fallthrough error error error no-floating-decimal error error no-global-assign error error [  "error",  {    "exceptions": []  }] no-implicit-coercion [  "off",  {    "boolean": false,    "number": true,    "string": true,    "allow": []  }] no-implicit-globals off no-implied-eval error error no-invalid-this off error no-iterator error error no-labels [  "error",  {    "allowLoop": false,    "allowSwitch": false  }] [  "error",  {    "allowLoop": false,    "allowSwitch": false  }] no-lone-blocks error error no-loop-func error no-magic-numbers [  "off",  {    "ignore": [],    "ignoreArrayIndexes": true,    "enforceConst": true,    "detectObjects": false  }] no-multi-spaces error [  "error",  {    "ignoreEOLComments": false  }] error no-multi-str error error error no-new error error no-new-func error error no-new-wrappers error error error no-nonoctal-decimal-escape no-octal error error error no-octal-escape error error no-param-reassign [  "error",  {    "props": true,    "ignorePropertyModificationsFor": [      "acc",      "accumulator",      "e",      "ctx",      "context",      "req",      "request",      "res",      "response",      "$scope",      "staticContext"    ]  }] no-proto error error no-redeclare error [  "error",  {    "builtinGlobals": false  }] error no-restricted-properties [  "error",  {    "object": "arguments",    "property": "callee",    "message": "arguments.callee is deprecated"  },  {    "object": "global",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "self",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "window",    "property": "isFinite",    "message": "Please use Number.isFinite instead"  },  {    "object": "global",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "object": "self",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "object": "window",    "property": "isNaN",    "message": "Please use Number.isNaN instead"  },  {    "property": "&lowbar;&lowbar;defineGetter&lowbar;&lowbar;",    "message": "Please use Object.defineProperty instead."  },  {    "property": "&lowbar;&lowbar;defineSetter&lowbar;&lowbar;",    "message": "Please use Object.defineProperty instead."  },  {    "object": "Math",    "property": "pow",    "message": "Use the exponentiation operator (**) instead."  }] no-return-assign [  "error",  "except-parens"] [  "error",  "always"] no-return-await error no-script-url error no-self-assign error [  "error",  {    "props": true  }] [  "error",  {    "props": true  }] no-self-compare error error no-sequences error error no-throw-literal error error error no-unmodified-loop-condition error off no-unused-expressions [  "error",  {    "allowShortCircuit": true,    "allowTernary": true,    "allowTaggedTemplates": true,    "enforceForJSX": false  }] [  "error",  {    "allowShortCircuit": false,    "allowTernary": false,    "allowTaggedTemplates": false,    "enforceForJSX": false  }] no-unused-labels error error no-useless-call error off no-useless-catch error error error no-useless-concat error no-useless-escape error error error no-useless-return error error no-void error error no-warning-comments [  "off",  {    "terms": [      "todo",      "fixme",      "xxx"    ],    "location": "start"  }] no-with error error error error prefer-named-capture-group off prefer-promise-reject-errors error [  "error",  {    "allowEmptyReject": true  }] error prefer-regex-literals [  "error",  {    "disallowRedundantWrapping": true  }] off radix error require-await off require-unicode-regexp off vars-on-top error wrap-iife [  "error",  "any",  {    "functionPrototypeMethods": true  }] [  "error",  "outside",  {    "functionPrototypeMethods": false  }] yoda [  "error",  "never"] error Strict Mode Rule eslint:recommended standard airbnb-base google strict [  "error",  "never"] Variables Rule eslint:recommended standard airbnb-base google init-declarations off no-delete-var error error error no-label-var error no-restricted-globals [  "error",  {    "name": "isFinite",    "message": "Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite";  },  {    "name": "isNaN",    "message": "Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan";  },  "addEventListener",  "blur",  "close",  "closed",  "confirm",  "defaultStatus",  "defaultstatus",  "event",  "external",  "find",  "focus",  "frameElement",  "frames",  "history",  "innerHeight",  "innerWidth",  "length",  "location",  "locationbar",  "menubar",  "moveBy",  "moveTo",  "name",  "onblur",  "onerror",  "onfocus",  "onload",  "onresize",  "onunload",  "open",  "opener",  "opera",  "outerHeight",  "outerWidth",  "pageXOffset",  "pageYOffset",  "parent",  "print",  "removeEventListener",  "resizeBy",  "resizeTo",  "screen",  "screenLeft",  "screenTop",  "screenX",  "screenY",  "scroll",  "scrollbars",  "scrollBy",  "scrollTo",  "scrollX",  "scrollY",  "self",  "status",  "statusbar",  "stop",  "toolbar",  "top"] no-shadow error no-shadow-restricted-names error error error no-undef error error error no-undef-init error error no-undefined off no-unused-vars error [  "error",  {    "args": "none",    "caughtErrors": "none",    "ignoreRestSiblings": true,    "vars": "all"  }] [  "error",  {    "vars": "all",    "args": "after-used",    "ignoreRestSiblings": true  }] [  "error",  {    "args": "none"  }] no-use-before-define [  "error",  {    "functions": false,    "classes": false,    "variables": false  }] [  "error",  {    "functions": true,    "classes": true,    "variables": true  }] Stylistic Issues Rule eslint:recommended standard airbnb-base google array-bracket-newline [  "off",  "consistent"] off array-bracket-spacing [  "error",  "never"] [  "error",  "never"] [  "error",  "never"] array-element-newline [  "off",  {    "multiline": true,    "minItems": 3  }] off block-spacing [  "error",  "always"] [  "error",  "always"] [  "error",  "never"] brace-style [  "error",  "1tbs",  {    "allowSingleLine": true  }] [  "error",  "1tbs",  {    "allowSingleLine": true  }] error camelcase [  "error",  {    "allow": [      "^UNSAFE&lowbar;"    ],    "properties": "never",    "ignoreGlobals": true,    "ignoreDestructuring": false,    "ignoreImports": false  }] [  "error",  {    "properties": "never",    "ignoreDestructuring": false,    "ignoreImports": false,    "ignoreGlobals": false  }] [  "error",  {    "properties": "never",    "ignoreDestructuring": false,    "ignoreImports": false,    "ignoreGlobals": false  }] capitalized-comments [  "off",  "never",  {    "line": {      "ignorePattern": ".",      "ignoreInlineComments": true,      "ignoreConsecutiveComments": true    },    "block": {      "ignorePattern": ".",      "ignoreInlineComments": true,      "ignoreConsecutiveComments": true    }  }] comma-dangle [  "error",  {    "arrays": "never",    "objects": "never",    "imports": "never",    "exports": "never",    "functions": "never"  }] [  "error",  {    "arrays": "always-multiline",    "objects": "always-multiline",    "imports": "always-multiline",    "exports": "always-multiline",    "functions": "always-multiline"  }] [  "error",  "always-multiline"] comma-spacing [  "error",  {    "before": false,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] error comma-style [  "error",  "last"] [  "error",  "last",  {    "exceptions": {      "ArrayExpression": false,      "ArrayPattern": false,      "ArrowFunctionExpression": false,      "CallExpression": false,      "FunctionDeclaration": false,      "FunctionExpression": false,      "ImportDeclaration": false,      "ObjectExpression": false,      "ObjectPattern": false,      "VariableDeclaration": false,      "NewExpression": false    }  }] error computed-property-spacing [  "error",  "never",  {    "enforceForClassMembers": true  }] [  "error",  "never"] error consistent-this off eol-last error [  "error",  "always"] error func-call-spacing [  "error",  "never"] [  "error",  "never"] error func-name-matching [  "off",  "always",  {    "includeCommonJSModuleExports": false,    "considerPropertyDescriptor": true  }] func-names warn func-style [  "off",  "expression"] function-call-argument-newline [  "off",  "consistent"] function-paren-newline [  "error",  "consistent"] id-denylist off id-length off id-match off implicit-arrow-linebreak [  "error",  "beside"] indent [  "error",  2,  {    "SwitchCase": 1,    "VariableDeclarator": 1,    "outerIIFEBody": 1,    "MemberExpression": 1,    "FunctionDeclaration": {      "parameters": 1,      "body": 1    },    "FunctionExpression": {      "parameters": 1,      "body": 1    },    "CallExpression": {      "arguments": 1    },    "ArrayExpression": 1,    "ObjectExpression": 1,    "ImportDeclaration": 1,    "flatTernaryExpressions": false,    "ignoreComments": false,    "ignoredNodes": [      "TemplateLiteral ",      "JSXElement",      "JSXElement > ",      "JSXAttribute",      "JSXIdentifier",      "JSXNamespacedName",      "JSXMemberExpression",      "JSXSpreadAttribute",      "JSXExpressionContainer",      "JSXOpeningElement",      "JSXClosingElement",      "JSXFragment",      "JSXOpeningFragment",      "JSXClosingFragment",      "JSXText",      "JSXEmptyExpression",      "JSXSpreadChild"    ],    "offsetTernaryExpressions": true  }] [  "error",  2,  {    "SwitchCase": 1,    "VariableDeclarator": 1,    "outerIIFEBody": 1,    "FunctionDeclaration": {      "parameters": 1,      "body": 1    },    "FunctionExpression": {      "parameters": 1,      "body": 1    },    "CallExpression": {      "arguments": 1    },    "ArrayExpression": 1,    "ObjectExpression": 1,    "ImportDeclaration": 1,    "flatTernaryExpressions": false,    "ignoredNodes": [      "JSXElement",      "JSXElement > *",      "JSXAttribute",      "JSXIdentifier",      "JSXNamespacedName",      "JSXMemberExpression",      "JSXSpreadAttribute",      "JSXExpressionContainer",      "JSXOpeningElement",      "JSXClosingElement",      "JSXFragment",      "JSXOpeningFragment",      "JSXClosingFragment",      "JSXText",      "JSXEmptyExpression",      "JSXSpreadChild"    ],    "ignoreComments": false,    "offsetTernaryExpressions": false  }] [  "error",  2,  {    "CallExpression": {      "arguments": 2    },    "FunctionDeclaration": {      "body": 1,      "parameters": 2    },    "FunctionExpression": {      "body": 1,      "parameters": 2    },    "MemberExpression": 2,    "ObjectExpression": 1,    "SwitchCase": 1,    "ignoredNodes": [      "ConditionalExpression"    ],    "flatTernaryExpressions": false,    "offsetTernaryExpressions": false,    "ignoreComments": false  }] jsx-quotes [  "off",  "prefer-double"] key-spacing [  "error",  {    "beforeColon": false,    "afterColon": true  }] [  "error",  {    "beforeColon": false,    "afterColon": true  }] error keyword-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": true,    "after": true,    "overrides": {      "return": {        "after": true      },      "throw": {        "after": true      },      "case": {        "after": true      }    }  }] error line-comment-position [  "off",  {    "position": "above",    "ignorePattern": "",    "applyDefaultPatterns": true  }] linebreak-style [  "error",  "unix"] error lines-around-comment off lines-between-class-members [  "error",  "always",  {    "exceptAfterSingleLine": true  }] [  "error",  "always",  {    "exceptAfterSingleLine": false  }] max-depth [  "off",  4] max-len [  "error",  100,  2,  {    "ignoreUrls": true,    "ignoreComments": false,    "ignoreRegExpLiterals": true,    "ignoreStrings": true,    "ignoreTemplateLiterals": true  }] [  "error",  {    "code": 80,    "tabWidth": 2,    "ignoreUrls": true,    "ignorePattern": "goog.(module&verbar;require)"  }] max-lines [  "off",  {    "max": 300,    "skipBlankLines": true,    "skipComments": true  }] max-lines-per-function [  "off",  {    "max": 50,    "skipBlankLines": true,    "skipComments": true,    "IIFEs": true  }] max-nested-callbacks off max-params [  "off",  3] max-statements [  "off",  10] max-statements-per-line [  "off",  {    "max": 1  }] multiline-comment-style [  "off",  "starred-block"] multiline-ternary [  "error",  "always-multiline"] [  "off",  "never"] new-cap [  "error",  {    "newIsCap": true,    "capIsNew": false,    "properties": true  }] [  "error",  {    "newIsCap": true,    "newIsCapExceptions": [],    "capIsNew": false,    "capIsNewExceptions": [      "Immutable.Map",      "Immutable.Set",      "Immutable.List"    ],    "properties": true  }] error new-parens error error newline-per-chained-call [  "error",  {    "ignoreChainWithDepth": 4  }] no-array-constructor error error error no-bitwise error no-continue error no-inline-comments off no-lonely-if error no-mixed-operators [  "error",  {    "groups": [      [        "==",        "!=",        "===",        "!==",        ">",        ">=",        "<",        "<="      ],      [        "&&",        "&verbar;&verbar;"      ],      [        "in",        "instanceof"      ]    ],    "allowSamePrecedence": true  }] [  "error",  {    "groups": [      [        "%",        "*"      ],      [        "%",        "+"      ],      [        "%",        "-"      ],      [        "%",        ""      ],      [        "%",        "/"      ],      [        "/",        "*"      ],      [        "&",        "&verbar;",        "<<",        ">>",        ">>>"      ],      [        "==",        "!=",        "===",        "!=="      ],      [        "&&",        "&verbar;&verbar;"      ]    ],    "allowSamePrecedence": false  }] no-mixed-spaces-and-tabs error error error error no-multi-assign error no-multiple-empty-lines [  "error",  {    "max": 1,    "maxEOF": 0  }] [  "error",  {    "max": 1,    "maxBOF": 0,    "maxEOF": 0  }] [  "error",  {    "max": 2  }] no-negated-condition off no-nested-ternary error no-new-object error error error no-plusplus error no-restricted-syntax [  "error",  {    "selector": "ForInStatement",    "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array."  },  {    "selector": "ForOfStatement",    "message": "iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations."  },  {    "selector": "LabeledStatement",    "message": "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand."  },  {    "selector": "WithStatement",    "message": "`with` is disallowed in strict mode because it makes code impossible to predict and optimize."  }] no-tabs error error error no-ternary off no-trailing-spaces error [  "error",  {    "skipBlankLines": false,    "ignoreComments": false  }] error no-underscore-dangle [  "error",  {    "allow": [],    "allowAfterThis": false,    "allowAfterSuper": false,    "enforceInMethodNames": true,    "allowAfterThisConstructor": false,    "allowFunctionParams": true  }] no-unneeded-ternary [  "error",  {    "defaultAssignment": false  }] [  "error",  {    "defaultAssignment": false  }] no-whitespace-before-property error error nonblock-statement-body-position [  "error",  "beside",  {    "overrides": {}  }] object-curly-newline [  "error",  {    "multiline": true,    "consistent": true  }] [  "error",  {    "ObjectExpression": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ObjectPattern": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ImportDeclaration": {      "minProperties": 4,      "multiline": true,      "consistent": true    },    "ExportDeclaration": {      "minProperties": 4,      "multiline": true,      "consistent": true    }  }] object-curly-spacing [  "error",  "always"] [  "error",  "always"] error object-property-newline [  "error",  {    "allowMultiplePropertiesPerLine": true,    "allowAllPropertiesOnSameLine": false  }] [  "error",  {    "allowAllPropertiesOnSameLine": true,    "allowMultiplePropertiesPerLine": false  }] one-var [  "error",  {    "initialized": "never"  }] [  "error",  "never"] [  "error",  {    "var": "never",    "let": "never",    "const": "never"  }] one-var-declaration-per-line [  "error",  "always"] operator-assignment [  "error",  "always"] operator-linebreak [  "error",  "after",  {    "overrides": {      "?": "before",      ":": "before",      "&verbar;>": "before"    }  }] [  "error",  "before",  {    "overrides": {      "=": "none"    }  }] [  "error",  "after"] padded-blocks [  "error",  {    "blocks": "never",    "switches": "never",    "classes": "never"  }] [  "error",  {    "blocks": "never",    "classes": "never",    "switches": "never"  },  {    "allowSingleLineBlocks": true  }] [  "error",  "never"] padding-line-between-statements off prefer-exponentiation-operator off prefer-object-spread error quote-props [  "error",  "as-needed"] [  "error",  "as-needed",  {    "keywords": false,    "unnecessary": true,    "numbers": false  }] [  "error",  "consistent"] quotes [  "error",  "single",  {    "avoidEscape": true,    "allowTemplateLiterals": false  }] [  "error",  "single",  {    "avoidEscape": true  }] [  "error",  "single",  {    "allowTemplateLiterals": true  }] semi [  "error",  "never"] [  "error",  "always"] error semi-spacing [  "error",  {    "before": false,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] error semi-style [  "error",  "last"] sort-keys [  "off",  "asc",  {    "caseSensitive": false,    "natural": true  }] sort-vars off space-before-blocks [  "error",  "always"] error error space-before-function-paren [  "error",  "always"] [  "error",  {    "anonymous": "always",    "named": "never",    "asyncArrow": "always"  }] [  "error",  {    "asyncArrow": "always",    "anonymous": "never",    "named": "never"  }] space-in-parens [  "error",  "never"] [  "error",  "never"] space-infix-ops error error space-unary-ops [  "error",  {    "words": true,    "nonwords": false  }] [  "error",  {    "words": true,    "nonwords": false,    "overrides": {}  }] spaced-comment [  "error",  "always",  {    "line": {      "markers": [        "package",        "!",        "/",        ",",        "="      ]    },    "block": {      "balanced": true,      "markers": [        "*package",        "!",        ",",        ":",        "::",        "flow-include"      ],      "exceptions": [        ""      ]    }  }] [  "error",  "always",  {    "line": {      "exceptions": [        "-",        "+"      ],      "markers": [        "=",        "!",        "/"      ]    },    "block": {      "exceptions": [        "-",        "+"      ],      "markers": [        "=",        "!",        ":",        "::"      ],      "balanced": true    }  }] [  "error",  "always"] switch-colon-spacing [  "error",  {    "after": true,    "before": false  }] error template-tag-spacing [  "error",  "never"] [  "error",  "never"] unicode-bom [  "error",  "never"] [  "error",  "never"] wrap-regex off ECMAScript 6 Rule eslint:recommended standard airbnb-base google arrow-body-style [  "error",  "as-needed",  {    "requireReturnForObjectLiteral": false  }] arrow-parens [  "error",  "always"] [  "error",  "always"] arrow-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": true,    "after": true  }] constructor-super error error error error generator-star-spacing [  "error",  {    "before": true,    "after": true  }] [  "error",  {    "before": false,    "after": true  }] [  "error",  "after"] no-class-assign error error error no-confusing-arrow [  "error",  {    "allowParens": true  }] no-const-assign error error error no-dupe-class-members error error error no-duplicate-imports off no-new-symbol error error error error no-restricted-exports [  "off",  {    "restrictedNamedExports": [      "default",      "then"    ]  }] no-restricted-imports [  "off",  {    "paths": [],    "patterns": []  }] no-this-before-super error error error error no-useless-computed-key error error no-useless-constructor error error no-useless-rename error [  "error",  {    "ignoreDestructuring": false,    "ignoreImport": false,    "ignoreExport": false  }] no-var warn error error object-shorthand [  "error",  "always",  {    "ignoreConstructors": false,    "avoidQuotes": true  }] prefer-arrow-callback [  "error",  {    "allowNamedFunctions": false,    "allowUnboundThis": true  }] prefer-const [  "error",  {    "destructuring": "all",    "ignoreReadBeforeAssign": false  }] [  "error",  {    "destructuring": "any",    "ignoreReadBeforeAssign": true  }] [  "error",  {    "destructuring": "all",    "ignoreReadBeforeAssign": false  }] prefer-destructuring [  "error",  {    "VariableDeclarator": {      "array": false,      "object": true    },    "AssignmentExpression": {      "array": true,      "object": false    }  },  {    "enforceForRenamedProperties": false  }] prefer-numeric-literals error prefer-rest-params error error prefer-spread error error prefer-template error require-yield error error rest-spread-spacing [  "error",  "never"] [  "error",  "never"] error sort-imports [  "off",  {    "ignoreCase": false,    "ignoreDeclarationSort": false,    "ignoreMemberSort": false,    "memberSyntaxSortOrder": [      "none",      "all",      "multiple",      "single"    ]  }] symbol-description error error template-curly-spacing [  "error",  "never"] error yield-star-spacing [  "error",  "both"] [  "error",  "after"] [  "error",  "after"]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】繰り返し処理を利用し、西暦2000年から本日までの西暦の年のみを全て表示

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>2000年から本日までの年だけを全て表示</title> </head> <body> <script> document.write('<p>' + '↓現在日時分秒を取得(new Dateメソッド)' + '</p>') // ←任意行 var date = new Date(); document.write('<p>' + date + '</p>') // ←任意行 document.write('<p>' + '↓現在日時から「年」のみを取得(getFullYeaメソッド)' + '</p>') // ←任意行 var year = date.getFullYear(); document.write('<p>' + year +'がyaerに入る' + '</p>') // ←任意行 document.write('<p>' + '↓初期値を設定' + '</p>') // ←任意行 for (var i = 2000; i<= year; i++) { document.write('<p>' + i + '</p>') } </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React + OpenWeatherMap API で現在の気象を表示する

はじめに React-Leafletでマップを表示で地図を表示させ、マーカーを置いた。この記事では、OpenWeatherMap の API である Weather maps 1.0 を用いて、気象データを地図に重ね合わせる。React Leaflet、Weather maps 1.0 を参考にした。また leaflet や react-leaflet はインストール済みという前提で進める。インストールをしていない場合はReact-Leafletでマップを表示を参照。 API キーの取得 OpenWeatherMap の API から気象海象データを取得するには、API キーを取得する必要がある。Create New Account にてアカウントを作成すればキーを取得できる。いくつか制限はあるが、無料版で十分すぎる機能が使える。 コンポーネントの作成 地図を表示させ、さらに気象データを重ねるコンポーネントのコードを以下に示す。このコンポーネントでは現在の雲、降水量、海面気圧、風速、気温の5つの気象データを重ねることができる。 Weather.js import React from "react"; import "leaflet/dist/leaflet.css"; import { LayersControl, MapContainer, TileLayer, WMSTileLayer } from "react-leaflet"; const APIKey = "取得した API キーを書く"; const SimpleLeaflet = () => { const position = [35.685175, 139.7528]; return ( <div> <MapContainer center={position} zoom={13} style={{ height: "100vh" }} > <TileLayer attribution='&amp;copy <a href="http://osm.org/copyright";>OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <LayersControl position="topright" > <LayersControl.Overlay name="Cloud" checked> <WMSTileLayer url={`https://tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=${APIKey}`} /> </LayersControl.Overlay> <LayersControl.Overlay name="Precipitation"> <WMSTileLayer url={`https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid=${APIKey}`} /> </LayersControl.Overlay> <LayersControl.Overlay name="Sea Level Pressure"> <WMSTileLayer url={`https://tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=${APIKey}`} /> </LayersControl.Overlay> <LayersControl.Overlay name="Wind Speed"> <WMSTileLayer url={`https://tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=${APIKey}`} /> </LayersControl.Overlay> <LayersControl.Overlay name="Temperature"> <WMSTileLayer url={`https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid=${APIKey}`} /> </LayersControl.Overlay> </LayersControl> </MapContainer> </div> ) } export default SimpleLeaflet; 上記コンポーネントを読み込んで、開発用サーバーで実行した結果を以下に示す。 LayersControl を使用することで、上記 GIF のようにどの Layer を重ねるか選択できるようにしている。また LayersControl.Overlay タグ内に 'checked' と追記することで、デフォルトで選択状態にできる。 Layers control | React Leaflet に Layer のグループ分けなど細かい編集の例なども載っている。 おわりに 今回は Weather maps 1.0 を試してみた。現在は Weather maps 2.0 がローンチしており、そこでは予報データや過去のデータも取得できるとのことだったが、試したところ結果がうまく反映されなかったので、うまく扱える人がいたら教えて下さい。 (2021/5/7 追記) 直接 OpenWeatherMap に問い合わせたところ、無料版では対応していないとのこと。Detailed price - OpenWeatherMap にたしかにそう書いてある。試せなくて残念。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

errorの内容だけ返す関数の作成

与えられた配列にエラーナンバー、エラーの内容、エラーの発生した日時を含む要素からエラーの内容だけ抜き出す関数を考える const errorLogs = [ "Error 101:Invalid Exception AAA - 2020/01/01/01:00", "Error 3:Invalid Exception BBBB - 2020/01/01/02:00", "Error 22:Invalid Exception CCCCC - 2020/01/01/03:00", ]; ここから下記のものだけを抜き出して出力したい // Invalid Exception AAA // Invalid Exception BBBB // Invalid Exception CCCCC 考えたこと ①:から-の間の文字を抜き出せば良い ②:,-を見つける =>indexOfの利用 ③指定した文字列だけを抜き出す =>substrの利用 const errorLogs = [ "Error 101:Invalid Exception AAA - 2020/01/01/01:00", "Error 3:Invalid Exception BBBB - 2020/01/01/02:00", "Error 22:Invalid Exception CCCCC - 2020/01/01/03:00", ]; function findError(num) { const findDoubleColon = errorLogs[num].indexOf(":"); const findHyphen = errorLogs[num].indexOf("-"); const Error = errorLogs[num].substr( findDoubleColon + 1, findHyphen - findDoubleColon - 1 ); return Error; } for (i = 0; i < errorLogs.length; i++) { console.log(findError(i)); } //実行結果 //Invalid Exception AAA //Invalid Exception BBBB //Invalid Exception CCCCC P.S.以前コメントいただいた変数の命名方法が雑いという意見はもう少し勉強してから反映させていきます 貴重なご意見ありがとうございます お気づきの点がありましたら今後もコメントお願い致します
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptの基礎を改めて Part3

JavaScriptを学習して重要だと感じた点をまとめていく。 正規表現 正規表現と文字列のパターンを定義したもの。 正規表現オブジェクトはリテラルかRegExpコンストラクタで作成する。 例1 const patternA = /a+/; // aという文字列が1回以上連続している文字列を表現 const patternB = new RegExp("\s{4}"); // スペースが4回以上連続している文字列を表現 正規表現を用いることでより広範囲な文字検索ができるようになる。 正規表現の種類についてはこちらに網羅されている。 クロージャー JavaScript Primerでは以下のように解説している。 クロージャーとは「外側のスコープにある変数への参照を保持できる」という関数が持つ性質のことです。 ※ JavaScript Primerの項目クロージャーより抜粋。 https://jsprimer.net/basic/function-scope/#closure クロージャーはガベージコレクションと静的スコープの性質を利用しているので、 まずはガベージコレクションと静的スコープについてまとめていく。 ※ ガベージコレクションと静的スコープが理解できているなら後述の「クロージャー(続き)」に飛んでください。 ガベージコレクション メモリ上に展開されている使わなくなった変数などを開放すること。 (前提知識:プログラム上で定義された変数などのオブジェクトはメモリ上に展開される) 具体的にはメモリ上に展開されているオブジェクトが「どのオブジェクトからも参照されない状態」になるとガベージコレクションが動く。 例2 let str = "abc"; /* "abc"という文字列データがメモリ上に展開される。 この時点では変数strが"abc"を参照している。 */ str = "def"; /* "def"という文字列データがメモリ上に展開される。(変数strの中身が変わる) この時点で文字列"abc"を参照しているオブジェクトはないためガベージコレクションによって 文字列"abc"がメモリ上から開放される。 */ console.log(str); >> "def" 逆に「何かしらのオブジェクトに参照されている状態」をキープすればメモリ上に残しておきたいオブジェクトを ガベージコレクションの対象外にすることができる。 例3 const createString = () => { let str = "abc"; return str; } const getString = createString(); // 変数getStringに関数createStringの結果を代入。 console.log(getString); >> abc // 文字列"abc"は変数getStringに参照されているためガベージコレクションの対象外となる。 静的スコープ * オブジェクト呼び出し時に参照する範囲(スコープ)および順番を静的に決定しているもの。 JavaScriptはオブジェクト呼び出し時にまず呼び出されたスコープ内で対象となるオブジェクトを参照(探す)する。 オブジェクトが呼び出されたスコープ内で対象オブジェクトが見つからなかった場合は、 一つ外側のスコープで対象オブジェクトを参照(探す)する。 この参照範囲が遷移する動きをスコープチェーンという。 例4 const x = "エックス"; const y = "ワイ"; // グローバルスコープ内で変数x,yを定義。 const callXY = () => { const x = "えっくす"; // 関数callXYの関数スコープ内で変数xを定義 console.log(x); // 変数xを呼び出す。 >> "えっくす" // 変数xを呼び出したスコープ(今回の例だとcallXYの関数スコープ)内にある変数xを参照。 console.log(y); >> "ワイ" /* 変数yが関数callXYの関数スコープ内に無いため一つ外側のスコープ(今回の例だとグローバルスコープ)で 定義されている変数yを参照する。 */ } クロージャー(続き) * クロージャーを使うことによって関数内に残しておきたいオブジェクトをガベージコレクションされずに 保持することができるようになる。 例5 const createCount = () => { let count = 0; // 関数createCountのスコープ内に変数countを定義。 return function plusCount() { count += 1; /* 関数plusCountのスコープ内に変数countが定義されていないのでスコープチェーンによって 関数createCountのスコープ内に定義されている変数countが参照される。 */ return count; }; }; const myCount = createCount(); console.log(myCount); >> 1 console.log(myCount); >> 2 console.log(myCount); >> 3 /* 変数countは関数createCountに参照されているためガベージコレクションされずに 関数plusCountで+1された変数countを保持することができる。 */
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2021年現在】初心者でもご安心。chartkickのインストールの仕方(rails 6)

アプリケーションにグラフを差し込むのに便利なchartkickの説明(導入メイン)となります。 1.Chartkickの導入 gemfileに gem 'chartkick' を記述。その後忘れずにbundle installも! 続いて % yarn add chartkick chart.js ※こちらのコマンド忘れずに そしてapp/javascript/packs/application.js内に import "chartkick/chart.js" を記述する! ※もしグラフが上手く表示されない場合は app/javascript/packs/application.js内の記述を import "chartkick/chart.js"ではなく require("chartkick") require("chart.js") としてみてください。 rails5以前 の方は //= require chartkick //= require Chart.bundle こちらを。 2.グラフ表示 いよいよグラフ表示です! グラフを表示させたい「○○.html.erb」に <%= pie_chart [['赤', 50], ['青', 50]]%> と記述。 この段階で画面上に円グラフが表示されているか確認することで、chartkickがちゃんと導入できているか確認することができます。 ※もし上手く表示されない場合、『サーバー閉じてからのrails s』  もしくは『js内の記述を変更』してみてください 3.グラフについて pie_chartの部分を変更すればグラフの種類も変更可能です column_chart(縦棒グラフ) bar_chart(横棒グラフ) line_chart(折れ線グラフ) 今回は速攻でグラフが表示されるかを確認するためコントローラーを経由せず、ビュー内に直接データ記述(赤50青50)しました。 一般的な使い方としては コントローラ内にデータ記述する方法など色々ありますので下のリンクをご参考に。 参考サイト chartkick 【Rails】Rails完結!グラフを簡単に作成できるライブラリChartkickについて簡単にまとめてみた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactで画像アップロード機能を実装してローカルファイルを読み込ませる

FileReaderを使ってローカルにある画像をアップロードさせる機能の作り方を実装します。 この記事をベースにした別記事も用意しています 準備中:Firebaseを使わずにブラウザ上でローカル画像のサイズをリサイズする new Image() のcanvasを利用した方法 完成品 ソースコード:https://codesandbox.io/s/react-img-upload-e4q8s?file=/src/App.js 無駄な要素は極力はぶいた簡素なアップローダーにしました。 FileReaderを使って実装 imgUploader.jsx import { useState } from "react"; import "./styles.css"; const App = () => { const [uploadImg, setUploadImg] = useState(""); const handleUploadImg = (e) => { if (!e.currentTarget.files || e.currentTarget.files.length === 0) return; const fileReader = new FileReader(); const file = e.currentTarget.files[0]; if (file.type !== "image/jpeg" && file.type !== "image/png") return; fileReader.onloadend = () => { setUploadImg(fileReader.result); }; fileReader.readAsDataURL(file); }; return ( <div className="App"> <h1>React画像アップロード</h1> <input type="file" onChange={(e) => handleUploadImg(e)} /> <div style={{ margin: "10px" }}> <img src={uploadImg} alt="アップロード画像" style={{ maxWidth: "200px" }} /> </div> </div> ); }; export default App; JSXエレメントの解説 省略 <input type="file" onChange={(e) => handleUploadImg(e)} /> 省略 上記のように input の属性 file に指定して onChange で画像を選ばれた後に関数が走るようにしておきます。 省略 <img src={uploadImg} alt="アップロード画像" style={{ maxWidth: "200px" }} /> 省略 src={} の中身には uploadImg の state を入れておきます。 state は onChange の中の関数(handleUploadImg)で変化させます。 handleUploadImgの解説 handleUploadImg.jsx const handleUploadImg = (e) => { if (!e.currentTarget.files || e.currentTarget.files.length === 0) return; //ファイルが存在しない状態ならそのまま離脱 const fileReader = new FileReader(); const file = e.currentTarget.files[0]; if (file.type !== "image/jpeg" && file.type !== "image/png") return; //ファイル形式が jpeg, png 以外なら離脱 fileReader.onloadend = () => { setUploadImg(fileReader.result); //resultの中にblob形式の画像データとして画像が格納されているのでそれをイメージ画像として読み込む }; fileReader.readAsDataURL(file); //new FileReader()インスタンスの readAsDataURL() メソッドを使ってアップロードしたファイルをそのまま読み込ませて fireReader.onloadend を走らせ fileReader.result の中身を取り出す }; 以上のように簡単に実装することができます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】1から100までの整数に対し、 3で割り切れる場合は「Fizz」 5で割り切れる場合は「Buzz」 3でも5でも割り切れる場合は「FizzBuzz」 上記以外は数値そのまま を表示。 ※どの繰り返し処理を利用するかは自由。

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>FizzBuzz</title> </head> <body> <script> var i = 0; while (i <= 100) { i++; if (i % 3 === 0 && i % 5 === 0){ document.write('<p>FizzBuzz【' + i + '】3でも5でも割り切れる</p>'); } else if (i % 3 === 0) { document.write('<p>Fizz【' + i + '】3で割り切れる</p>'); } else if (i % 5 === 0){ document.write('<p>Buzz【' + i + '】5で割り切れる</p>'); } else { document.write('<p>' +i+ '</p>' ); } } </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrap 5 と smooth-scroll.js の相性が悪かった話

どのような現象になるか Bootstrap5 と smooth-scroll.js (など、おそらく JavaScript を使ってのスムーズスクロール全般に言える可能性がある)を導入すると、スクロールが ”つっかかる” 動きになりました。(Chrome,Edge で確認。その他未確認。) Bootstrap4 ではそのような動きでなかったため、どの部分で相性が悪いのかと探っていたら、Bootstrap5では、しれっと、CSSでスムーズスクロールを実現する、scroll-behavior: smooth; が入っていやがりました。 ひとまず こうやることで回避 Bootstrap 5 の CSS から、以下が省かれていれば良いってことになるはずです。 @media (prefers-reduced-motion: no-preference) { :root { scroll-behavior: smooth; } } せいぜい上記部分なので、ダウンロードしたCSSを直接編集でも大丈夫かと思いますが、カスタマイズのやり方は以下などにて。 結論 素直にCSS scroll-behavior: smooth; を導入しましょう! smooth-scroll.js のgithubを確認すると、「DEPRECATION NOTICE」 つまり 「廃止の通知」となっていて、CSSで導入したほうが良いよ、みたいな事が書いてありました…… ヘッダサイズの調整について CSS scroll-margin-top で調整しましょう。 こんな感じ。 html, body { scroll-padding-top: 60px; } ヘッダのサイズを自動で取得してくれるんで、js の方が楽ちんなんだけどなぁ。 bootstrap5 でヘッダサイズ算出機能やスピード調整などもあると良いですね。(あるかも知れないですね) safari ブラウザについて 知らない子にしちゃおう…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScript input要素に対して使用可能なカラーピッカーUIを作成

input要素で使用可能なカラーピッカーです。 screen shot グラデーションにはcanvasは使わず、CSSのconic-gradient()とlinear-gradient()のみで表示しています。 表示中のリサイズ(UIの右下ドラッグ)も可能です。 script color_picker.js 'use strict'; { const obj = { color: {h: 0, s: 0, v: 1}, }, eventListenerManage = (function() { const events = {}; let key = 1; return { add: function(target, type, listener, capture) { target.addEventListener(type, listener, capture); events[key] = { target: target, type: type, listener: listener, capture: capture }; return key++; }, remove: function(key) { if(key in events) { const e = events[key]; e.target.removeEventListener(e.type, e.listener, e.capture); delete(events[key]); } } }; }()), touchFlg = window.ontouchstart !== undefined ? true : false, uid = '-' + Math.random().toString(36).slice(-4); window.addEventListener('DOMContentLoaded', function() { // picker elements document.querySelector('body').innerHTML += ` <div class='colorPicker${uid}'> <div class='circle${uid}'></div> <div class='innerCircle${uid}'> <div class='pointer${uid}'></div> </div> <div class='circleInput${uid}'></div> <div class='rect${uid}'> <div class='rectMask${uid}'></div> <div class='pointer${uid}'> <div class='circle1${uid}'></div> <div class='circle2${uid}'></div> </div> </div> <div class='rectInput${uid}'></div> <div class='resize${uid}'></div> <input type='${touchFlg ? 'checkbox' : 'text'}' class='d${uid}'> </div> `; // elements style set let s = (obj.picker = document.querySelector('div.colorPicker' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.overflow = 'hidden'; s.width = s.height = '200px'; // hue ring s = (obj.circle = obj.picker.querySelector('.circle' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = '100%'; s.borderRadius = '50%'; const g = []; for(let i = 0; i <= 360; i += 60) { g.push(`hsl(${i}deg 100% 50%) ${i}deg`); } s.backgroundImage = `conic-gradient(${g.join(',')})`; s = (obj.circleInput = obj.picker.querySelector('.circleInput' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = '100%'; s.borderRadius = '50%'; s = (obj.innerCircle = obj.picker.querySelector('.innerCircle' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = '80%'; s.top = s.left = '10%'; s.backgroundColor = '#fff'; s.borderRadius = '50%'; s = (obj.circlePointer = obj.innerCircle.querySelector('.pointer' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = '4%'; s.height = '10%'; s.top = '-11.4%'; s.left = '48%'; s.border = '1px #000 solid'; // color rectangle s = (obj.rect = obj.picker.querySelector('.rect' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = (75 / Math.sqrt(2)) + '%'; s.top = s.left = (50 - (75 / Math.sqrt(2) / 2)) + '%'; s.backgroundColor = '#f00'; s = (obj.rectInput = obj.picker.querySelector('.rectInput' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = (88 / Math.sqrt(2)) + '%'; s.top = s.left = (50 - (88 / Math.sqrt(2) / 2)) + '%'; // gradation filter s = (obj.rectMask = obj.rect.querySelector('.rectMask' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = '100%'; s.backgroundImage = 'linear-gradient(to top, #000 0%, #0000 100%), linear-gradient(to left, #fff0 0%, #fff 100%)'; s = (obj.rectPointer = obj.rect.querySelector('.pointer' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.width = s.height = '10%'; s.top = s.left = '0'; s = (obj.rectPointerCircle1 = obj.rectPointer.querySelector('.circle1' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.top = s.left = '-50%'; s.width = s.height = '100%'; s.border = '3px #fff solid'; s.borderRadius = '50%'; s = (obj.rectPointerCircle2 = obj.rectPointer.querySelector('.circle2' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.top = s.left = (-50 + (100 - 95) / 2) + '%'; s.width = s.height = '95%'; s.border = '1px #000 solid'; s.borderRadius = '50%'; // resize icon s = (obj.resize = obj.picker.querySelector('.resize' + uid)).style; s.position = 'absolute'; s.boxSizing = 'border-box'; s.borderRight = s.borderBottom = '1px #888 solid'; s.width = s.height = '10%'; s.right = s.bottom = '0'; s.cursor = 'nwse-resize'; s = (obj.d = obj.picker.querySelector('.d' + uid)).style; s.position = 'absolute'; s.left = s.top = '-600px'; obj.picker.style.display = 'none'; // picker eventListener set const ev = { mousedown: touchFlg ? 'touchstart' : 'mousedown', mousemove: touchFlg ? 'touchmove' : 'mousemove', mouseup: touchFlg ? 'touchend' : 'mouseup', }; obj.circleInput.addEventListener(ev.mousedown, function(e) { obj.d.focus(); obj.circleInput.style.zIndex = '1'; obj.t = 'circle'; circleInput(e); feedbackValue(obj.p); obj.touchmoveId = eventListenerManage.add(obj.picker, 'touchmove', function(e) { e.preventDefault(); }, { passive: false }); }); obj.rectInput.addEventListener(ev.mousedown, function(e) { obj.d.focus(); obj.t = 'rect'; rectInput(e); feedbackValue(obj.p); obj.touchmoveId = eventListenerManage.add(obj.picker, 'touchmove', function(e) { e.preventDefault(); }, { passive: false }); }); obj.resize.addEventListener(ev.mousedown, function(e) { obj.d.focus(); obj.t = 'resize'; obj.pageX = obj.picker.offsetLeft; obj.pageY = obj.picker.offsetTop; obj.touchmoveId = eventListenerManage.add(obj.picker, 'touchmove', function(e) { e.preventDefault(); }, { passive: false }); }); window.addEventListener(ev.mousemove, function(e) { if(obj.t !== 'resize') return; const h = (touchFlg ? e.touches[0].pageX : e.pageX) - obj.pageX; const v = (touchFlg ? e.touches[0].pageY : e.pageY) - obj.pageY; const size = Math.max(100, Math.min(h, v)); obj.picker.style.width = obj.picker.style.height = size + 'px'; obj.rectPointer.style.left = (obj.rect.clientWidth * obj.color.s) + 'px'; obj.rectPointer.style.top = (obj.rect.clientHeight * (1 - obj.color.v)) + 'px'; }); window.addEventListener(ev.mouseup, function(e) { setTimeout(function() { obj.t = ''; obj.circleInput.style.zIndex = ''; if(obj.touchmoveId) { eventListenerManage.remove(obj.touchmoveId); obj.touchmoveId = 0; } }); if(obj.t !== undefined && obj.t !== '' || obj.windowScroll == 1) return; obj.picker.style.display = 'none'; if(obj.p !== undefined) { delete obj.p; for(const e of elements) { e.dataset.colorpickerDisplay = 0; } } }); obj.circleInput.addEventListener(ev.mousemove, function(e) { if(obj.t === undefined || obj.t !== 'circle') return; circleInput(e); obj.rect.style.backgroundColor = `hsl(${obj.color.h}deg 100% 50%)`; feedbackValue(obj.p); }); obj.rectInput.addEventListener(ev.mousemove, function(e) { if(obj.t === undefined || obj.t !== 'rect') return; rectInput(e); feedbackValue(obj.p); }); window.addEventListener(ev.mousedown, function(e) { obj.windowScroll = 0; }); window.addEventListener('touchmove', function(e) { obj.windowScroll = 1; }); // target elements eventListener set const elements = document.querySelectorAll('input[data-colorpicker]'); let i = 1; for(const e of elements) { e.dataset.colorpickerId = i++; e.addEventListener('click', function() { if(e.dataset.colorpickerDisplay & 1) { obj.picker.style.display = 'none'; e.dataset.colorpickerDisplay = 0; } else { const size = e.dataset.colorpicker.match(/size[^:]*:\s*([.\d]+)/i); obj.picker.style.width = obj.picker.style.height = (size !== null ? Math.max(100, size[1]) : 200) + 'px'; displayPicker(e); obj.rectPointer.style.left = obj.rectPointer.style.top = '0'; obj.rect.style.backgroundColor = '#f00'; obj.innerCircle.style.transform = 'rotate(0deg)'; const p = document.createElement('p'); p.style.color = e.value; const rgb = p.style.color.match(/\d+/g); if(rgb !== null) { const hsv = rgb2hsv(+rgb[0], +rgb[1], +rgb[2]); obj.innerCircle.style.transform = `rotate(${hsv.h}deg)`; obj.rectPointer.style.left = (obj.rect.clientWidth * hsv.s) + 'px'; obj.rectPointer.style.top = (obj.rect.clientHeight * (1 - hsv.v)) + 'px'; obj.rect.style.backgroundColor = `hsl(${hsv.h}deg 100% 50%)`; obj.color = {h: hsv.h, s: hsv.s, v: hsv.v}; } e.dataset.colorpickerDisplay = 1; if(obj.p !== undefined) { if(e.dataset.colorpickerId !== obj.p.dataset.colorpickerId) obj.p.dataset.colorpickerDisplay = 0; } obj.p = e; } }); } }); // functions function displayPicker(e) { obj.picker.style.display = 'block'; const x = e.offsetLeft + obj.picker.clientWidth <= window.innerWidth || window.innerWidth < obj.picker.clientWidth ? e.offsetLeft : window.innerWidth - obj.picker.clientWidth; obj.picker.style.left = x + 'px'; obj.picker.style.top = (8 + e.offsetTop + e.clientHeight) + 'px'; obj.color = {h: 180, s: 0, v: 1}; setTimeout(function() { obj.d.focus();}); } function circleInput(e) { const h = obj.circle.clientWidth, v = obj.circle.clientHeight, x = touchFlg ? e.touches[0].clientX - obj.picker.offsetLeft + window.scrollX : e.layerX, y = touchFlg ? e.touches[0].clientY - obj.picker.offsetTop + window.scrollY : e.layerY, at = Math.atan2(v / 2 - y , h / 2 - x), k = ((at * (360 / (Math.PI * 2))) + 270) % 360; obj.innerCircle.style.transform = `rotate(${k}deg)`; obj.color.h = k; } function rectInput(e) { const h = obj.rect.clientWidth, v = obj.rect.clientHeight, x_ = (touchFlg ? e.touches[0].clientX - obj.rectInput.offsetLeft - obj.picker.offsetLeft + window.scrollX : e.layerX) - (obj.rectInput.clientWidth - h) / 2, y_ = (touchFlg ? e.touches[0].clientY - obj.rectInput.offsetTop - obj.picker.offsetTop + window.scrollY : e.layerY) - (obj.rectInput.clientHeight - v) / 2, x = x_ < 0 ? 0 : x_ > h ? h : x_, y = y_ < 0 ? 0 : y_ > v ? v : y_; obj.rectPointer.style.left = x + 'px'; obj.rectPointer.style.top = y + 'px'; obj.color.s = x / h; obj.color.v = 1 - y / v; } function feedbackValue(e) { const c = obj.color; e.value = hsv2rgb(c.h, c.s, c.v); e.style.backgroundColor = e.value; const rgb = e.style.backgroundColor.match(/\d+/g); if(rgb !== null) { const l = (rgb[0] * 2 + rgb[1] * 4 + +rgb[2]) / 3; e.style.color = l > 300 ? '#000' : '#fff'; } } function hsv2rgb(h, s, v) { h /= 60; const c = [v, v, v], a = Math.floor(h), f = h - a; c[Math.floor(a / 2 + 2) % 3] *= (1 - s); c[(7 - a) % 3] *= (1 - s * (a % 2 ? f : 1 - f)); for (let i in c) c[i] = Math.round(c[i] * 255); return '#' + ('00000' + (c[0] << 16 | c[1] << 8 | c[2]).toString(16)).slice(-6); } function rgb2hsv(r, g, b) { const v = Math.max(r, g, b), d = v - Math.min(r, g, b), s = v ? d / v : 0, h = s ? (v === r ? (g - b) / d + (g < b ? 6 : 0) : v === g ? 2 + (b - r) / d : 4 + (r - g) / d) * 60 : 0; return {h: h, s: s, v: v / 255}; } } 使用方法 scriptタグでcolor_picker.jsを読み込み、対象input要素にdata-colorpicker属性を付加することで適用できます。 input要素のtypeはとくに制限していませんが、text推奨です。 <script src='color_picker.js'></script> <input type='text' data-colorpicker> <input type='text' data-colorpicker='size:300'> オプションで値に初期サイズを指定できます。 単位はpixel、最小値は100、無指定時のデフォルトは200です。 サンプル <!DOCTYPE html> <html lang='ja'> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1"> <script src='color_picker.js'></script> </head> <body> <input type='text' data-colorpicker value='#ffff00'> <input type='text' data-colorpicker> <input type='text' data-colorpicker='size:300'> <input type='text' data-colorpicker='size:250'> <br> <input type='button' style='width:70px' data-colorpicker> </body> </html> 設置デモ スマホ、PC両対応(IE除く)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ページトップリンク+スムーススクロール【作成中】

概要 下記3つの方法で実現します jQuery CSS JavaScript jQueryでの実現方法 参考書籍 動くWebデザイン アイディア帳 実現方法 ページトップリンク aタグでトップ(#)にリンクする -----省略----- <p id="page-top"><a href="#">Page Top</a></p> ページトップリンクをクリックするとjQuery animate scrollTop:0 へ移動させる $('#page-top').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); 結果 思った通りに動作しました return falseの意味は下記で確認しました 【JavaScript】return falseの意味について総まとめ。コード付で解説 CSSでの実現方法 参考 CSSのみ!簡単にスムーズスクロールを導入する htmlはjQueryの場合と同じです html { scroll-behavior: smooth; } 結果 思った通りに動作しました 注意点 Safari、Opera、IEには対応していません JavaScriptでの実現方法 参考 【脱jQuery】Javascriptのみでスムーススクロールを実装【コピペ】 htmlの内容はjQueryに加えてid要素を付与 -----省略----- <p id="page-top"><a id = "page_top_link" href="#">Page Top</a></p> JSでaタグのクリックでスムースクロールする ※思っていたより簡単 const smoothScrollTrigger = document.getElementById("page_top_link"); smoothScrollTrigger.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ページトップリンク+スムーススクロール

概要 下記4つの方法で実現します jQuery CSS JavaScript JavaScript+Vue.js jQueryでの実現方法 参考書籍 動くWebデザイン アイディア帳 実現方法 ページトップリンク aタグでトップ(#)にリンクする -----省略----- <p id="page-top"><a href="#">Page Top</a></p> ページトップリンクをクリックするとjQuery animate scrollTop:0 へ移動させる $('#page-top').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); 結果 思った通りに動作しました return falseの意味は下記で確認しました 【JavaScript】return falseの意味について総まとめ。コード付で解説 CSSでの実現方法 参考 CSSのみ!簡単にスムーズスクロールを導入する htmlはjQueryの場合と同じです html { scroll-behavior: smooth; } 結果 思った通りに動作しました 注意点 Safari、Opera、IEには対応していません JavaScriptでの実現方法 参考 【脱jQuery】Javascriptのみでスムーススクロールを実装【コピペ】 htmlの内容はjQueryに加えてid要素を付与 -----省略----- <p id="page-top"><a id = "page_top_link" href="#">Page Top</a></p> JSでaタグのクリックでスムースクロールする ※思っていたより簡単 const smoothScrollTrigger = document.getElementById("page_top_link"); smoothScrollTrigger.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); }); JavaScript+Vue.jsでの実現方法 htmlはクリックイベント追加 <footer id="footer"> <p id="page-top"><a v-on:click = "page_top_click" href="#">Page Top</a></p> -----省略----- </footer> var footer = new Vue({ el:"#footer", methods:{ page_top_click:function(e){ e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); } } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【備忘録】カスタムデータ属性(data-*)について

初めに cssやjavascriptでカスタムデータ属性が使われている。カスタムデータ属性とは何か、そして使い方について備忘録として残します。 ※内容に間違いなどがある場合はご指摘をよろしくお願いします。 カスタムデータ属性とは htmlのタグに固有の値を付与してcssやjavascriptでその値を取得して利用できるようにしたもの。 書き方 htmlでカスタムデータ属性を付与したいタグにdata-*という形式で指定。divタグだと以下のようになる。 <div data-属性名=値></div> 属性名と値は任意のものであり、自由に指定できる。 例として以下のようにdata-hogeというカスタムデータ属性を指定したとします。 <section class="custom_data_section"> <div class="test" data-hoge="text">Hello World</div> </section> cssで利用する場合 まずhtmlのdivタグにdata-hogeというカスタムデータ属性を付与します。 ①セレクターとして使う [data-属性名]という書き方でセレクターとして使います。 [data-hoge] { color: red; } /* .testを付けても結果は同じ */ .test[data-hoge] { color: red; } ②擬似要素として使う 擬似要素afterやbeforeの中身としてcontentプロパティにattr()関数を使ってカスタムデータ属性の値を渡します。 attr()関数について:https://developer.mozilla.org/ja/docs/Web/CSS/attr() .test::before { content: attr(data-hoge); font-size: 50px; color: purple; } data-hogeの値"text"が画面に表示されました。 javascriptで利用する場合 ①カスタムデータ属性の設定 querySelectorで.testを取得し、「test.dataset.属性名 = 値」で新しいカスタムデータ属性を設定できます。 const test = document.querySelector(".test"); test.dataset.huga = 20; コンソールで確認すると「data-huga」というカスタムダータ属性ができました。また、値として"20"と表示されます。 ②カスタムデータ属性の値を取得 「test.dataset.属性名」で簡単に取得できます。 const test = document.querySelector(".test"); const hoge = test.dataset.hoge; console.log(hoge); ③カスタムデータ属性の値を変更 「test.dataset.属性名 = 変更する値」で値の変更ができます。 const test = document.querySelector(".test"); test.dataset.hoge = "hello"; console.log(test); コンソールで確認するとtextからhelloに変わっていることがわかります。 参考サイト https://www.webprofessional.jp/how-why-use-html5-custom-data-attributes/ https://qiita.com/k152744/items/c96fcf0141798bf48dd7 https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/data-* https://techacademy.jp/magazine/24740 https://whiskers.nukos.kitchen/2016/11/19/data-attr-style.html https://twotone.me/web/2658/ https://apex-traders.net/html-custom-data/ https://developer.mozilla.org/ja/docs/Web/CSS/attr()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Promise・async/await

非同期処理のデメリット 非同期通信は実行完了を待たず次の処理を行ってしまう為、制御が難しいというデメリットがあります。 例えばapiを叩きレスポンスに対して特定の処理をしたいとします。 ネットワーク通信はとても重たい処理なので、実行結果を待たず次の処理に進んでしまいエラーになってしまいます。 Promiseやasync/awaitを使えば実行完了を制御する事ができます。 Promise まだ確定してない値の状態を表すオブジェクトのことで、非同期処理の操作が完了したときに結果を返すものです。 このPromiseオブジェクトでは、値が確定した時に行って欲しい処理を登録する事ができます。 const promiseFunc = () => { return new Promise((resolve, reject) => { someAsynchronousFunc(() => { // 何かしらの非同期処理 }).then(() => { // 非同期処理が成功した場合 return resolve('成功!') }).catch(() => { // 非同期処理が失敗した場合 return reject('失敗!') }) }) } resolveとrejectを引数で渡します。 このresolveかrejectが実行されるまで次の処理に進まなくなります。 その為順番に制御され同期処理と同じような動きになります。 コールバック地獄 可読性という意味でもメリットがあります。 連続で非同期処理を行いたい場合、コールバック関数を使うとネストが深くなる為可読性が落ちます。 setTimeout(() => { console.log(3); setTimeout(() => { console.log(2); setTimeout(() => { console.log(1); }, 1000); }, 1000); }, 1000); Promise化 const sleep = ms => new Promise(resolve => setTimeout(resolve,ms)); sleep(1000) .then(() => console.log(3)) .then(() => sleep(1000)) .then(() => console.log(2)) .then(() => sleep(1000)) .then(() => console.log(1)) thenでつなぐ事で可読性が上がります。これをthenチェーンと言います。 連続してthenで繋げられるのはthenメソッドの返り値がPromiseオブジェクトの為です。 async/await promiseをよりシンプル且つ直感的に書けるようにしたものです。 const asyncAwaitFunc = async () => { const hoge = await someAsynchronousFunc(() => { // 何かしらの非同期処理 }).then(() => { // 非同期処理が成功した場合 return '成功!' }).catch(() => { // 非同期処理が失敗した場合 return '失敗!' }) } asyncは関数前に、awaitは関数実行時につけます。 awaitを使うには必ずasync付きの関数内で行う必要があります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

タグ関数についてまとめてみた

タグ関数とは HTMLのテンプレートを引数に渡す目的で実装された関数のことです。 以下のコードでは、tagFunction がタグ関数に該当します。 const view = tagFunction` <div>${hoge}と${fuga}</div> `; function tagFunction(strings, ...values) { console.log(strings); console.log(...values); } タグ関数について調べた背景 JSPrimerでタグ関数を学習していた際、 上記のようなタグ関数の引数をコンソールに出力した際に、配列が出力された 第一引数(strings) の出力結果 0: "↵ <div> 1: "と" 2: "</div>↵" 第二引数(...values) の出力結果 hoge fuga この時  Q. どういうルールで、第一引数に入る配列が作成されるのか  Q. タグ関数を呼び出す際、引数にはHTMLテンプレート1つしか渡していないのに、第二引数に値が入るのはなぜか という疑問を持ったので、調べてみました。 タグ関数の呼び出し方 タグ関数を呼び出す時は、通常の関数と違い 関数`テンプレート`; という書き方をします。 一般的な関数呼び出しは 関数(引数); と書きます。 使い方 実際のコードだと以下のように使います。 escapeHTML がタグ関数に該当します。 const view = escapeHTML` <h4>${userInfo.name} (@${userInfo.login})</h4> <img src="${userInfo.avatar_url}" alt="${userInfo.login}" height="100"> <dl> <dt>Location</dt> <dd>${userInfo.location}</dd> <dt>Repositories</dt> <dd>${userInfo.public_repos}</dd> </dl> `; function escapeHTML(strings, ...values) { return strings.reduce((result, str, i) => { const value = values[i - 1]; if (typeof value === "string") { return result + escapeSpecialChars(value) + str; } else { return result + String(value) + str; } }); } userInfoの定義 githubのユーザ情報が格納されており、各プロパティの詳細は以下の通りです。 userInfo.name:ユーザ名 userInfo.login:ログイン名 userInfo.avatar_url:プロフィール画像 userInfo.location:住んでいる国名 userInfo.public_repos:パブリックリポジトリの数 それでは、背景で書いた疑問の解答を書いていきます。 疑問1つ目 Q. どういうルールで、HTMLのテンプレートが区切られて、配列へ格納されるのか A. テンプレートリテラル内の${value}が区切りとなり、それぞれが一要素として配列へ格納されます 配列をコンソールに出力すると、以下が表示されました。 (7) ["↵ <h4>", " (@", ")</h4>↵ <img src="", "" alt="", "" height="100">↵ <dl>↵ <dt>Location</dt>↵ <dd>", "</dd>↵ <dt>Repositories</dt>↵ <dd>", "</dd>↵ </dl>↵ ", raw: Array(7)] 0: "↵ <h4>" 1: " (@" 2: ")</h4>↵ <img src="" 3: "" alt="" 4: "" height="100">↵ <dl>↵ <dt>Location</dt>↵ <dd>" 5: "</dd>↵ <dt>Repositories</dt>↵ <dd>" 6: "</dd>↵ </dl>↵ " 疑問2つ目 Q. タグ関数を呼び出す際、引数にはHTMLテンプレート1つしか渡していないのに、第二引数に値が入るのはなぜか A. valuesには、テンプレートリテラル内の${value}の実際の値が格納された配列が入るため 第二引数(...values) もコンソールに出力すると、以下が表示されました。 null "bita-kodai" "プロフィール画像のURL" "bita-kodai" null 17 終わりに 最後までご覧頂きありがとうございます。 何か補足や疑問点、フィードバック等々ございましたら、コメント欄への記載をお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

event.targetとevent.currentTargetの違い

背景 ネストしたHTML要素の親要素に対してイベントハンドラのコールバック関数内の処理を付与した状態で、その子要素をクリックした。 すると、親要素に対して付与したはずのイベントハンドラのコールバック関数内の処理が、子要素に対してのみ実行された。  >>>挙動の参考<<< どうして親要素に付与したイベント処理が、子要素だけに実行されたか? という疑問が生じたので、調べてみた。 どうして親要素に付与したイベントハンドラのコールバック関数内で処理を行う対象が、子要素になったのか? これには2つの理由があり、分解して説明すると、、、 Q. 親要素に付与したイベントハンドラのコールバック関数内の処理が実行される理由  → キャプチャリングとバブリングの影響により、子要素をクリックした場合でも、親要素に付与されたイベントハンドラのコールバック関数内の処理が実行された ※ 本記事では、キャプチャリングとバブリングについては触れません  >>>キャプチャリングとバブリングの参考サイト<<< Q. 子要素が、親要素に付与したイベントハンドラのコールバック関数内で処理を行う対象となった理由  → 処理の実行先をevent.targetとしていた場合、event.targetはイベントを発生させた要素指すため、子要素でイベントが発生すると、event.targetは子要素を指す。 結局どう解決したのか event.currentTargetを使うことで解決 event.targetとevent.currentTargetの違い event.target:イベントを発生させた要素を指す event.currentTarget:イベントハンドラが登録されている要素を指す event.targetを使った場合の挙動例 HTMLタグの構造が html <div class="parent"> 親要素 <div>子要素</div> </div> となっているとする。 親要素に const parentElm = document.querySelector('.parent'); parentElm.addEventListener('click', event => { event.target.setAttribute('style', 'background-color: blue;'); }) をセットする。 この状態で子要素をクリックすると、子要素のbackground-colorだけがblueとなる。 event.targetにはイベントを発生させた要素(= 子要素)が入るため。 event.currentTargetを使った場合の挙動例 親要素に jsx const parentElm = document.querySelector('.parent'); parentElm.addEventListener('click', event => { event.currentTarget.setAtrribute('style', 'background-color: blue;'); }) をセットする。 この状態で子要素をクリックしても 常に親要素のbackground-colorがblueとなる。 currentTargetには、イベントハンドラを登録した要素(= 親要素)が入る。 終わり ありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Adobe JSX を作って知ったこと

Adobe JSX とは JavaScript で Adobe 製品を操る仕組みのこと。 今回「Photoshop のレイヤーカラーラベルを変更できるスクリプト」を作ってみようと思い立ったのだが、あまり情報がない。 もとい、有用な情報があまりない。 検索すると色々出てくるんだけど「これをコピペしよう」とかが多く実際に利用できそうなスクリプトがないし資料もない。 なので、他の記事ではあまり触れられておらず苦労した部分だけ書いた。 ※Adobe JSX といいつつ Photoshop についてのみ記載… あまり他の記事に書かれていないこと 普通の JavaScript でいい 拡張子を jsx にするだけ。 上から順に実行される。 Script フォルダに入れておけば自動的に [ファイル]→[スクリプト] に表示される Script フォルダはデフォルトであれば、ここ。 C:\Program Files\Adobe\Adobe Photoshop 2021\Presets\Scripts\ Photoshop の JSX は2種類の操作方法がある 一般的な DOM オブジェクトによる操作 Action をスクリプト化したもの 1番の DOM オブジェクトによる操作ができる場合は問題無い。 いつも通り DOM オブジェクトの操作で済む。 例えば、アクティブレイヤーの表示・非表示を切り替える場合は // app はビルトインのグローバル変数でここから DOM をたどれる app.activeDocument.activeLayer.visible = false; こんな感じ。 問題は、DOM として提供されていないプロパティを変更する場合。 ActionReference オブジェクト ActionDescriptor オブジェクト executeAction / executeActionGet 関数 を使って Action として処理する。 これがとにかく面倒くさい。 例えば、下記のコードは現在アクティブなレイヤーのカラーラベルを取得する処理。 // 現在の Color Label の取得 var ref = new ActionReference(); ref.putEnumerated( charIDToTypeID("Lyr "), // 4文字ID型式を Photoshop が理解する形に変換 Lyr = Layer charIDToTypeID("Ordn"), // 4文字ID型式を Photoshop が理解する形に変換 Ordn = Ordinal charIDToTypeID("Trgt") // 4文字ID型式を Photoshop が理解する形に変換 Trgt = TargetEnum ); var desc = executeActionGet(ref); // Action を実行して ActionDescripter を取得 var colorID = desc.getEnumerationValue(stringIDToTypeID('color')); // color プロパティを取得 var curColor = typeIDToStringID(colorID); // 人間が解る形に変換 ここで出てくる Lyr や Ordn といった謎の4文字についてはオフィシャルにも全ては載っていない。 全てが載っているページは↓の WaybackMachine にある Photoshop Constants Rosetta Stone また、そもそも Action を使った処理を人間の手で書いている人はあまりいない。 というのも、Adobe が提供している ScriptingListener というプラグインを使うと Action を JavaScript として保存できるようになるため。 必要な処理を Action として記録して Script 化して使っている人が多いのが実情。 JSX で○○するにはこうするんだよ~的なスクリプトが沢山公開されているが、変数名が foo1, foo2 みたいな連番ぽい数字が付いているものは ScriptingListener を使って作ったもの。 全然参考にならない。 そんな訳なので実は ActionReference と ActionDescriptor についてはあまり良く理解できていない。 恐らく ActionReference 操作対象 ActionDescriptor 操作に必要なプロパティなどを保存する Key-Value ストレージ という感じかなあと思っている。 JavaScriptResource このスクリプトの各種属性を記述しておく所。 ちなみに、Photoshop の起動時1回だけ読み込む。 変更した場合は Photoshop を再起動しないといけない。 詳しくは JavaScript Reference を。 今回指定した XML は↓こんな感じ。 /* <javascriptresource> <name>色ラベルの変更 / Toggle Color Label</name> <about> Toggle Color Label Version 1.00 Copyright (c) 2021 @pik. </about> </javascriptresource> */ name, about タグだけ説明すると name メニューに表示されるテキストを指定するところ。 about [ヘルプ]→[プラグインについて]で表示されるもの。 上記のコードのように途中で改行を入れればそのまま改行されて表示される。 他にも色々設定できて、メニューの Enable/Disable を状態に応じて自動的に変更できたりするらしいが、方法は解らず。 Target 宣言 ↓こんな感じでターゲットを指定しておける。 #target photoshop jsx ファイルをダブルクリックして起動するときとかに役立つ? デバッグレベル デバッグレベルは 0: disable 1: break on error 2: break at beginning の3つあるが、どれもエラーになった時適切に行番号を表示してくれるので 1, 2 を使う事はあまり無さそう。 $.level = 0; // デバッグレベルの設定 ローカライズ 一般的な JavaScript のローカライズ機構しか使えない $.localize = true; // 自動的にローカライズ文字列を使う設定 const msg = {en:"test", ja:"テスト"}; // ロケールとテキストを持つオブジェクト alert(msg); // ロケールに応じて自動的にテキストが選択される 一番悩んだのはここ。 Adobe が最初から提供している Script はメニューに各国の言葉が表示されている。 JavaScriptResource でメニューに表示されるテキストを指定できるが、ここを動的に変更しないといけない。 だが JavaScriptResource は動的に変更できないようだ。 Adobe が最初から提供している Script については Adobe format for localized Strings という特別な型式(ZString)を使っているらしい…が、ZString は Internal use only とあって情報が全然無い。 詳しくは↓ Global localize function 結局仕方がないので 色ラベルの変更 / Toggle Color Label と日本語と英語を並記した。 作った物 呼び出す度にカラーラベルが切り替わるスクリプト。 ショートカットを指定して呼び出すと便利かもしれない。 …でも単純に右クリックメニューからやった方が速いんじゃないかなあ…(奥さんの要望で作ったものの、奥さんはペンタブのペンのボタンを「ブラシの設定」「Ctrl+Z」に割り当ててる奇特な人なので必要だった) ソース ソースは無名関数型式にしているけど、その必要は全くない。 単純に必要なオブジェクトが取れなかった時に処理をやめさせたかっただけ。 (インデントが深くならないように) 一応 Gist にも同じ物を。 https://gist.github.com/freeonterminate/666d4f47b83594d82c9915f5e0098815 // Toggle Color Label // // ABOUT // Change color label. // None → Red → Orange → Yellow → Green // → Blue → Violet → Gray → None // // LICENSE // Copyright (c) 2021 twitter:@pik // Released under the MIT license // http://opensource.org/licenses/mit-license.php // // HISTORY // 2021/05/06 1.00 Release. // /* <javascriptresource> <name>色ラベルの変更 / Toggle Color Label</name> <about> Toggle Color Label Version 1.00 Copyright (c) 2021 @pik. </about> </javascriptresource> */ #target photoshop $.level = 0; $.localize = true; const msgErrBackground = { en: "Color labels cannot be set for the background layer", ja: "背景レイヤーには色ラベルを設定できません" }; (function(){ try { var doc = app.activeDocument; if (doc.activeLayer.isBackgroundLayer) { alert(msgErrBackground); return; } } catch(e) { return; } const colors = [ "none", "red" , "orange", "yellowColor", "grain", "blue" , "violet", "gray", ]; try { // 現在のカラーラベルの取得 var ref = new ActionReference(); ref.putEnumerated( charIDToTypeID("Lyr "), // Layer charIDToTypeID("Ordn"), // Ordinal charIDToTypeID("Trgt") // TargetEnum ); var desc = executeActionGet(ref); var curColor = typeIDToStringID(desc.getEnumerationValue(stringIDToTypeID('color'))); // 設定するカラーラベルの取得 var index = 0; var len = colors.length; for (var i = 0; i < colors.length; i++) { if (curColor == colors[i]) { index = i + 1; break; } } if (index == len) index = 0; var newColor = colors[index]; // カラーラベルの設定 var descColor = new ActionDescriptor(); descColor.putEnumerated( charIDToTypeID('Clr '), // Color charIDToTypeID('Clr '), // Color stringIDToTypeID(newColor) ); var target = new ActionDescriptor(); target.putReference(charIDToTypeID('null'), ref); target.putObject( charIDToTypeID('T '), // To charIDToTypeID('Lyr '), // Layer descColor ); executeAction(charIDToTypeID('setd'), target, DialogModes.NO); } catch (e) { alert(e.message); } })(); 最後に Adobe JSX を完全に理解するのは難しそう。 特に charID とかリファレンスないの酷すぎる。 一番参考になったのは↓このページ 特に役に立ったのが grain という色についてのところ。 知らなければ green のタイポだと思うところだった。 ちなみに完全に理解すると↓こういう感じで商売ができるっぽい MightyPlugins.cc / MagicScripts http://bereza.cz/ps
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む