20210513のJavaScriptに関する記事は18件です。

【Rails6】新・JavaScriptによる「入力フォームの内容のリアルタイムチェック機能」の実装例

以前、【Rails6】JavaScriptによる「入力フォームの内容のリアルタイムチェック機能」の実装例という記事で、入力フォームのリアルタイムチェック機能の実装方法を紹介しましたが、この実装方法には以下の問題がありました。 エラーメッセージのタグをhiddenで隠しているので、フォームの中に不自然な空白がある 複数のタイプのエラーメッセージを表示しようとすると空白がさらに大きくなってしまう 今回はこれを改善し、しかもパワーアップしました。 前回と同様にjQueryのようなライブラリは使用せず、そのままのJavaScriptで実装したことが今回もポイントです。 実行環境 Rails 6.0.3.6 動作確認 今回のリアルタイムチェック機能の仕様は以下の通りです。 入力された値によって以下のエラーメッセージが表示される 半角数字以外の場合→「価格は半角数字で入力してください」 300〜9,999,999の範囲外の場合→「価格は300〜9,999,999の範囲で設定してください」 正しい値を入力するとメッセージが非表示になる Javascriptのコード メインとなるJavaScriptのコードは以下の通りです。 app/javascript/validation.js //validationイベントを定義 const validation = () => { //エラーメッセージを表示するための要素を取得して変数化 const priceErrorElement = document.getElementById("price-error"); //フォームの値が入る要素を取得して変数化 const itemPrice = document.getElementById("item-price"); //ここから半角数字での入力を促すイベント //半角数字でないものにマッチする正規表現を変数化 const pricePattern = /^\d+$/; //入力フォームでキーが離されたときにイベントが発生 itemPrice.addEventListener("keyup", e => { //idがprice-character-errorの要素(エラーメッセージ)を取得して変数化 const errorMessageCharacter = document.getElementById("price-character-error"); //入力された値が正規表現にマッチしている or 空白のとき if (pricePattern.test(itemPrice.value) || itemPrice.value == "") { //エラーメッセージが存在しているとき if (errorMessageCharacter != null) { //エラーメッセージを削除 errorMessageCharacter.remove(); } //入力された値が正規表現にマッチしていないとき } else { //エラーメッセージが存在していないとき if (errorMessageCharacter === null) { //エラーメッセージを挿入 priceErrorElement.insertAdjacentHTML('afterend', '<div id="price-character-error" class="price-error">価格は半角数字で入力してください</div>' ); } } }); //ここまで半角数字での入力を促すイベント //ここから300〜9,999,999の範囲での入力を促すイベント //最小値と最大値を変数化 const minimumPrice = 300; const maximumPrice = 9999999; //入力フォームでキーが離されたときにイベントが発生 itemPrice.addEventListener("keyup", e => { //idがprice-range-errorの要素(エラーメッセージ)を取得して変数化 const rangeErrorMessage = document.getElementById("price-range-error"); //入力された値が300より小さい or 9,999,999より大きいとき if (itemPrice.value < minimumPrice || itemPrice.value > maximumPrice ) { //エラーメッセージが存在していないとき if (rangeErrorMessage === null) { //エラーメッセージを挿入 priceErrorElement.insertAdjacentHTML('afterend', '<div id="price-range-error" class="price-error">価格は300〜9,999,999の範囲で設定してください</div>' ); } //入力された値が300以上 or 9,999,999以下のとき } else { //エラーメッセージの要素が存在しているとき if (rangeErrorMessage != null) { //エラーメッセージを削除 rangeErrorMessage.remove(); } } }); //ここまで300〜9,999,999の範囲での入力を促すイベント } //ページが読み込まれた(load)ときに、validationイベントを実行 window.addEventListener("load", validation) 上記validation.jsをapplication.jsで読み込むことを忘れないようにしましょう。 app/javascript/packs/application.js require("../validation") Viewのコード エラーメッセージを入れたい箇所に以下の要素を記述します。 new.html.erb <div id="price-error"></div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LINE bot を作ってみた2(postback編)

前回 で味を占めたので、今度は postback を使用したアンケートを作ってみた 環境 Google Spread Sheet Google Apps Script LINE Developers 経緯 LINEbot と GAS だとすぐに作って動作確認できるし、インフラ準備とか必要ないからラクで楽しいなぁ もうちょっと LINEbot の種類を見てみよう 手順(概要) LINE Developers でチャンネルの作成 GAS 構築 GAS 公開 LINE Developers に Webhook URL を登録 動作確認 手順(詳細) 1. LINE Developers でチャンネルの作成 https://developers.line.biz/console/channel/{id}/ で以下情報のチャンネルを作成する Channel type:Messaging API Provider:前回作成したやつ その他の項目は任意 当該チャンネルでトークンを発行する [MessagingAPI設定] > [チャネルアクセストークン] の「発行」を押下 2. GAS 構築 以下にソースを置きました https://github.com/soso555BoBs/linebot2_with_gas 今回は GAS ファイルだけ作成 その後、任意のスプレッドシートに結果を記載するようにした 前回のやり方だといちいちスプレッドシートを開かないと GAS がいじれなかったのが面倒くさかったため なお、スプレッドシート ID やデバッグ用 LINEID など公開したくない情報は全てスプレッドシートの Properties に入れるようにした 以下設定方法 GAS エディタ右上にある [以前のエディタを使用] を選択 「なして古いの使うん?」ていうアンケートフォームが出てくるがそっ閉じ [ファイル] > [プロジェクトのプロパティ] と選択 [スクリプトのプロパティ] タブに以下 7 行を追加する DEBUGID:デバッグ情報を送付するLINEID。ハッシュ値みたいなやつ。 PUSH_URL:LINEbot の PUSH URL REPLY_URL:LINEbot の REPLY URL SHEETID:アンケートの選択肢および結果を貯めるスプレッドシートのID SHEETNAME:スプレッドシートの中のシート名称 TEMP_FOLDER_ID:グラフ画像を作成するフォルダ。作成した画像は削除されるため、一時的な出力先。 TOKEN:LINEbot のトークン 3. GAS 公開 前回の ここ 参照のこと 4. LINE Developers に Webhook URL を登録 前回の ここ 参照のこと 5. 動作確認 動いた! 感想&注意点 前回から引き続き、デバッグ方法がわからなかったので、以下 3 通りの方法を駆使した GAS エディタのデバッグ機能 ターミナルから curl コマンドを叩く GAS を公開した URL へ、期待する POST パラメータを付与して curl を叩く すると、エラーの場合はエラー文言がレスポンスパラメータとしてもらえる デバッグしたい箇所に「DEBUGID 向けに LINE のトークを発出」するようにした ソースだとここ みたいな感じ 結局、Exception をキャッチしてスタックトレースを発出するようにした ここ 今回はなんだかんだ完了までに 2 日間くらいかかった デバッグ方法が確立できていないのが主たる原因 GAS の公開バージョンも 80 を上回った 何かのシミュレーションをして、その結果を画像配布するようなサービスに流用できそう ただし GAS だと複数人同時問い合わせに耐えうる保証はない し、そもそもやり方を調べていない 簡単に動かしてみる、がテーマなのでとりあえずそこは保留にした
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Next.js+framer-motionで画面遷移アニメーション

Next.js でReactのアニメーションライブラリであるframer-motionを使ったので、メモがてら記事にしたいと思います。 当方初投稿なので至らない点もあるかと思いますが、温かい目で見てもらえればと思います。 はじめに Framer MotionとはReactで使用できるアニメーションライブラリです。純粋にアニメーションを実装しようとするとかなり複雑なものになってしまいますが、専用のコンポーネントを使うことで手軽にプログラムに組み込めるようになっています。 react-router-dom と組み合わせたものが多いですが、Next.js との相性も良さそうです。 前提 Next.js v10.1.3 TypeScript framer-motion v4.1.16 framer-motionのインストール npm でインストールできます。 npm install framer-motion コード _App.tsx import React from "react"; import type { AppProps } from "next/app"; import { AnimatePresence } from "framer-motion"; function MyApp({ Component, pageProps, router }: AppProps) { return ( <div> <AnimatePresence exitBeforeEnter> <Component {...pageProps} key={router.route} /> </AnimatePresence> </div> ); } export default MyApp; Next.js はファイル名を元にルーティングされるのでルーターの細かい設定は要りません。(楽!) <Component> の中身がルーティングによって変わるので、その上を<AnimatePresence>で囲います。これはコンポーネントがアンマウントされた時のアニメーションを有効にするものです。 exitBeforeEnterのPropはコンポーネントがアンマウントされるのを待ってから次のコンポーネントに移るものです。これがないと遷移元のアンマウントと遷移先のマウントのアニメーションが同時に発火してしまいます。 子要素である<Component>には必ずkeyを追加してください。値はrouter.routeが一意な値を返してくれます。 (任意のページ).tsx import React from "react"; import { motion } from "framer-motion"; export default function Home() { return ( <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ ease: "easeOut", duration: 1 }} > <...> </motion.div> 各ページのコードでは<motion>コンポーネントでアニメーションを実装します。アニメーションの動きは以下のようになります。 マウント時: initial → animate アンマウント時: animate → exit transitionではアニメーションの種類(ease)や時間(duration)などを記述します。 framer-motionの機能についてはまだ把握しきれていない部分が多いので、省略します。かなり多彩なアニメーションを作ることができるみたいなので、是非こちらを参照してみてください。 まとめ Next.js(React)でアニメーションを実装する時にはとても有用だなと感じました。是非導入を検討してみてはいかがでしょうか。 拙いながらも、アウトプットが大事だと思い記事を書いてみました。まだまだ足りないところばかりですが、今後も記事を投稿してみようと思うのでよろしくお願いいたします! 参考 Framer Motion 【遊んでみた】framer-motion基本のき
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Next.js + TypeScript + Tailwind CSS プロジェクトの環境構築手順

Next.js + TypeScript + Tailwind CSS プロジェクトの環境構築手順をまとめました。 はじめに node と npm はインストールが済んでいる前提で、進めていきます。 動作環境 node -v v15.7.0 npm -v 7.4.3 また、この記事の内容はmacOS (Apple Silicon)で実行しています。 Windowsをご利用の方は適宜読み替えていただければと思います。 1.Next.jsのプロジェクトを作成 Next.jsのプロジェクトを作成(フォルダが作成されるので、作業用ディレクトリ直下で行う) npx create-next-app - What is your project named? とプロジェクト名を聞かれるので、任意のプロジェクト名を入力します。今回は next-sample とします。 すると入力した名前のフォルダが作成されます。 ローカルサーバーを起動します。 // 作成したプロジェクトへ移動 cd next-sample npm run dev ブラウザからhttp://localhost:3000にアクセスして、以下の画面が表示されればNext.jsの準備は完了です! 2.TypeScriptの導入 必要なパッケージをインストールします。 npm i -D typescript @types/react @types/node 元々、作成されているpages/以下のjsファイルをtsファイルに書き換えます。 mv pages/_app.js pages/_app.tsx mv pages/index.js pages/index.tsx tsconfig.jsonはnpm run devすると自動的に作られるので、用意する必要はありません。 再度、npm run devを実行して、Next.jsをインストールした際に確認した画面が表示されれば、TypeScriptの導入は完了です。 3.Tailwind CSSの導入 こちらの公式ページを参考にTailwind CSSをインストール npm i -D tailwindcss@latest postcss@latest autoprefixer@latest 次に設定ファイルの作成 npx tailwindcss init -p 実行すると、tailwind.config.js と postcss.config.js が生成されます。 tailwind.config.js の purgeの設定を行います。 tailwind.config.js module.exports = { - purge: [], // この行を削除 + purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'], // この行を追加 darkMode: false, // or 'media' or 'class' theme: { extend: {}, }, variants: { extend: {}, }, plugins: [], } styles/globals.cssの内容を書き換えます。 styles/globals.css @tailwind base; @tailwind components; @tailwind utilities; これでTailwind CSSの準備も完了です! あとは ./pages/index.tsxのclassNameに用意されているユーティリティクラス を設定して、適用されれば動作確認も完了です! pages/index.js <h1 className="text-red-400 text-5xl"> Welcome to <a href="https://nextjs.org">Next.js!</a> </h1> 参考文献 Install Tailwind CSS with Next.js Tailwind CSS Cheat Sheet
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Blocklyでスライダー入力を行う

Blocklyとは Googleの開発している、ブロックプログラミングを自由に自分で作れちゃうやつ 2021年のゴールデンウィークに発表があって、プラグインが色々でてきました! 公式のサンプル: https://google.github.io/blockly-samples/ ということで、このプラグインを使った(ギリギリ)最新の情報を記事にしていきます。 用語 リファレンスでトップにある単語をちょっと触った自分がまとめてみました(間違ってたらコメントお願いします汗) Blockly まぁ全体のこと Workspace ブロックを組む場所 Toolbox ブロックがある場所 Block ブロック自体 Workspaceに置かれているものには固有idがある 画像の場合は2つのBlockがWorkspaceに置かれている Field ブロック内の入力やテキストの情報 _ Generator ブロック配置からコードの生成 JS以外にもPythonなども Blocklyを使ってJavaScript実行までの最小構成 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/blockly/blockly.min.js"></script> <title>Blockly test</title> </head> <body> <!-- Toolboxのブロック --> <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none"> <block type="math_number"> <field name="NUM">123</field> </block> <block type="text"></block> <block type="text_print"></block> </xml> <!-- Workspace --> <div id="blocklyDiv" style="height: 480px; width: 600px;"></div> <!-- 実行ボタン --> <button onclick="run()">実行</button> <script> const demoWorkspace = Blockly.inject('blocklyDiv', { media: 'https://unpkg.com/blockly/media/', toolbox: document.getElementById('toolbox') }); function run() { const code = Blockly.JavaScript.workspaceToCode(demoWorkspace); console.log(code); try { eval(code); } catch (e) { alert(e); } } </script> </body> </html> カスタムブロックの最小構成 ifやprintなど揃ってますが、自分でもオリジナルのブロックが作れます! 作り方は以下のサイトがけっこう詳しく書いてます ブロック情報はだいたい別ファイルにするのが普通ですが、あえて1つのファイルで書いてみると… <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/blockly/blockly.min.js"></script> <script> Blockly.Blocks['custom_test'] = { init: function () { this.appendDummyInput() .appendField("テストの値は") .appendField(new Blockly.FieldNumber(0), "num") .appendField("です"); this.setOutput(true, null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } }; Blockly.JavaScript['custom_test'] = function (block) { var number_num = block.getFieldValue('num'); var code = number_num; return [code, Blockly.JavaScript.ORDER_NONE]; }; </script> <title>Blockly test</title> </head> <body> <!-- Toolboxのブロック --> <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none"> <block type="math_number"> <field name="NUM">123</field> </block> <block type="text"></block> <block type="text_print"></block> <block type="custom_test"></block> </xml> <!-- Workspace --> <div id="blocklyDiv" style="height: 480px; width: 600px;"></div> <!-- 実行ボタン --> <button onclick="run()">実行</button> <script> const demoWorkspace = Blockly.inject('blocklyDiv', { media: 'https://unpkg.com/blockly/media/', toolbox: document.getElementById('toolbox') }); function run() { const code = Blockly.JavaScript.workspaceToCode(demoWorkspace); console.log(code); try { eval(code); } catch (e) { alert(e); } } </script> </body> </html> さっそくPluginを使ってスライダー入力にしてみる ここからは、最新情報ですね。 プラグインのところへ行き、使いたいものを選択 例えば、@blockly/field-slider それぞれの説明にはビルドするようのコードしか説明に書かれてないです ですがいったん、npmでインストールしましょう(yarnでも可) npm i @blockly/field-slider そうすると、node_modulesの中にdistフォルダがあって、 これをscriptで読み込んであげればオッケーです <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://unpkg.com/blockly/blockly.min.js"></script> <script src="node_modules/@blockly/field-slider/dist/index.js"></script> <script> Blockly.Blocks['custom_test'] = { init: function () { this.appendDummyInput() .appendField("テストの値は") .appendField(new FieldSlider(1, 0, 10, 0.1), "num") .appendField("です"); this.setOutput(true, null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } }; Blockly.JavaScript['custom_test'] = function (block) { var number_num = block.getFieldValue('num'); var code = number_num; return [code, Blockly.JavaScript.ORDER_NONE]; }; </script> <title>Blockly test</title> </head> <body> <!-- Toolboxのブロック --> <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none"> <block type="math_number"> <field name="NUM">123</field> </block> <block type="text"></block> <block type="text_print"></block> <block type="custom_test"></block> </xml> <!-- Workspace --> <div id="blocklyDiv" style="height: 480px; width: 600px;"></div> <!-- 実行ボタン --> <button onclick="run()">実行</button> <script> const demoWorkspace = Blockly.inject('blocklyDiv', { media: 'https://unpkg.com/blockly/media/', toolbox: document.getElementById('toolbox') }); function run() { const code = Blockly.JavaScript.workspaceToCode(demoWorkspace); console.log(code); try { eval(code); } catch (e) { alert(e); } } </script> </body> </html> カスタムブロックの部分しか変えてないです。 まとめと所感 公式にも書いといてくれって感じでつまづきました… distはたしかにコミットはしないだろうけど、cdnとかにあったら便利だしこれからしてくれるだろうと思ってます… でもわかると幅が増えてぜひほかのも使ってみたくなりました!(日付入力とか絶対便利) 最小構成のコードは自分のメモとしてもいいですね〜
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

メンタル疾患症状管理、服薬管理Webシステム(書き込み結果、ファイル出力編)

メンタル疾患病状管理、服薬管理Webシステム(書き込み結果、ファイル出力編)のソースコードを公開いたします。 ファイル書き込み(result.php)のソースコードです。 <!-- result.php --> <!-- メンタル疾患、服薬管理の表示プログラム --> <!-- メンタル疾患、服薬管理システム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <?php $message = 'OK'; $year = htmlspecialchars($_REQUEST['year']); $month = htmlspecialchars($_REQUEST['month']); $day = htmlspecialchars($_REQUEST['day']); $sleep = htmlspecialchars($_REQUEST['sleep']); $mental = htmlspecialchars($_REQUEST['mental']); $morning = htmlspecialchars($_REQUEST['morning']); $evening = htmlspecialchars($_REQUEST['evening']); $night = htmlspecialchars($_REQUEST['night']); $iraira = htmlspecialchars($_REQUEST['iraira']); $head_pain = htmlspecialchars($_REQUEST['head_pain']); $offence = htmlspecialchars($_REQUEST['offence']); $die = htmlspecialchars($_REQUEST['die']); $OD = htmlspecialchars($_REQUEST['OD']); $nothing = htmlspecialchars($_REQUEST['nothing']); $panik = htmlspecialchars($_REQUEST['panic']); $kanashibari = htmlspecialchars($_REQUEST['kanashibari']); $content = htmlspecialchars($_REQUEST['content']); $line = $year . $month . $day. "\n". "睡眠度:" . $sleep . "\n" . "気分の落ち込み度" . $mental . "\n" . "投薬管理: " . $morning . " " . $evening. " " . $night ."\n" . "あてはまる主な症状: " .$iraira . " " . $head_pain . " ". $offence . " " .$die . " " . $OD . " " .$nothing . " " .$panik . " " .$kanashibari. "\n" . "症状の詳細:" . $content . "\n" . PHP_EOL; file_put_contents(__DIR__ . '/articles.txt', $line, FILE_APPEND | LOCK_EX); require_once 'views/result.tpl.php'; 書き込み結果を表示するソースコードです。(result.tpl.php) <!-- result.tpl.php --> <!-- 結果表示ののテンプレートプログラム --> <!-- メンタル疾患、服薬管理システム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <!DOCTYPE html> <html lang='ja'> <?php include('header.inc.php'); ?> <body> <h1>書き込みました</h1> <p><?= $message ?></p> <p> <?php if(isset($year)) { echo $year . ', '; } if(isset($month)) { echo $month . ', '; } if(isset($day)) { echo $day . ', '; } if(isset($sleep)) { echo $sleep . ', '; } if(isset($mental)) { echo $mental; } if(isset($morning)) { echo $morning; } if(isset($evening)) { echo $evening; } if(isset($night)) { echo $night; } if(isset($iraira)) { echo $iraira; } if(isset($head_pain)) { echo $head_pain; } if(isset($offence)) { echo $head_pain; } if(isset($die)) { echo $die; } if(isset($OD)) { echo $die; } if(isset($nothing)) { echo $nothing; } if(isset($panic)) { echo $nothing; } if(isset($kanashibari)) { echo $kanashibari; } if(isset($content)) { echo $content; } ?> </p> <form action='mental.php' method='get'> <button type='submit' id="submit">戻る</button> </form> <?php include('footer.inc.php'); ?> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js】コンポーネントはパスカルケースで書くのがオススメ

はじめに 仕事で使う事になったので1からVue.jsについて学んだ。 ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 コンポーネントはパスカルケースで書くのがオススメ コンポーネント(single file component)の命名方法は以下の2つが選択肢にある。 # 具体例 ケバブケース hello-world パスカルケース HelloWorld が、命名時はパスカルケースを用いるのがオススメでその理由は以下。  パスカルケースはJavaScriptでよく使われるため、エディターで開発する際に自動補完されやすい  HTML要素と見分けがつきやすい(HTMLの要素・タグはケバブケースで書くため) 以下の画像のように、LikeNumberは緑色だが、like-headerは青色でHTMLの要素(divタグ)と同じで見分けにくい1  Vue.js以外のWebコンポーネントを使う際に見分けがつきやすい 余談 DOMテンプレート2の場合は、ケバブケースで記載しなければならない。 理由は、 ブラウザがDOMを描画する際には、htmlファイル→JavaScriptsファイルの順番で読み込む ブラウザがhtmlファイルを読み込む際には大文字小文字は区別されない という2つの事があり、DOMテンプレートでパスカルケースを使うと全て小文字と認識され3意図しない動きになるため。 Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4 LikeNumberはGlobal登録したコンポーネント。like-headerはLocal登録したコンポーネントで、LikeHeaderをケバブケースで書いたもの。※Vue.jsではコンポーネントをパスカルケースで定義しtemplateではケバブケースで記述するという事ができる。※また、LikeHeader": LikeHeaderの部分は"like-header": LikeHeaderとも書ける。 ↩ HTML上(.htmlファイル)に定義するコンポーネント ↩ HelloWorld → helloworldと見なされる ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

メンタル疾患症状管理、服薬管理Webシステム(画面入力編)

メンタル疾患症状管理、服薬管理Webシステム(画面入力編)のソースコードを公開いたします。 メインとなるmental.phpのソースコードです。 <!-- mental.php --> <!-- ボディー部分のプログラム --> <!-- メンタル疾患、服薬管理システム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <?php $message = 'メンタル疾患、投薬管理システム'; $lines = file(__DIR__ . '/articles.txt', FILE_IGNORE_NEW_LINES); require_once 'views/mental.tpl.php'; ヘッダー部分の部分のテンプレートソースコードです。 <!-- header.inc.php --> <!-- ヘッダー部分のテンプレートプログラム --> <!-- メンタル疾患、投薬管理システム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <head> <meta charset='utf-8'> <title>メンタルチェックシステム</title> <style> body { background-color:bisque; padding: 10px; } p.header { font-size:20px; color:crimson; } h1 { font-size: 40px; color:blueviolet; } h2 { font-size: 20px; color:blue; } #submit { background-color:darkgreen; border: 1px solid aqua; padding 15px 90px; border-radius: 10px; font-size:15px; color: #fff; } #submit:hover { background-color:darkblue; } a{ display:inline-block; padding:10px 20px 10px 20px; color:white; background-color:green; font-size:18px; font-weight: bold; border:solid 3px pink; border-radius:8px; } a:hover { background-color:darkcyan; } .nogizaka{ font-size:8px; color:red; } </style> </head> ボディー部分のテンプレートソースコードです <!-- mental_tpl.php --> <!-- ボディー部分のテンプレートプログラム --> <!-- メンタルチェックシステム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <!DOCTYPE html> <html lang='ja'> <?php include('header.inc.php'); ?> <script type="text/javascript"> <!-- function check(){ //変数の定義 const content = document.getElementById('content'); const submit = document.getElementById('submit'); if(content.value.replace(/\s+/, '').length === 0 ){ window.alert('詳細が入力されていません。'); return false; } else { if(window.confirm('送信してよろしいですか?')){ // 確認ダイアログを表示 return true; } else{ // 「キャンセル」時の処理 window.alert('キャンセルされました'); // 警告ダイアログを表示 return false; // 送信を中止 } } } // --> </script> <body> <h1>メンタル疾患、投薬管理</h1> <p class="header"><?= $message ?></p> <form action='result.php' method='post' onSubmit="return check()"> <dl> <label for='year'>年</label> <select name="year"> <option value="2021年">2021年</option> <option value="2022年">2022年</option> <option value="2023年">2023年</option> <option value="2024年">2024年</option> <option value="2025年">2025年</option> </select> <p></p> <label for='month'>月</label> <select name="month"> <option value="1月">1月</option> <option value="2月">2月</option> <option value="3月">3月</option> <option value="4月">4月</option> <option value="5月">5月</option> <option value="6月">6月</option> <option value="7月">7月</option> <option value="8月">8月</option> <option value="9月">9月</option> <option value="10月">10月</option> <option value="11月">11月</option> <option value="12月">12月</option> </select> <p></p> <label for='day'>日</label> <select name="day"> <option value="1日">1日</option> <option value="2日">2日</option> <option value="3日">3日</option> <option value="4日">4日</option> <option value="5日">5日</option> <option value="6日">6日</option> <option value="7日">7日</option> <option value="8日">8日</option> <option value="9日">9日</option> <option value="10日">10日</option> <option value="11日">11日</option> <option value="12日">12日</option> <option value="13日">13日</option> <option value="14日">14日</option> <option value="15日">15日</option> <option value="16日">16日</option> <option value="17日">17日</option> <option value="18日">18日</option> <option value="19日">19日</option> <option value="20日">20日</option> <option value="21日">21日</option> <option value="22日">22日</option> <option value="23日">23日</option> <option value="24日">24日</option> <option value="25日">25日</option> <option value="26日">26日</option> <option value="27日">27日</option> <option value="28日">28日</option> <option value="29日">29日</option> <option value="30日">30日</option> <option value="31日">31日</option> </select> <p></p> <dd>睡眠度を選んでください。 <select name="sleep"> <option value="よく眠れた">よく眠れた</option> <option value="眠れた">眠れた</option> <option value="普通">普通</option> <option value="あまり眠れなかった">あまり眠れなかった</option> <option value="全く眠れなかった">全く眠れなかった</option> </select></dd> <p></p> <dd>気分の落ち込み度 <select name="mental"> <option value="大きい"> 大きい <option value="やや大きい"> やや大きい <option value="普通"> 普通 <option value="やや小さい"> やや小さい <option value="小さい"> 小さい </select> </dd> <p></p> <dd>服薬管理 <input type="checkbox" name="morning" id="morning" value="朝食後">朝食後 <input type="checkbox" name="evening" id="evening" value="夕食後">夕方後 <input type="checkbox" name="night" id="night" value="寝る前">寝る前 </dd> <p></p> <dd>あてはまる主な症状をチェックしてください <br> <input type="checkbox" name="iraira" id ="iraira" value="イライラしている">イライラしている <input type="checkbox" name="head_pain" id="head_pain" value="頭痛がする">頭痛がする <input type="checkbox" name="offence" id="offence" value="攻撃的">攻撃的 <input type="checkbox" name="die" id="die" value="自殺願望">自殺願望 <input type="checkbox" name="OD" id="OD" value="大量に薬を飲みたい">OD <input type="checkbox" name="nothing" id="nothing" value="何もする気がない">何もする気がない <input type="checkbox" name="panik" id="panic" value="パニック状態">パニック状態 <input type="checkbox" name="kanashibari" id="kanashibari" value="金縛りにあった">金縛りにあった <br> </dd> <p></p> <dd>今日の様子を詳しく書いてください</dd> <dd><textarea name="content" id="content" rows="5" cols="100" ></textarea></dd> <p></p> </dl> <input type="submit" value="button" id="submit" onMouseOver="changeColor()" onMouseOut="revertColor()"> <script> function changeColor(){ document.getElementById('submit').style.backgroundColor = 'yellow'; } function revertColor(){ document.getElementById('submit').style.backgroundColor = null; } </script> <h2>投稿一覧</h2> <?php foreach ($lines as $line) { ?> <p><?= $line ?></p> <?php } ?> <?php include('footer.inc.php'); ?> <br> <a href="../index.html" id="menu">メニュー画面に戻る</a> フッターのソースコードです。 <!-- footer.tpl.php --> <!-- フッター部分のテンプレートプログラム --> <!-- メンタル疾患、服薬管理システム --> <!-- 新規作成 2021/5/12 --> <!-- 作成者:乃木坂好きのITエンジニア --> <hr> <footer class="nogizaka">by 乃木坂好きのITエンジニア</footer>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【jQueryメモ】ページ内スクロール

【ポイント】 ・ヘッダーが固定の場合はヘッダーの高さ分topから引く script.js //---------------- //ページ内スクロール //---------------- jQuery('a[href^="#"]').on('click', function () { var header = jQuery('.header').innerHeight(); var id = jQuery(this).attr('href'); var position = 0 if (id != '#') { position = jQuery(id).offset().top - header;//ヘッダー分の高さを引く } jQuery('html,body').animate({ scrollTop:position }, 300);//0,3秒かけて実行 }); //---------------------------- //トップに戻るボタンのスクロール表示 //----------------------------- jQuery(window).on('scroll', function () { if (150 < jQuery(this).scrollTop()) { jQuery('.to-top').addClass('is-show');//150px以上動かしたら表示 } else { jQuery('.to-top').removeClass('is-show');//それ以外は非表示 } });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ほぼ初心者が作ったキャラ名、アイテム名、今日の一言を表示するプログラム

はじめに 初心者が仕事に行く元気を出すために作ったものです。 ホラーゲーム「SIREN」シリーズのキャラ名、アイテム名、今日のひとことを表示するだけのプログラムです。 各シリーズのどれかに限定するか、全シリーズを対象にするか選ぶとボタンの文字が変わります。 とりあえずこんなの作りたーいみたいな雑な発想から、あの機能欲しいこんなのつけたいでごちゃごちゃ機能を足していったものです。 変遷まとめみたいなやつ 初めに作った機能 ・キャラ名、アイテム名、セリフを出す ・シリーズを限定できる(無印だけ出す、全シリーズ出すなどが選べる) 後々付け加えた機能 ・シリーズを限定するとボタンの文字が変わる 無印/全シリーズ、2のみ、NTのみで別々 ・全シリーズにしたとき、ランダムにキャッチコピーを表示する。 変更ボタンを押すとキャッチコピーがランダムに変わる 今後付けたい機能 ・ 前置きが長くなりましたがここからがコードです。 だいぶごちゃっとしてますが(Javascriptが)多めに見ていただけると幸いです。 ここから何とかもうちょっと短くしたい気持ちはあります。 コード まずはHTML onchangeやonclickを使ってJavascriptのfunctionを呼び出しています。 javascript.html <html lang="ja"> <head> <script type="text/javascript" src="javascript_imp.js"></script> <link rel="stylesheet" href="javascript_imp.css"> <title>練習</title> </head> <body class="box"> <p>SIREN占い</p> <form name="form1"> <select name="limited" id="limited" size=1 onchange="change_func()"> <option value="one_only">無印のみ</option> <option value="two_only">2のみ</option> <option value="nt_only">ntのみ</option> <option value="all">全シリーズ</option> </select><span id="reload"></span> <p></p> <label for="number">何回占いをしますか?(1~5の間で入れてください)</label> <input type="number" name="number" id="number" min="1" max="5" value="1"></input>回 <p><span id="caution"></span></p> </form> <p></p> <button id="button_click" onclick="click_func()">ジェノサイダー!</button> <p></p> <span class="change" id="change"></span> <p></p> <fotter> 参考資料:各種bot 実況者様の動画など </fotter> </body> </html> 次にJavaScriptです。 for文、if文、Random関数、配列、連想配列(dictionary)などを使ってキャラ名を選択したりキャラ説明を出しています。 セリフはセリフでfunctionにしてあるのは純粋に一つ一つの要素が長くて後で追加したり編集するときに絶対めんどくさくなりそうだと思ったからです。 キャラごとのセリフをそれぞれ配列にしてfunctionの最後で一つに結合。それをjsファイル全体で使える変数に入れ直してます。 javascript.js var series = ["one", "two", "nt"]; var character_one = ["須田恭也","神代美耶子","竹内多聞","安野依子","志村晃","宮田司郎","牧野慶","八尾比沙子","神代亜矢子","神代淳","高遠玲子","四方田春海","美浜奈保子","恩田理沙","前田知子","石田徹雄", "恩田美奈","志村晃一"]; var character_two = ["一樹守","木船郁子","矢倉市子","永井頼人","三沢岳明","阿部倉司","三上脩","岸田百合","多河柳子","藤田茂","喜代田章子","加奈江","太田ともえ","太田常雄","三上隆平","沖田宏"]; var character_nt = ["ハワード・ライト","美耶古","サム・モンロー","メリッサ・ゲイル","ベラ・モンロー","犀賀省悟","アマナ","ソル・ジャクソン","河辺幸江"]; var item_one = ["火掻き棒","ネイルハンマー","ラチェットスパナ","テレフォンカード","発煙筒","ヴェール","壊れたラジオ","拳銃","木製バット","ライター","笑い袋","ビーズ人形","焔薙","図書貸し出しカード","写真","宇理炎", "鎌"]; var item_two = ["壊れた朱石のブレスレット","壊れた碧石のブレスレット","釘バット","メダル","髪飾り","首輪","奇石","週刊アトランティス","TNT","釘","軍用スコップ","あんなき","ゴルフクラブ","空き缶",""]; var item_nt = ["一升瓶","アナログテレビ","改造散弾銃","案内板","ビデオカメラ","缶切り","携帯電話","杭","アンテナ","ブローチ","柄杓","宇理炎","つるはし","トロッコ","ハニュウダカブト",""]; var quotation_one = Quotation_One(); var quotation_two = Quotation_Two(); var quotation_nt = Quotation_Nt(); var character; var item; var quotation; var word; var c_series; var i_series; var q_series; var num_fortune; var array_character = []; var array_item = []; var array_quotation = []; var num_c, num_i, num_q; num_c = 0; num_i = 0; num_q = 0; //どのシリーズか限定する文言が変わったらボタンの文字も変更 function change_func(){ var limited = document.getElementById("limited").value; if(limited == "one_only"){ document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "ジェノサイダー!"; }else if(limited == "two_only"){ document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "神風見せてやるよ!"; }else if(limited == "all"){ random_tagline(); document.getElementById("reload").innerHTML = "<span id='random' onclick='random_tagline()'>変更</span>"; }else { document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "Go To Hell!"; } } //配列を綺麗にまっさらにする function array_clean(){ array_character.splice(0); array_character = array_character.filter(Boolean); array_item = array_item.filter(Boolean); array_quotation = array_quotation.filter(Boolean); } //ゲームのキャッチコピーのどれかをランダムに出す function random_tagline(){ //ランダムな数字を1-3で出す var zetubo = Math.floor(Math.random() * 3) + 1; if(zetubo == 1){ document.getElementById("button_click").innerHTML = "どうあがいても、絶望"; }else if(zetubo == 2){ document.getElementById("button_click").innerHTML = "逃げ場なんて、ないよ"; }else{ document.getElementById("button_click").innerHTML = "息をすることさえ、恐怖"; } } //ボタンをクリックしたときの動作 function click_func(moji) { var num_fortune = document.getElementById("number").value; array_character.length = 0; array_quotation.length = 0; array_item.length = 0; num_i = 0; num_c = 0; num_q = 0; //もし占い回数が1未満、もしくは5より大きかった場合は警告を出す if(num_fortune<1 || num_fortune>5){ document.getElementById("caution").innerHTML = "範囲外です。1~5のどれかを入れてください"; moji = ""; }else{//それ以外の場合(占い回数が範囲内の場合) document.getElementById("caution").innerHTML = ""; var moji = ""; for(var i = 0; i < num_fortune; i++){ //シリーズが限定されているかを確認 var select = document.form1.limited.selectedIndex; if(select == 0){ c_series = "one"; i_series = "one"; q_series = "one"; }else if(select == 1){ c_series = "two"; i_series = "two"; q_series = "two"; }else if(select == 2){ c_series = "nt"; q_series = "nt"; i_series = "nt"; }else{ //キャラ、アイテム、セリフをそれぞれランダムに取得 c_series = series[Math.floor(Math.random() * series.length)]; q_series = series[Math.floor(Math.random() * series.length)]; i_series = series[Math.floor(Math.random() * series.length)]; } //キャラクターのシリーズをどれにするか if(c_series == "one"){ character = character_one[Math.floor(Math.random() * character_one.length)]; }else if(c_series == "two"){ character = character_two[Math.floor(Math.random() * character_two.length)]; }else if(c_series=="nt"){ character = character_nt[Math.floor(Math.random() * character_nt.length)]; } //アイテムのシリーズをどれにするか if(i_series == "one"){ item = item_one[Math.floor(Math.random() * item_one.length)]; }else if(i_series == "two"){ item = item_two[Math.floor(Math.random() * item_two.length)]; }else if(i_series=="nt"){ item = item_nt[Math.floor(Math.random() * item_nt.length)]; } //名言のシリーズをどれにするか if(q_series == "one"){ quotation = quotation_one[Math.floor(Math.random() * quotation_one.length)]; }else if(q_series == "two"){ quotation = quotation_two[Math.floor(Math.random() * quotation_two.length)]; }else if(q_series=="nt"){ quotation = quotation_nt[Math.floor(Math.random() * quotation_nt.length)]; } //要素を追加していく array_character[num_c] = character; array_item[num_i] = item; array_quotation[num_q] = quotation; //配列のempty要素を全削除 array_character = array_character.filter(Boolean); array_item = array_item.filter(Boolean); array_quotation = array_quotation.filter(Boolean); moji += add(character, item, quotation, i, num_fortune); num_c++; num_i++; num_q++; } } //HTMLを変更する document.getElementById("change").innerHTML = moji; } //説明を出すときの分岐用に文字を数字にそれぞれ変換する function henkan(suji){ if(suji == "one"){ return 1; }else if(suji == "two"){ return 2; }else{ return 3; } } //HTML作成用 function add(character, item, word, i, num_fortune){ return "<p>----------</p><span class='fortune-telling'><div class='explain' id='explain_" + i + "'></div><span class='character' id='character'>今日のあなたにぴったりなキャラクターは<div class='link' onclick='Explain_character(" + i + ", " + henkan(c_series) + ", " + num_fortune + ")'>" + character + "</div>です!</span><p></p><span class='item' id='item'>ラッキーアイテムは<div class='link' onclick='Explain_item(" + i + ", " + henkan(i_series) + ", " + num_fortune + ")'>"+item+"</div>です!</span><p></p><span class='quotation ' id='quotation'>今日の一言は「<div class='link' onclick='Explain_quotation(" + i + ", " + henkan(q_series) + ", " + num_fortune + ")'>"+word+"</div>」です!</span></span>"; } //無印の配列を生成して合成する奴 function Quotation_One(){ var kyoya = ["お前じゃなくて、須田恭也","悪いけど、美耶子との約束なんだ","そんで、この村からも逃げ出そう","お前らみたいなのがいる限り、俺は何度でも現れる"]; var miyako = ["恭也…ありがとう","ぐーず","ケルブじゃないとやっぱりだめ…","早く連れてけ!","私の目を使って"]; var jun = ["昨日のお返しだよ","美耶子、お前の役割はまだ終わってないだろう?","どうして亜矢子まで!","誰だ!"]; var ayako = ["違う…私は違う…!","あんたが生贄の羊になりなさいよ!","淳は、私の許嫁なんだから!"]; var yao = ["この水があなたの体内に入ったの…流した血の分だけ","あなたが実を盗んだのね!","もう、待つのは嫌…!"]; var makino = ["八尾さん…どこに行ったんだ?","私は…ただのみじめな道化だった","狂ってる…!","知子ちゃん!","きゅるってる!"]; var miyata = ["私も美奈さんを探していたんだ。とりあえず一緒に病院に","っ馬鹿な…!","それでも俺は、牧野さんになりたかった","煉獄の炎よ。俺の命と引き換えだ","あぁ…今行くよ", "本当にしつこい女だな"]; var risa = ["お姉ちゃん!お姉ちゃんなの!?","もしかして、宮田先生?私、恩田美奈の妹です!理沙です!","お姉ちゃんはどこなんですか!?お姉ちゃんは無事なんですか!?","そっくり!先生も双子?","お姉ちゃん男なんですか!?お姉ちゃん武士なんですか!?"]; var akira = ["お前が呼んだのか?","よそ者か…迷い込んだのか?","竹内か…","この村ももう終わりだ…","結局逃げきれないということか"]; var mihama = ["こっそりカメラ回してるんじゃないでしょうね!","永遠の若さ…永遠の若さ…"]; var tomoko = ["求導師様、どうしたんですか?","はーるみちゃんがほーしい","お父さん!お母さん!開けてよ!"]; var tamon = ["志村さん…なのか…?","車にいろと言ったはずだ","しかし、とんだ里帰りに君を巻き込んでしまったな","お父さん、お母さん…!"]; var yoriko = ["先生、家族ごっこしてる場合ですか!","無理やりついてきたのは私ですよ?","とりあえず村の人探しましょうよ。きっと大騒ぎですよ!","先生、それって…本物?"]; var takato = ["先生が絶対に助けてあげるからね…!","春海ちゃん!だめ…諦めたらだめ…!","春海ちゃん、どこぉ…?","めぐみ…お母さんを許して…","じゃあ、先生はお母さんになってあげる。春海ちゃんの"]; var harumi = ["お母さん…","先生、春海怖いよ…","うん…春海、待ってる","先生、助けて!先生!早く来て!"]; var ishida = ["無駄な抵抗は止めなさい","了解…射殺します"]; return kyoya.concat(miyako, jun, ayako, yao, makino, miyata, risa, akira, mihama, tomoko, tamon, yoriko, takato, harumi, ishida); } //2の配列を生成して合成する奴 function Quotation_Two(){ var ituki = ["クソ…俺は、だまされたのか?","化け物め…化け物め…化け物め…!","人にものを頼むときはお願いします、だろ?","やつの動きを止めるんだ!","俺という観測者が到達したとき、可能性は一つに収束する"]; var ikuko = ["もう一人の私…こんな思いしないのかな…?","結局この島に引き寄せられちゃったよ、お母さん…","先に…私たちが先にたどり着かないと!","そんな…化け物見るような眼で見ないでよ…","こんなところでかっこつけたって誰も見てないんだから!"]; var nagai = ["神風見せてやるよ!","沖田さん!死なないでください…沖田さん…!","人に助けてもらったときは何て言うんだっけ?"]; var misawa = ["士長、応戦だ","俺だけ先に目覚めちゃうけど…悪いな","久しぶりに最高の気分だ","あっち側もこっち側も関係ない","なーがいくん!一緒に遊びましょー!"]; var itiko = ["わからない…わからないよ…","お寝坊さんなお姉ちゃん","お前もずっと寂しかったんだろう?","違う…私、あの時死んだ!私は私じゃない!","みーつけた!"]; var kanae = ["脩…お姉ちゃんを許して…","脩、どこにいるの?","七つの門の七つの鍵を開けるの","お休み、脩"]; var yuri = ["あなたは、私を信じてくれる?","お母さんは鳩を飛ばし続けてたの","私を見て…"]; var shu = ["ツカサなのか…?これは、お前の…","お姉ちゃん!","お姉ちゃんもお外で遊べたらいいのにね","見える…見えるよ……"]; var abe = ["これ…純金じゃねぇのか?","クソすぎだろ!このままじゃよぉ…"]; var ryuko = ["あなた、お母さんと同じ気配…お母さん、目覚めようとしてるのね?","ごめんね…"]; var ryuhei = ["化け物なんかじゃないですよ","おーい、かくれんぼか?","学会に発表しなきゃなぁ"]; var hujita = ["やんなっちまうなぁ…","すまんなぁ、朝子","検挙するぞ!","始末書…始、末書"]; var kiyota = ["なんだか最悪の誕生日","あぁ…たくさんの強い念が…","私だってペーパーなんだから!","…分かった。信じる"]; var tomoe = ["髪飾り…お父様にもらった、髪飾り…","ここにいる!化け物女がここにいる!","誰か来て!誰かー!","虫けらのくせに!","髪飾り返してよ!","都会ってどんなところなのかなぁ"]; var tuneo = ["お前たち、やってくれるな?","藤田のバカ息子が…結局逃げかえってきたか"]; var okita = ["永井も随分と冷たいよなぁ","永井ぃ!俺だよ俺ぇ!","永井ー。根性出せよぉ"]; return ituki.concat(ikuko, nagai, misawa, itiko, kanae, yuri, shu, abe, ryuko, ryuhei, hujita, kiyota, tomoe, tuneo, okita); } //NTの配列を生成して合成する奴 function Quotation_Nt(){ var haward = ["Miyako, I promise.","ボクは、ハワード。君は?","ミヤコ、イッショ、ガンバル!"]; var saiga = ["運命に抗ってみますか?ご自由に","幸江…","俺はダンテではない。ベアトリーチェの導きは期待できない","もうあきらめろ。無駄だ。流れに身を任せろ","さすがに飽きた"]; var bella = ["Daddy said you can make bugs show up if you put something sweet on a tree...(ダディが言ってた 木に蜜を塗ったら虫が来るって)"]; var mellisa = ["When this thing died, the others did too.(こいつが死んだら…あいつらも死んだ?)"]; var yukie = ["先生は…私がいないと、だめなんだからぁ","先生ぇ…"]; var sam = ["Hey! Does that works? Maybe we can use it to call for help!(おい!その電話は使えないのか?その電話で助けを呼んでくれよ!)"]; var sol = ["Melissa,Bella...I hope you guys are okay.(メリッサ、ベラ…無事でいてくれよ…)"]; var amana = ["Perhaps we can set a trap.(罠を仕掛けられないでしょうか?)"]; var miyako = ["死にたくない!一緒に逃げたい!村の外を見てみたい、こんな村大嫌い…!","…早く連れてけ","いや!死ぬなんて絶対に嫌!","こんなことしかできない。…ごめんね、せっかく綺麗だったのに"]; return haward.concat(saiga, bella, mellisa, yukie, sam, sol, amana, miyako); } //どのシリーズのアイテムの説明を表示するかを判定 function Explain_item(item, series, num_fortune){ var id; document.getElementByClassName("link").style = ""; // colorのみ document.getElementByClassName("link").innerHTML = ""; var name = array_item[item]; if(series == 1){ ExplainItem_one(name, item); }else if(series == 2){ ExplainItem_two(name, item); }else{ ExplainItem_nt(name, item); } } //どのシリーズのキャラの説明を表示するかを判定 function Explain_character(character, series, num_fortune){ var id; for(var i = 0; i<num_fortune; i++){ id = "explain_"  + i; document.getElementById(id).style = ""; // colorのみ document.getElementById(id).innerHTML = ""; } var name = array_character[character]; if(series == 1){ ExplainCharacter_one(name, character); }else if(series == 2){ ExplainCharacter_two(name, character); }else{ ExplainCharacter_nt(name, character); } } //無印キャラクター説明用 function ExplainCharacter_one(character, num){ let dictionary = {"須田恭也":"『SIREN』の主人公。16歳。通称『ジェノサイダー』。都市伝説について調べようと村を訪れ、異変に巻き込まれる。", "安野依子":"『SIREN』の登場人物。竹内多聞の車にこっそりと乗りこんで着いてきたために異変に巻き込まれる。明るくマイペースな性格。", "竹内多聞":"大学教授。村の伝わる怪しい儀式などの真相を知るために帰ってきて異変に巻き込まれる。なぜか拳銃を所持。こっそり着いてきた生徒の安野依子と行動を共にする。", "志村晃":"山の中に住んでいた老人。異変に巻き込まれた村をおかしく思い、山から下りてくる。", "宮田司郎":"宮田医院の医者。その裏では神代にとって不都合な人間を消すという役割を担っている。とある事情から山の中にいたところで異界に巻き込まれる。", "牧野慶":"求導師。気弱な性格をしている。儀式をしていたが異変に巻き込まれ、求導女を探して歩き回る。道中で前田知子を保護し、行動を共にする。", "八尾比沙子":"求導女。須田を導いたりと優しいように見えるが…?", "神代美耶子":"神の花嫁。儀式の生贄だったが、異変に巻き込まれた際に逃走。盲目の為、一人での行動がほぼ不可能。", "神代淳":"神代の次代当主として養子になった。その立場故か少し傲慢なところがある。儀式中に異変に巻き込まれる。", "神代亜矢子":"神代家次期当主、神代淳の許嫁。神代淳によく構われている妹の神代美耶子の事をよく思っていない。儀式中に異変に巻き込まれる。", "四方田春海":"小学生。高遠玲子、名越栄治と共に星を見る会に参加中に異変に巻き込まれる。教師である高遠玲子と共に行動する。", "高遠玲子":"教師。名越栄治、四方田春海と星を見る会に参加中に異変に巻き込まれる。生徒である四方田春海と行動を共にする。", "志村晃一":"志村晃の息子。27年前に行方不明となった。詳しくは羽生蛇村異聞参照。", "美浜奈保子":"グラビアアイドル。クルーたちと共に村に来たが、巻き込まれた際に離れ離れとなってしまう。一人で行動する。", "恩田理沙":"恩田美奈の双子の妹。姉に会いに村に戻ってきたが異変に巻き込まれる。一人で廃屋から脱出した後、宮田司郎と出会い行動を共にする。", "前田知子":"両親と喧嘩し、家出している最中に異変に巻き込まれてしまった少女。両親のもとへ戻るため求導師と共に行動する。", "石田徹雄":"警察官。須田の前に現れ、銃を向けてくる。", "恩田美奈":"宮田医院の看護師。異変に巻き込まれる前に死亡していた。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } //2キャラクター説明用 function ExplainCharacter_two(character, num){ let dictionary = {"一樹守":"『SIREN2』の主人公。オカルト雑誌、週刊アトランティスの記者。夜見島に伝わる都市伝説などを調査するために夜見島へ渡る。", "木船郁子":"感応視という能力を持っている。一樹たちを夜見島に送る船長の手伝いをしていた。", "矢倉市子":"記憶が一部ない少女。フェリーの中で目を覚まし、助けに来てくれた警察官の藤田茂と共に行動する。", "永井頼人":"夜見島に不時着した自衛隊の士長。尊敬する上官の沖田が着陸の際に自分を庇って亡くなってしまったため、同じく生存した三沢岳明と共に行動する。", "三沢岳明":"永井の上官。生き残った永井の指揮を執った。幻覚を見たりすることがあり、薬に頼っている。", "阿部倉司":"恋人が死んだと信じられず、探すために占い師の喜代田章子と共に夜見島へ来た。", "三上脩":"とある事柄によって弱視になってしまった青年。自らの過去の記憶を取り戻すべく生まれ故郷の夜見島へと向かった。", "岸田百合":"正体不明の少女。島の廃倉庫の中に倒れていたところを一樹によって保護される。", "多河柳子":"阿部の恋人。頭部を何度も殴打されて死亡している。", "藤田茂":"警察官。人のいないはずの夜見島で怪しい女を見たという通報を聞いて夜見島へと向かう。お人好しなところがあり、だまされやすい。", "喜代田章子":"占い師の少女。過去視という能力を持っている。阿部の無実を確実にするため、阿部と共に夜見島へと向かう。", "太田ともえ":"網元の娘。網元という自分の父親の仕事に対して誇りを持っており、自身も島を不浄から守るため尽力する。髪飾りは父親からのプレゼント。", "太田常雄":"網元。島を不浄なものから守るために尽力している。", "三上隆平":"三上脩の父親。SIRENの登場人物、竹内多聞の父親とは交流があった。妻を事故で亡くしている。", "沖田宏":"永井頼人の上官であり三沢岳明の部下。不時着の際に永井を庇って死亡。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } //NTキャラクター説明用 function ExplainCharacter_nt(character, num){ let dictionary = {"ハワード・ライト":"『SIREN:NT』の主人公。儀式の犠牲になろうとしていた少女を助け、異界に巻き込まれる。", "美耶古":"神の花嫁。儀式の際にハワードが止めに入った時に逃走。盲目ではない。", "サム・モンロー":"教授。娘と一緒に暮らしており、妻とは別れている。村の儀式を撮りに来たテレビクルーたちに同行している時に異界に巻き込まれる。", "メリッサ・ゲイル":"テレビクルーの一人。娘とは一緒に暮らしておらず、夫とは別れている。儀式を撮っている最中に異界に巻き込まれる。", "ベラ・モンロー":"サム・モンローとメリッサ・ゲイルの娘。父親と一緒に暮らしており、ベビーシッターが見つからなかったため", "犀賀省悟":"犀賀医院の院長。その裏ではアマナの不都合となる人間を消すという役割をしていた。", "アマナ":"求導女。怪我をしていたハワードの事を助け、共に行動する。", "ソル・ジャクソン":"テレビクルーのカメラマン。メリッサの事が好き。", "河辺幸江":"犀賀医院の看護師。異界に巻き込まれる前に死亡していた。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } 最後はCSSです。 体裁をいい感じに整えています。 javascript.css span{ display: inline-block; margin:10px 10px; } body{ display: inline-block; margin:10 auto; width:100vm; padding-bottom:10%; } #caution{ color:red; } .fortune-telling{ border:1px dashed blue; } form{ font-size:16px; } .change{ margin-left-10%; margin-right:auto; } .box{ border-right:solid 3px #66CCFF; border-left:solid 3px #66CCFF; border-top:solid 3px #9999CC; border-bottom:solid 3px #9999CC; text-align:center; width:80%; } .link{ color:#6699CC; } fotter{ color: #CCCCCC; font-size:13px; } #random{ border:solid 1px #99CCCC; user-select: none; /* CSS3 */ -moz-user-select: none; /* Firefox */ -webkit-user-select: none; /* Safari、Chromeなど */ -ms-user-select: none; /* IE10かららしい */ } というわけでコードはこんな感じでした。 まとめ 難しかったです。 予想しない挙動(キャラ名を押すと必ずすべての説明が一番上のキャラ名の上に表示されてしまうなど)が起きたりエラーが起きたり結構してました。 でも楽しかったのでこれからも改良していきたいですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ほぼ初心者が作ったランダムに好きなホラーゲームのキャラ名、セリフ、アイテムを表示するプログラム

個人的に大好きなホラーゲーム、SIREN。 朝仕事に行く前などに占いのような形式でキャラ名とアイテム名とセリフが出るプログラムが欲しいな!そうすれば仕事行く元気すごく出るよ!! その思いが募った結果、手軽に作れるJavaScriptとHTML、CSSを使って好きなホラーゲームのキャラ名、アイテム名、セリフが出るプログラムを作ってみました。 JavaScriptに関しても初心者なので結構コードがぐちゃぐちゃになってしまったので今後改良出来たらしていきたいですね。 スマホアプリのjsanywhereを使って実行するのでデータベースなどは使用していません。 作ったもの ・好きなホラーゲーム、SIRENのキャラ名、アイテム名、セリフをランダムに表示する ・何回表示するかを1-5回までで選択できる。 ・シリーズを限定するか全シリーズにするかを選択できる。 ・シリーズを限定した場合は各主人公のセリフを表示、全シリーズにした場合はシリーズのキャッチコピーをランダムに表示する(変更というボタンをクリックすることでランダムにキャッチコピーを変更可能) ・キャラ名をクリックすると説明が見れる javascript_imp.html <html lang="ja"> <head> <script type="text/javascript" src="javascript_imp.js"></script> <link rel="stylesheet" href="javascript_imp.css"> <title>練習</title> </head> <body class="box"> <p>SIREN占い</p> <form name="form1"> <select name="limited" id="limited" size=1 onchange="change_func()"> <option value="one_only">無印のみ</option> <option value="two_only">2のみ</option> <option value="nt_only">ntのみ</option> <option value="all">全シリーズ</option> </select><span id="reload"></span> <p></p> <label for="number">何回占いをしますか?(1~5の間で入れてください)</label> <input type="number" name="number" id="number" min="1" max="5" value="1"></input>回 <p><span id="caution"></span></p> </form> <p></p> <button id="button_click" onclick="click_func()">ジェノサイダー!</button> <p></p> <span class="change" id="change"></span> <p></p> <fotter> 参考資料:各種bot 実況者様の動画など </fotter> </body> </html> 複数回結果を表示することもあるのでHTMLは結構シンプルになってます。 シリーズを選択すると文字が変わる、という風にしたかったのでonchangeを使ってjavascriptのfunctionを呼び出しています。 javascript_imp.js var series = ["one", "two", "nt"]; var character_one = ["須田恭也","神代美耶子","竹内多聞","安野依子","志村晃","宮田司郎","牧野慶","八尾比沙子","神代亜矢子","神代淳","高遠玲子","四方田春海","美浜奈保子","恩田理沙","前田知子","石田徹雄", "恩田美奈","志村晃一"]; var character_two = ["一樹守","木船郁子","矢倉市子","永井頼人","三沢岳明","阿部倉司","三上脩","岸田百合","多河柳子","藤田茂","喜代田章子","加奈江","太田ともえ","太田常雄","三上隆平","沖田宏"]; var character_nt = ["ハワード・ライト","美耶古","サム・モンロー","メリッサ・ゲイル","ベラ・モンロー","犀賀省悟","アマナ","ソル・ジャクソン","河辺幸江"]; var item_one = ["火掻き棒","ネイルハンマー","ラチェットスパナ","テレフォンカード","発煙筒","ヴェール","壊れたラジオ","拳銃","木製バット","ライター","笑い袋","ビーズ人形","焔薙","図書貸し出しカード","写真","宇理炎", "鎌"]; var item_two = ["壊れた朱石のブレスレット","壊れた碧石のブレスレット","釘バット","メダル","髪飾り","首輪","奇石","週刊アトランティス","TNT","釘","軍用スコップ","あんなき","ゴルフクラブ","空き缶",""]; var item_nt = ["一升瓶","アナログテレビ","改造散弾銃","案内板","ビデオカメラ","缶切り","携帯電話","杭","アンテナ","ブローチ","柄杓","宇理炎","つるはし","トロッコ","ハニュウダカブト",""]; var quotation_one = Quotation_One(); var quotation_two = Quotation_Two(); var quotation_nt = Quotation_Nt(); var character; var item; var quotation; var word; var c_series; var i_series; var q_series; var num_fortune; var array_character = []; var array_item = []; var array_quotation = []; var num_c, num_i, num_q; num_c = 0; num_i = 0; num_q = 0; //どのシリーズか限定する文言が変わったらボタンの文字も変更 function change_func(){ var limited = document.getElementById("limited").value; if(limited == "one_only"){ document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "ジェノサイダー!"; }else if(limited == "two_only"){ document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "神風見せてやるよ!"; }else if(limited == "all"){ random_tagline(); document.getElementById("reload").innerHTML = "<span id='random' onclick='random_tagline()'>変更</span>"; }else { document.getElementById("reload").innerHTML = ""; document.getElementById("button_click").innerHTML = "Go To Hell!"; } } //配列を綺麗にまっさらにする function array_clean(){ array_character.splice(0); array_character = array_character.filter(Boolean); array_item = array_item.filter(Boolean); array_quotation = array_quotation.filter(Boolean); } //ゲームのキャッチコピーのどれかをランダムに出す function random_tagline(){ //ランダムな数字を1-3で出す var zetubo = Math.floor(Math.random() * 3) + 1; if(zetubo == 1){ document.getElementById("button_click").innerHTML = "どうあがいても、絶望"; }else if(zetubo == 2){ document.getElementById("button_click").innerHTML = "逃げ場なんて、ないよ"; }else{ document.getElementById("button_click").innerHTML = "息をすることさえ、恐怖"; } } //ボタンをクリックしたときの動作 function click_func(moji) { var num_fortune = document.getElementById("number").value; array_character.length = 0; array_quotation.length = 0; array_item.length = 0; num_i = 0; num_c = 0; num_q = 0; //もし占い回数が1未満、もしくは5より大きかった場合は警告を出す if(num_fortune<1 || num_fortune>5){ document.getElementById("caution").innerHTML = "範囲外です。1~5のどれかを入れてください"; moji = ""; }else{//それ以外の場合(占い回数が範囲内の場合) document.getElementById("caution").innerHTML = ""; var moji = ""; for(var i = 0; i < num_fortune; i++){ //シリーズが限定されているかを確認 var select = document.form1.limited.selectedIndex; if(select == 0){ c_series = "one"; i_series = "one"; q_series = "one"; }else if(select == 1){ c_series = "two"; i_series = "two"; q_series = "two"; }else if(select == 2){ c_series = "nt"; q_series = "nt"; i_series = "nt"; }else{ //キャラ、アイテム、セリフをそれぞれランダムに取得 c_series = series[Math.floor(Math.random() * series.length)]; q_series = series[Math.floor(Math.random() * series.length)]; i_series = series[Math.floor(Math.random() * series.length)]; } //キャラクターのシリーズをどれにするか if(c_series == "one"){ character = character_one[Math.floor(Math.random() * character_one.length)]; }else if(c_series == "two"){ character = character_two[Math.floor(Math.random() * character_two.length)]; }else if(c_series=="nt"){ character = character_nt[Math.floor(Math.random() * character_nt.length)]; } //アイテムのシリーズをどれにするか if(i_series == "one"){ item = item_one[Math.floor(Math.random() * item_one.length)]; }else if(i_series == "two"){ item = item_two[Math.floor(Math.random() * item_two.length)]; }else if(i_series=="nt"){ item = item_nt[Math.floor(Math.random() * item_nt.length)]; } //名言のシリーズをどれにするか if(q_series == "one"){ quotation = quotation_one[Math.floor(Math.random() * quotation_one.length)]; }else if(q_series == "two"){ quotation = quotation_two[Math.floor(Math.random() * quotation_two.length)]; }else if(q_series=="nt"){ quotation = quotation_nt[Math.floor(Math.random() * quotation_nt.length)]; } //要素を追加していく array_character[num_c] = character; array_item[num_i] = item; array_quotation[num_q] = quotation; //配列のempty要素を全削除 array_character = array_character.filter(Boolean); array_item = array_item.filter(Boolean); array_quotation = array_quotation.filter(Boolean); moji += add(character, item, quotation, i, num_fortune); num_c++; num_i++; num_q++; } } //HTMLを変更する document.getElementById("change").innerHTML = moji; } //説明を出すときの分岐用に文字を数字にそれぞれ変換する function henkan(suji){ if(suji == "one"){ return 1; }else if(suji == "two"){ return 2; }else{ return 3; } } //HTML作成用 function add(character, item, word, i, num_fortune){ return "<p>----------</p><span class='fortune-telling'><div class='explain' id='explain_" + i + "'></div><span class='character' id='character'>今日のあなたにぴったりなキャラクターは<div class='link' onclick='Explain_character(" + i + ", " + henkan(c_series) + ", " + num_fortune + ")'>" + character + "</div>です!</span><p></p><span class='item' id='item'>ラッキーアイテムは<div class='link' onclick='Explain_item(" + i + ", " + henkan(i_series) + ", " + num_fortune + ")'>"+item+"</div>です!</span><p></p><span class='quotation ' id='quotation'>今日の一言は「<div class='link' onclick='Explain_quotation(" + i + ", " + henkan(q_series) + ", " + num_fortune + ")'>"+word+"</div>」です!</span></span>"; } //無印の配列を生成して合成する奴 function Quotation_One(){ var kyoya = ["お前じゃなくて、須田恭也","悪いけど、美耶子との約束なんだ","そんで、この村からも逃げ出そう","お前らみたいなのがいる限り、俺は何度でも現れる"]; var miyako = ["恭也…ありがとう","ぐーず","ケルブじゃないとやっぱりだめ…","早く連れてけ!","私の目を使って"]; var jun = ["昨日のお返しだよ","美耶子、お前の役割はまだ終わってないだろう?","どうして亜矢子まで!","誰だ!"]; var ayako = ["違う…私は違う…!","あんたが生贄の羊になりなさいよ!","淳は、私の許嫁なんだから!"]; var yao = ["この水があなたの体内に入ったの…流した血の分だけ","あなたが実を盗んだのね!","もう、待つのは嫌…!"]; var makino = ["八尾さん…どこに行ったんだ?","私は…ただのみじめな道化だった","狂ってる…!","知子ちゃん!","きゅるってる!"]; var miyata = ["私も美奈さんを探していたんだ。とりあえず一緒に病院に","っ馬鹿な…!","それでも俺は、牧野さんになりたかった","煉獄の炎よ。俺の命と引き換えだ","あぁ…今行くよ", "本当にしつこい女だな"]; var risa = ["お姉ちゃん!お姉ちゃんなの!?","もしかして、宮田先生?私、恩田美奈の妹です!理沙です!","お姉ちゃんはどこなんですか!?お姉ちゃんは無事なんですか!?","そっくり!先生も双子?","お姉ちゃん男なんですか!?お姉ちゃん武士なんですか!?"]; var akira = ["お前が呼んだのか?","よそ者か…迷い込んだのか?","竹内か…","この村ももう終わりだ…","結局逃げきれないということか"]; var mihama = ["こっそりカメラ回してるんじゃないでしょうね!","永遠の若さ…永遠の若さ…"]; var tomoko = ["求導師様、どうしたんですか?","はーるみちゃんがほーしい","お父さん!お母さん!開けてよ!"]; var tamon = ["志村さん…なのか…?","車にいろと言ったはずだ","しかし、とんだ里帰りに君を巻き込んでしまったな","お父さん、お母さん…!"]; var yoriko = ["先生、家族ごっこしてる場合ですか!","無理やりついてきたのは私ですよ?","とりあえず村の人探しましょうよ。きっと大騒ぎですよ!","先生、それって…本物?"]; var takato = ["先生が絶対に助けてあげるからね…!","春海ちゃん!だめ…諦めたらだめ…!","春海ちゃん、どこぉ…?","めぐみ…お母さんを許して…","じゃあ、先生はお母さんになってあげる。春海ちゃんの"]; var harumi = ["お母さん…","先生、春海怖いよ…","うん…春海、待ってる","先生、助けて!先生!早く来て!"]; var ishida = ["無駄な抵抗は止めなさい","了解…射殺します"]; return kyoya.concat(miyako, jun, ayako, yao, makino, miyata, risa, akira, mihama, tomoko, tamon, yoriko, takato, harumi, ishida); } //2の配列を生成して合成する奴 function Quotation_Two(){ var ituki = ["クソ…俺は、だまされたのか?","化け物め…化け物め…化け物め…!","人にものを頼むときはお願いします、だろ?","やつの動きを止めるんだ!","俺という観測者が到達したとき、可能性は一つに収束する"]; var ikuko = ["もう一人の私…こんな思いしないのかな…?","結局この島に引き寄せられちゃったよ、お母さん…","先に…私たちが先にたどり着かないと!","そんな…化け物見るような眼で見ないでよ…","こんなところでかっこつけたって誰も見てないんだから!"]; var nagai = ["神風見せてやるよ!","沖田さん!死なないでください…沖田さん…!","人に助けてもらったときは何て言うんだっけ?"]; var misawa = ["士長、応戦だ","俺だけ先に目覚めちゃうけど…悪いな","久しぶりに最高の気分だ","あっち側もこっち側も関係ない","なーがいくん!一緒に遊びましょー!"]; var itiko = ["わからない…わからないよ…","お寝坊さんなお姉ちゃん","お前もずっと寂しかったんだろう?","違う…私、あの時死んだ!私は私じゃない!","みーつけた!"]; var kanae = ["脩…お姉ちゃんを許して…","脩、どこにいるの?","七つの門の七つの鍵を開けるの","お休み、脩"]; var yuri = ["あなたは、私を信じてくれる?","お母さんは鳩を飛ばし続けてたの","私を見て…"]; var shu = ["ツカサなのか…?これは、お前の…","お姉ちゃん!","お姉ちゃんもお外で遊べたらいいのにね","見える…見えるよ……"]; var abe = ["これ…純金じゃねぇのか?","クソすぎだろ!このままじゃよぉ…"]; var ryuko = ["あなた、お母さんと同じ気配…お母さん、目覚めようとしてるのね?","ごめんね…"]; var ryuhei = ["化け物なんかじゃないですよ","おーい、かくれんぼか?","学会に発表しなきゃなぁ"]; var hujita = ["やんなっちまうなぁ…","すまんなぁ、朝子","検挙するぞ!","始末書…始、末書"]; var kiyota = ["なんだか最悪の誕生日","あぁ…たくさんの強い念が…","私だってペーパーなんだから!","…分かった。信じる"]; var tomoe = ["髪飾り…お父様にもらった、髪飾り…","ここにいる!化け物女がここにいる!","誰か来て!誰かー!","虫けらのくせに!","髪飾り返してよ!","都会ってどんなところなのかなぁ"]; var tuneo = ["お前たち、やってくれるな?","藤田のバカ息子が…結局逃げかえってきたか"]; var okita = ["永井も随分と冷たいよなぁ","永井ぃ!俺だよ俺ぇ!","永井ー。根性出せよぉ"]; return ituki.concat(ikuko, nagai, misawa, itiko, kanae, yuri, shu, abe, ryuko, ryuhei, hujita, kiyota, tomoe, tuneo, okita); } //NTの配列を生成して合成する奴 function Quotation_Nt(){ var haward = ["Miyako, I promise.","ボクは、ハワード。君は?","ミヤコ、イッショ、ガンバル!"]; var saiga = ["運命に抗ってみますか?ご自由に","幸江…","俺はダンテではない。ベアトリーチェの導きは期待できない","もうあきらめろ。無駄だ。流れに身を任せろ","さすがに飽きた"]; var bella = ["Daddy said you can make bugs show up if you put something sweet on a tree...(ダディが言ってた 木に蜜を塗ったら虫が来るって)"]; var mellisa = ["When this thing died, the others did too.(こいつが死んだら…あいつらも死んだ?)"]; var yukie = ["先生は…私がいないと、だめなんだからぁ","先生ぇ…"]; var sam = ["Hey! Does that works? Maybe we can use it to call for help!(おい!その電話は使えないのか?その電話で助けを呼んでくれよ!)"]; var sol = ["Melissa,Bella...I hope you guys are okay.(メリッサ、ベラ…無事でいてくれよ…)"]; var amana = ["Perhaps we can set a trap.(罠を仕掛けられないでしょうか?)"]; var miyako = ["死にたくない!一緒に逃げたい!村の外を見てみたい、こんな村大嫌い…!","…早く連れてけ","いや!死ぬなんて絶対に嫌!","こんなことしかできない。…ごめんね、せっかく綺麗だったのに"]; return haward.concat(saiga, bella, mellisa, yukie, sam, sol, amana, miyako); } //どのシリーズのアイテムの説明を表示するかを判定 function Explain_item(item, series, num_fortune){ var id; document.getElementByClassName("link").style = ""; // colorのみ document.getElementByClassName("link").innerHTML = ""; var name = array_item[item]; if(series == 1){ ExplainItem_one(name, item); }else if(series == 2){ ExplainItem_two(name, item); }else{ ExplainItem_nt(name, item); } } //どのシリーズのキャラの説明を表示するかを判定 function Explain_character(character, series, num_fortune){ var id; for(var i = 0; i<num_fortune; i++){ id = "explain_"  + i; document.getElementById(id).style = ""; // colorのみ document.getElementById(id).innerHTML = ""; } var name = array_character[character]; if(series == 1){ ExplainCharacter_one(name, character); }else if(series == 2){ ExplainCharacter_two(name, character); }else{ ExplainCharacter_nt(name, character); } } //無印キャラクター説明用 function ExplainCharacter_one(character, num){ let dictionary = {"須田恭也":"『SIREN』の主人公。16歳。通称『ジェノサイダー』。都市伝説について調べようと村を訪れ、異変に巻き込まれる。", "安野依子":"『SIREN』の登場人物。竹内多聞の車にこっそりと乗りこんで着いてきたために異変に巻き込まれる。明るくマイペースな性格。", "竹内多聞":"大学教授。村の伝わる怪しい儀式などの真相を知るために帰ってきて異変に巻き込まれる。なぜか拳銃を所持。こっそり着いてきた生徒の安野依子と行動を共にする。", "志村晃":"山の中に住んでいた老人。異変に巻き込まれた村をおかしく思い、山から下りてくる。", "宮田司郎":"宮田医院の医者。その裏では神代にとって不都合な人間を消すという役割を担っている。とある事情から山の中にいたところで異界に巻き込まれる。", "牧野慶":"求導師。気弱な性格をしている。儀式をしていたが異変に巻き込まれ、求導女を探して歩き回る。道中で前田知子を保護し、行動を共にする。", "八尾比沙子":"求導女。須田を導いたりと優しいように見えるが…?", "神代美耶子":"神の花嫁。儀式の生贄だったが、異変に巻き込まれた際に逃走。盲目の為、一人での行動がほぼ不可能。", "神代淳":"神代の次代当主として養子になった。その立場故か少し傲慢なところがある。儀式中に異変に巻き込まれる。", "神代亜矢子":"神代家次期当主、神代淳の許嫁。神代淳によく構われている妹の神代美耶子の事をよく思っていない。儀式中に異変に巻き込まれる。", "四方田春海":"小学生。高遠玲子、名越栄治と共に星を見る会に参加中に異変に巻き込まれる。教師である高遠玲子と共に行動する。", "高遠玲子":"教師。名越栄治、四方田春海と星を見る会に参加中に異変に巻き込まれる。生徒である四方田春海と行動を共にする。", "志村晃一":"志村晃の息子。27年前に行方不明となった。詳しくは羽生蛇村異聞参照。", "美浜奈保子":"グラビアアイドル。クルーたちと共に村に来たが、巻き込まれた際に離れ離れとなってしまう。一人で行動する。", "恩田理沙":"恩田美奈の双子の妹。姉に会いに村に戻ってきたが異変に巻き込まれる。一人で廃屋から脱出した後、宮田司郎と出会い行動を共にする。", "前田知子":"両親と喧嘩し、家出している最中に異変に巻き込まれてしまった少女。両親のもとへ戻るため求導師と共に行動する。", "石田徹雄":"警察官。須田の前に現れ、銃を向けてくる。", "恩田美奈":"宮田医院の看護師。異変に巻き込まれる前に死亡していた。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } //2キャラクター説明用 function ExplainCharacter_two(character, num){ let dictionary = {"一樹守":"『SIREN2』の主人公。オカルト雑誌、週刊アトランティスの記者。夜見島に伝わる都市伝説などを調査するために夜見島へ渡る。", "木船郁子":"感応視という能力を持っている。一樹たちを夜見島に送る船長の手伝いをしていた。", "矢倉市子":"記憶が一部ない少女。フェリーの中で目を覚まし、助けに来てくれた警察官の藤田茂と共に行動する。", "永井頼人":"夜見島に不時着した自衛隊の士長。尊敬する上官の沖田が着陸の際に自分を庇って亡くなってしまったため、同じく生存した三沢岳明と共に行動する。", "三沢岳明":"永井の上官。生き残った永井の指揮を執った。幻覚を見たりすることがあり、薬に頼っている。", "阿部倉司":"恋人が死んだと信じられず、探すために占い師の喜代田章子と共に夜見島へ来た。", "三上脩":"とある事柄によって弱視になってしまった青年。自らの過去の記憶を取り戻すべく生まれ故郷の夜見島へと向かった。", "岸田百合":"正体不明の少女。島の廃倉庫の中に倒れていたところを一樹によって保護される。", "多河柳子":"阿部の恋人。頭部を何度も殴打されて死亡している。", "藤田茂":"警察官。人のいないはずの夜見島で怪しい女を見たという通報を聞いて夜見島へと向かう。お人好しなところがあり、だまされやすい。", "喜代田章子":"占い師の少女。過去視という能力を持っている。阿部の無実を確実にするため、阿部と共に夜見島へと向かう。", "太田ともえ":"網元の娘。網元という自分の父親の仕事に対して誇りを持っており、自身も島を不浄から守るため尽力する。髪飾りは父親からのプレゼント。", "太田常雄":"網元。島を不浄なものから守るために尽力している。", "三上隆平":"三上脩の父親。SIRENの登場人物、竹内多聞の父親とは交流があった。妻を事故で亡くしている。", "沖田宏":"永井頼人の上官であり三沢岳明の部下。不時着の際に永井を庇って死亡。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } //NTキャラクター説明用 function ExplainCharacter_nt(character, num){ let dictionary = {"ハワード・ライト":"『SIREN:NT』の主人公。儀式の犠牲になろうとしていた少女を助け、異界に巻き込まれる。", "美耶古":"神の花嫁。儀式の際にハワードが止めに入った時に逃走。盲目ではない。", "サム・モンロー":"教授。娘と一緒に暮らしており、妻とは別れている。村の儀式を撮りに来たテレビクルーたちに同行している時に異界に巻き込まれる。", "メリッサ・ゲイル":"テレビクルーの一人。娘とは一緒に暮らしておらず、夫とは別れている。儀式を撮っている最中に異界に巻き込まれる。", "ベラ・モンロー":"サム・モンローとメリッサ・ゲイルの娘。父親と一緒に暮らしており、ベビーシッターが見つからなかったため", "犀賀省悟":"犀賀医院の院長。その裏ではアマナの不都合となる人間を消すという役割をしていた。", "アマナ":"求導女。怪我をしていたハワードの事を助け、共に行動する。", "ソル・ジャクソン":"テレビクルーのカメラマン。メリッサの事が好き。", "河辺幸江":"犀賀医院の看護師。異界に巻き込まれる前に死亡していた。"} var id = "explain_" + num; document.getElementById(id).innerHTML = dictionary[character]; document.getElementById(id).style = "border:solid 2px #CCCCFF"; // colorのみ } キャラ名、アイテム名はそれぞれ最初のところで配列に入れてます。 セリフは長くてごちゃごちゃしそうなので下の方のメソッドでキャラ名の配列をそれぞれ作成→合成して一つの配列にしてます。 ・配列作成と結合 ・ランダム関数 ・特定のIDの中身を書き換える ・CSSの作成 ・directory(辞書型) この辺りを使ってます。 最初は配列を削除していなかったため、結果を表示してから回数を増やして実行すると最初の方の結果が一つ前と全く一緒という事象が起きたり、キャラ名を押して表示する説明が押したキャラ名の上ではなく一番上のキャラ名の上に表示されたり(IDが全て同じだったために起きた事象)など予想外なことがたくさん起きました。 何とか検索して考えて最終的に出来たのがさっきのコードです。 CSSはこんな感じです。 javascript.css @charset "utf-8"; span{ display: inline-block; margin:10px 10px; } body{ display: inline-block; margin:10 auto; width:100vm; padding-bottom:10%; } #caution{ color:red; } .fortune-telling{ border:1px dashed blue; } form{ font-size:16px; } .change{ margin-left-10%; margin-right:auto; } .box{ border-right:solid 3px #66CCFF; border-left:solid 3px #66CCFF; border-top:solid 3px #9999CC; border-bottom:solid 3px #9999CC; text-align:center; width:80%; } .link{ color:#6699CC; } fotter{ color: #CCCCCC; font-size:13px; } #random{ border:solid 1px #99CCCC; user-select: none; /* CSS3 */ -moz-user-select: none; /* Firefox */ -webkit-user-select: none; /* Safari、Chromeなど */ -ms-user-select: none; /* IE10かららしい */ } これから改良したい点としては ・特定のキャラ名+アイテム名+セリフだった場合は文言を表示する。 ・血液型占いとかのように何かしらの要素で表示する このあたりですかね…。前者はまだしも後者は結構コード増えそうなので今のこの趣味の範囲では「実装(一生未定)」という感じではありますが。 というわけで初心者の頑張りでした。 メモ帳にばーっと書いたのをインデントを少し直しただけなのでおかしなところがあったらご指摘いただければ幸いです。 これからもJavaScriptで色々作っていきたいですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Denoのreplをブラウザコンソールから使う

Denoのコマンドラインフラグの中にdeno repl --inspectというのを発見。使ってみたらいい感じだった。 使い方 コマンドライン $ deno repl --inspect Debugger listening on ws://127.0.0.1:9229/ws/595bd5b5-17d9-471e-baa0-ec369fca365b Deno 1.10.0+5792778 exit using ctrl+d or close() > Debugger session started. とコマンドを打ってからChromeの開発者ツールを開く。 左上にNode.jsの六角形マークが表示されているのでクリック。 すると、Node.jsという名前でDenoのreplが開く。 Deno.***のAPIたちが見えているので間違いなくDenoランタイムで動いているコードだ。 なぜNode.jsと左上に表示されているのかというと、inspectorプロトコル上でNode.jsを装うことでdevtoolの表示が改善できるからっぽい。 chrome://inspect/#devicesにアクセスしてdevicesからdenoを選択しても同じ結果が得られる。 とりあえず何かしらのreplが開きたい時に便利。メリットは ローカルファイルにアクセスできる デフォルトでfetchを使える(CORSを気にする必要なし) requireする必要なし みたいなところかな。 おまけ:この画面を自動で開きたい コマンドを打ってからウィンドウを毎回切り替えるのは面倒。スタートメニューからワンクリックで起動できないだろうか。 色々調べると ① http://127.0.0.1:9229/jsonにアクセスする ② ①で返ってくるjsonを元にdevtools://devtools/bundled/js_app.html?ws=127.0.0.1:9229/ws/<ここにuuid>&experiments=true&v8only=trueというURLにアクセスする という方法で開けることが分かった。 試した① javscriptブックマーク →ブックマークにjavascriptを登録するのが一番簡単そう。しかし、devtools://以下のURLへのアクセスは弾かれる。この方法は使えない。 試した② puppeteer →同じくdevtools://以下のURLは弾かれてダメだった。 試した③ Chrome拡張 似たことをしているChrome拡張にNIMとrawkitがある。が、前者はなんか動かず、後者はNodeのみ対応ということで使えなかった。 最終的にchrome拡張を自作することに。 background scriptからならdevtools://以下のページを操作することができそう。 バックグラウンドから1秒間隔でhttp://127.0.0.1:9229/jsonにアクセスし、 ・inspectorの情報が返ってくればdevtoolタブを開く ・返ってこなければdevtoolタブを閉じる という実装をする。 した。 フォルダ構成 extension/ ├manifest.json └background.js manifest.json { "name": "Deno Debugger Open", "version": "1.0.0", "manifest_version": 2, "description": "Deno Debugger Open", "permissions": ["tabs", "debugger", "<all_urls>"], "background": { "scripts": ["background.js"], "persistent": false } } background.js let url, shouldOpen; setInterval(async () => { try { const res = await fetch("http://127.0.0.1:9229/json"); const json = await res.json(); url = json[0].devtoolsFrontendUrl; shouldOpen = true; } catch (_) { shouldOpen = false; } if (!url) { return; } chrome.tabs.query({ url }, (tabs) => { if (shouldOpen) { if (!tabs.length) { console.log("open: ", url); chrome.tabs.create({ url }); } } else { console.log("close: ", url); for (const tab of tabs) { chrome.tabs.remove(tab.id); } } }); }, 1000); これを拡張機能として登録すると、replの起動を検知した時にブラウザの画面いっぱいにconsoleの画面が自動で開くようになるはず。 最後に、replの起動ボタンをスタートメニューに追加する。 ショートカットを作って、右クリック→スタートメニューに追加 でOK。 ショートカットのリンク先 C:\Windows\System32\cmd.exe /c deno repl --inspect これでスタートメニュからワンクリックでreplを開けるようになった。 今気づいたけどパーミッション指定(--allow-hoge)忘れてるな…replはパーミッション指定が不要だった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

配列の中身をいじって遊んでみた!【備忘録】

こんにちは! 本日2本目の投稿です! 今朝、こちらの投稿にて、配列の要素の追加と削除を行いましたが、今回は、配列の中身をいじってみました! すでに作ってある配列の要素を全て、連結したり、逆の順番にしてみたりと、思ったより、色々なことができました! 要素を連結してみよう! まず、配列の要素を全て連結し、文字列に変えてみましょう!join()メソッドを使います。 カンマ、または指定した文字列で、区切ることができます。引数に何も指定しないと、カンマで区切られることになります。 join()メソッドの使い方は以下です。 配列.join(); let array1 = ["あ", "い", "う", "え", "お"]; let array1_2 = array1.join(); // 引数に何も指定していないので、カンマで区切られる。 let array1_3 = array1.join("-"); console.log(array1); // ["あ", "い", "う", "え", "お"] console.log(array1_2); // あ,い,う,え,お console.log(array1_3); // あ-い-う-え-お 要素を指定した要素で、置き換える(埋める)! 指定した範囲のインデックスの要素を指定した要素で置き換えてみます!fill()メソッドを使います。 引数にインデックス番号を指定しなければ、最初から最後まで全ての要素を置き換える。 置き換えられて、変更された配列そのものが返されます。 fill()メソッドの使い方は以下です。 配列.fill(置き換えたい要素, 開始インデックス, 終了インデックス); let array2 = ["A", "B", "C", "D", "E", "F", "G"]; let array2_2 = array2.fill("X"); // 引数にインデックス番号が指定されていないので、全てが置き換わる。 let array2_3 = array2.fill("O", 2, 6); // インデックス番号2〜5の要素を、"O"で置き換える。 console.log(array2_2); // ["X", "X", "X", "X", "X", "X", "X"] console.log(array2_3); // ["X", "X", "O", "O", "O", "O", "X"] 要素の順番を逆にしてみる! 最後に、配列の要素を逆の順番にしてみましょう! いちいち取り出す必要はないですよ、reverse()メソッドを使うんです! reverse()メソッドの使い方は以下です。 配列.reverse(); let array3 = ["い", "ろ", "は", "に", "ほ", "へ", "と"]; let array3_2 = array3.reverse(); console.log(array3_2); // ["と", "へ", "ほ", "に", "は", "ろ", "い"] おわりに 配列自体を操作するメソッドについて、学ぶことができました! お読みいただきありがとうございました! 私自身、まだまだ初心者なので、もし、間違いや補足などございましたら、コメントや編集リクエストなど、お願い致します! 参考資料 柳井政和著 『JavaScript[完全]入門』(2021) MDN join() MDN fill() MDN reverse()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(vue3でのつまずき) v-modelが動かず、change は2回発火される場合の対処

vue3 を触っていて、2つのつまずきがあったので解決方をまとめました。 ■つまずき1:v-modelが動かない components/AInput.vue <template> <input @input="$emit('input', $event.target.value)" @change="$emit('change', $event.target.value)" /> </template> <script> export default { name: "AInput", }; </script> このコンポーネントにv-modelでバインドする際にvue3だとうまく動かないようでした。 App.vue <template> <div class="container"> コードを入力してください。 <AInput v-model="code" @change="onChange" type="tel" /> <p>コード: {{ code }}</p> </div> </template> <script> import AInput from "./components/AInput.vue"; export default { name: "App", components: { AInput, }, data() { return { code: '', }; }, methods: { onChange(v) { console.log('changed') console.log(v) } } }; </script> ■原因 v-modelの仕様が変わった vue3 の v-modelの仕様が、v2から変わっていました。 https://v3.ja.vuejs.org/guide/migration/v-model.html 破壊的変更: カスタムコンポーネントで使用する場合に、v-model のプロパティとイベントのデフォルト名が変更されます。 プロパティ: value -> modelValue イベント: input -> update:modelValue 破壊的変更: v-bind の .sync 修飾子とコンポーネントの model オプションは削除され、v-model の引数に置き換えられます。 新規: 同じコンポーネントに複数の v-model バインディングが可能になりました。 新規: カスタムの v-model 修飾子を作成する機能が追加されました。 こちらの記事に詳しく記載を頂いていました。 ■解決法 $emit するイベントを update:modelValue に変更 記載の通り、AInput.vue の @input の $emit するイベントを update:modelValue に変更するとv-modelが動きました。 components/AInput.vue <template> <input @input="$emit('update:modelValue', $event.target.value)" @change="$emit('change', $event.target.value)" /> </template> <script> export default { name: "AInput", }; </script> ■つまずき2:changeイベントが2回発火される また同時に、changeが2回$emitされる現象が起こりました。 ■原因 vue3から $emit の仕様が変わった 下記のページとRFCを見ると、コーディングの意図を明示的にするために、$emitするイベントをwhite list化することを求める変更が行われたようでした。 ■解決法 $emit するイベントをemitsに記述 こちらのissueの回答の通り、AInput.vue の $emit するイベントを 事前に把握して export default { emits: ["update:modelValue","change"], } と記述することでchangeが2回発火されなくなりました。 components/AInput.vue <template> <input @input="$emit('update:modelValue', $event.target.value)" @change="$emit('change', $event.target.value)" /> </template> <script> export default { name: "AInput", emits: ["update:modelValue", "change"], }; </script> 以上2つのつまずきについて解決方法をまとめました。 2つ目の方は、2回イベントが$emitされるのは結構危ないので気を付けたいと思いました。 以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScript 2つの時間の差異を求めて、時差を表示する

やりたかったこと  現在時刻とユーザーが任意に入力した時刻の間の差異を求めて、00日00時間00分00秒(遅れ/早い)といった具合に時差を分かりやすく表示させたい 主に使ったメソッド .getTime 1970年1月1日00時00分から現在までの時間をミリ秒(1/1000秒)で表した数字を返すメソッド Math.floor 小数点以下を切り捨ててくれるメソッド .toString 数値を文字列に変換してくれるメソッド .padStart 数値を固定長文字列に変換するためのメソッド 記載したコード const NowTime = new Date(); const ChangeTime = new Date(timeInput.value); / ここの「timeInput.value」にはユーザーが入力した任意の時刻が挿入される仕様です let TimeDefference; function leftFillNum(num, targetLength) { return num.toString().padStart(targetLength, 0); } function timeJudge(days, hour, minute, second) { return (leftFillNum(days, 2) + '日' + leftFillNum(hour, 2) + '時間' + leftFillNum(minute, 2) + '分' + leftFillNum(second, 2) + '秒'); } if (NowTime.getTime() > ChangeTime.getTime()){ TimeDefference = NowTime.getTime() - ChangeTime.getTime() let diffDays = Math.floor(TimeDefference/1000/60/60/24); let diffHour = Math.floor(TimeDefference/1000/60/60)%24; let diffMinute = Math.floor(TimeDefference/1000/60)%60; let diffSecond = Math.floor(TimeDefference/1000)%60; TimeDefference = timeJudge(diffDays, diffHour, diffMinute, diffSecond) + "遅れ"; } else if (NowTime.getTime() < ChangeTime.getTime()){ TimeDefference = ChangeTime.getTime() - NowTime.getTime() diffDays = Math.floor(TimeDefference/1000/60/60/24); diffHour = Math.floor(TimeDefference/1000/60/60)%24; diffMinute = Math.floor(TimeDefference/1000/60)%60; diffSecond = Math.floor(TimeDefference/1000)%60; TimeDefference = timeJudge(diffDays, diffHour, diffMinute, diffSecond) + "早い"; } 冗長的なコードで、もっとDRYに記述できると思うのですが、とりあえずこれで確認したい時刻の表示を現在時刻を起点にして早い/遅いに条件分岐して表示させることができました。 以前書いた記事で、.padStartについてご教示いただき、とても参考になりました。 もっと改良して、より見やすいコードにしていこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

配列の要素を追加・削除して遊んでみた!【備忘録】

こんにちは! 今日は、配列を使って遊んでみました。 配列の処理には、色々ありますが、今回は、「要素の追加・削除」です! 要素を追加する まずは、要素を追加してみましょう。 要素を追加するのに、「配列の末尾に追加する方法」と「配列の先頭に追加する方法」の2つがあります。 1. 末尾に追加してみた! ますは、末尾に追加する方法です。push()メソッドを使います。 push()メソッドの書き方は以下です。 元の配列.push(追加したい要素); let array1 = ["わらびもち", "大福", "みたらし団子"]; let array1_2 = array1.push("柏餅"); console.log(array1); // ["わらびもち", "大福", "みたらし団子", "柏餅"] console.log(array1_2); // 4 元の配列(上の例ではarray1)の末尾には、要素が追加され、要素が追加された配列の要素数(上の例では4)を返す。 2. 先頭に追加してみた! 続いて、配列の先頭に要素を追加してみます。unshift()メソッドを使います。 unshift()メソッドの書き方は以下です。 元の配列.unshift(追加したい要素); let array2 = ["チョコレート", "源氏パイ", "パックンチョ"]; let array2_2 = array2.unshift("おせんべい"); console.log(array2); //  ["おせんべい", "チョコレート", "源氏パイ", "パックンチョ"] console.log(array2_2); // 4 きちんと、先頭に要素(おせんべい)が追加され、要素数も、4になっていますね! 要素を削除する それでは、要素を削除してみましょう。 要素を追加したときと同じく、要素を削除するのに、「配列の末尾から削除する方法」と「配列の先頭から削除する方法」の2つがあります。 末尾から削除してみた! まずは、末尾から削除してみましょう。pop()メソッドを使います。 pop()メソッドの使い方は以下です。 元の配列.pop(); let array3 = ["コーヒー", "オレンジジュース", "りんごジュース"]; let array3_2 = array3.pop(); console.log(array3); // ["コーヒー", "オレンジジュース"] console.log(array3_2); // りんごジュース 元の配列の末尾から要素を削除し、削除された要素を返します。 元の配列(上の例ではarray3)の末尾から、オレンジジュースが消えています。また、削除された、りんごジュースが返ってきていますね! 先頭から削除してみた! 続いて、先頭から、要素を削除してみましょう!shift()メソッドを使います。 shift()メソッドの使い方は以下です。 元の配列.shift(); let array4 = ["ティラミス", "ショートケーキ", "モンブラン", "ホットケーキ"]; let array4_2 = array4.shift(); console.log(array4); // ["ショートケーキ", "モンブラン", "ホットケーキ"] console.log(array4_2); // ティラミス きちんと、元の配列は先頭にあったティラミスが削除されています。削除されたティラミスも返されてきましたね! おまけ:配列にオブジェクトを要素として追加・削除できるの? 最後に、配列の要素として、オブジェクトを追加する場合、削除する場合、上で紹介した4種のメソッド(push()、pop()、unshift()、shift())を使ったら、どうなるのか、やってみました! 末尾に追加(push()メソッド) let array5 = ["マグロ", "さんま", "いか", "サーモン", "真鯛"]; let obj = {name: "いくら", price: 298}; let array5_2 = array5.push(obj); console.log(array5); //  ["マグロ", "さんま", "いか", "サーモン", "真鯛", {name: "いくら", price: 298}] console.log(array5_2); // 6 末尾から削除(pop()メソッド) let array5_3 = array5.pop(); console.log(array5); // ["マグロ", "さんま", "いか", "サーモン", "真鯛"] console.log(array5_3); // {name: "いくら", price: 298} 先頭に追加(unshift()メソッド) let array6 = ["にんじん", "レタス", "白菜", "かぼちゃ"]; let obj2 = {name: "きゅうり", price: 130}; let array6_2 = array6.unshift(obj2); console.log(array6); // [{name: "きゅうり", price: 130}, "にんじん", "レタス", "白菜", "かぼちゃ"] console.log(array6_2); // 5 先頭から削除 let array6_3 = array6.shift(); console.log(array6); // ["にんじん", "レタス", "白菜", "かぼちゃ"] console.log(array6_3); // {name: "きゅうり", price: 130} おわりに 今日は、配列の要素を追加したり、削除したりするためのメソッドを使って、遊んでみました! お読みいただき、ありがとうございました! 私自身、まだまだ初心者ですので、もし、間違いや補足などございましたら、コメントや編集リクエストを、お願い致します! 参考資料 柳井政和著 『JavaScript[完全]入門』(2021) MDN push() MDN pop() MDN unshift() MDN shift()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Denoでpuppeteerを使う (windows)

puppeteerはNode.js向けのブラウザ自動操作ライブラリですが、Denoからも使用することができます。 deno-puppeteer 作者はDenoメンテナの一人であるLuca Casonato氏です。 使い方 環境はWindows10でやっていきます。 実行方法はReadMeページに書いてある通りです。 import puppeteer from "https://deno.land/x/puppeteer@9.0.0/mod.ts"; ただし、このまま実行するとエラーが出る可能性があります。私は出ました。 error: Uncaught (in promise) Error: Could not find browser revision 869685. Run "PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@9.0.0/install.ts" to download a supported browser binary. if (missingText) throw new Error(missingText); ^ at ChromeLauncher.launch (https://deno.land/x/puppeteer@9.0.0/src/deno/Launcher.ts:99:30) このエラーが出た場合は以下の手順を実行する必要があります。と書いてあります。 環境変数PUPPETEER_PRODUCTを設定 windowsの設定(もしくはコマンドライン)から環境変数PUPPETEER_PRODUCTをchromeに設定します。 初期インストールスクリプトを実行 deno run -A --unstable https://deno.land/x/puppeteer@<バージョン番号>/install.tsをコマンドラインで実行します。 C:\Users\...>deno run -A --unstable https://deno.land/x/puppeteer@9.0.0/install.ts Download https://deno.land/x/puppeteer@9.0.0/install.ts Download https://deno.land/x/progress@v1.1.4/mod.ts Download https://deno.land/std@0.74.0/fmt/colors.ts Check https://deno.land/x/puppeteer@9.0.0/install.ts 100.00% 62.7s 174152394/174152394 Downloaded chrome 869685 to C:\Users\...\AppData\Local\deno\deno_puppeteer\chromium\win64-869685\chrome-win\chrome.exe from https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/869685/chrome-win.zip これで初期設定が完了です。~\AppData\Local\deno\deno_puppeteer以下に必要なものがインストールされます。 余談ですがdeno runで直接http://~やdata://~のスクリプトが実行できるの便利ですよね… これで、以下のようなコードが実行できるようになっているはずです。 import puppeteer from "https://deno.land/x/puppeteer@9.0.0/mod.ts"; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto("https://www.yahoo.co.jp/"); await browser.close(); 基本的なAPIはNode.js版と同じです。 top-level-awaitがデフォルトで使えるのでシンプルにかけていい感じです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】3分のカウントダウンタイマーを作成せよ。具体的な要件は以下に示す。

1・カウントは03:00からスタートする 2・スタートボタンを押すと1秒ずつカウントが進む 3・カウントが00:00になったら「Time UP!」と表示する 4・ストップボタンを押すとカウントが止まる 5・リセットボタンを押すとカウントが03:00に戻り、カウントが止まる 6・スタートを二度押しても1秒ずつカウントが進むこと。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>カウントダウンタイマー</title> <script> //001----------javascriptの開始-------------------------------------------------- window.onload = function(){ //002----------スタートボタンをクリックして発火-------------------------------------- var start = document.getElementById('start'); start.addEventListener('click',count_start, false); //003----------ストップボタンをクリックして発火-------------------------------------- var stop = document.getElementById("stop"); stop.addEventListener("click",count_stop, false); //004----------リセットボタンをクリックして発火-------------------------------------- var reset = document.getElementById("reset"); reset.addEventListener("click",count_reset,false); } //----------------------------------------------------------------------------- //変数の定義--------------------------------------------------------------------- var count = 180; //カウントダウンの数字を格納する変数 3分なので180 var min = 0; //残り時間「分」を格納する変数 var sec = 0; //残り時間「秒」を格納する変数 var start_f = false; var interval; //----------------------------------------------------------------------------- //004----------スタート開始------------------------------------------------------ function count_start(){ //0041------------二度押しを防止する if (start_f === false) { //0042------------1秒毎にcont_down関数を呼び出す interval = setInterval(count_down,1000); start_f = true; } } //----------------------------------------------------------------------------- //005------------カウントダウンの開始--------------------------------------------- function count_down(){ //006-------------------------------------------------------------------------- if(count === 1){ var display = document.getElementById("default"); display.style.color = 'red'; display.innerHTML = "TIME UP!"; clearInterval(interval); //007------------------------------------------------------------------------- } else { //008------------------------------------------------------------------------- count--; //009----------Math.floor関数を使って小数点になった分を整数に変換する。--------------- min = Math.floor(count / 60); //010------------60秒で割ったあまりが秒となる------------------------------------- sec = count % 60; var count_down = document.getElementById("default"); count_down.innerHTML = ("0"+min) +":" + ("0"+sec).slice(-2); } } //006-----------ストップボタンの押下--------------------------------------- function count_stop(){ clearInterval(interval); start_f = false; } //007-----------リセットボタンの押下--------------------------------------- function count_reset(){ clearInterval(interval); count = 180; start_f = false; var count_down = document.getElementById("default"); count_down.style.color = 'black'; count_down.innerHTML = "03:00"; } </script> </head> <body> <!-----タイマーの3分を表示------------------------------------------> <p id="default">03:00</p> <!-----スタートボタンを表示-----------------------------------------> <button id="start">スタート</button> <!-----ストップボタンを表示-----------------------------------------> <button id="stop">ストップ</button> <!-----リセットボタンを表示-----------------------------------------> <button id="reset">リセット</button> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む