メニューボタン、タイムスタンプ
https://gyazo.com/c195e73d43622068abbb5837797bfb47
メニューボタン、タイムスタンプ
code:script.js
scrapbox.PopupMenu.addButton({
title: 'timestamp',
onClick: text => {
const now = new Date();
const date = now.toLocaleDateString('sv-SE');
const time = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
const formattedTimestamp = [${date}] ${time};
text = formattedTimestamp;
return text;
}
})
要望
いつもページ下部でつけてるタイムスタンプだが、モバイルでは手書き
なので、ボタンにして手間を減らしたいのである
欠点
2行以上選択しないと項目が出ない
モバイルで最も使用したいなので一操作で打ちたい
モバイルで使えるようにボタン化したい
ボタンの追加
code:style.css
button#Timestamp.tool-btn:hover { text-decoration: none }
button#Timestamp.tool-btn::before { position: absolute; content: '\f017'; font: 800 22px/46px 'Font Awesome 5 Free' }
button#Timestamp.tool-btn img { opacity: 0 }
https://gyazo.com/d60924bf61e8a018df9f1c0595eb7cbf
高さが合わないのが謎cFQ2f7LRuLYP.icontakker.icon
ボタン内の処理
code:script.js
const TimestampTitle = 'Timestamp'
scrapbox.PageMenu.addMenu({
title: TimestampTitle,
//これでボタンの追加ができた
image: '/assets/img/logo.png',
onClick: text => {
ここtextにしているのはダメで、今回やりたいのは「サイドのボタン」を「押す」と「記事を書いている白い部分」に「タイムスタンプ」が「書かれる」ことcFQ2f7LRuLYP.icon
code:script.js
const now = new Date();
const date = now.toLocaleDateString('sv-SE');
const time = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
const formattedTimestamp = [${date}] ${time};
text = formattedTimestamp;
return text;
onClickと同じ理由でダメcFQ2f7LRuLYP.icon
文字入力を自分で実装する必要があるtakker.icon
助かります!!!cFQ2f7LRuLYP.icon
今回のケースだとボタンをクリックした際にカーソルが消えてしまう?cFQ2f7LRuLYP.icon
やってみよ
内部でfocus()を実行しているので、消えても入力されますtakker.icon
混乱しそうな互換性処理を削除takker.icon
それ以外は手を加えてません
WIPcFQ2f7LRuLYP.icon
azamasucFQ2f7LRuLYP.icon
code:script.js
}
})
takker.iconさん修正1
code:script.js
const TimestampTitle = 'Timestamp'
scrapbox.PageMenu.addMenu({
title: TimestampTitle,
//これでボタンの追加ができた
image: '/assets/img/logo.png',
onClick: text => {
export function insertText(text) {
const cursor = document.getElementById("text-input");
cursor.focus();
cursor.value = text
const event = new InputEvent("input", { bubbles: true });
cursor.dispatchEvent(event);
const now = new Date();
const date = now.toLocaleDateString('sv-SE');
const time = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
const formattedTimestamp = [${date}] ${time};
text = formattedTimestamp;
return text;
}
}
})
そのまんま入れてみたところなぜか横のボタンが消えた。困ったぜcFQ2f7LRuLYP.icon
https://gyazo.com/2626e09827b69dc669f73e6660e39b4f
あーごめん、同等の処理をここに貼り付ければよいが曖昧でしたtakker.icon
❌そのままコピペ
✅今回の処理に使えるように記述を変更して取り込む
タイムスタンプの入力に関係ない寄り道を避けたい場合は壊れてる部分を修正しますが、寄り道含めて自力で解決したい(学習優先)場合は見守るだけにしておきます
後者でがんばります!cFQ2f7LRuLYP.icon
それはそれとして、このコードでボタンが消えるはずがないのだが……あ、構文エラー発見takker.icon
探してみよう
}!cFQ2f7LRuLYP.icon
修正1を改修する
export を消した
ら、横のボタンが戻った。やったね
https://gyazo.com/68bb0ed88110c5e86272cd63f55d0f00
別にexport する必要ないしな……cFQ2f7LRuLYP.icon
処理の順番として
1. 最初にタイムスタンプの処理をする。入力したいテキストを生成する
2. 1で作ったテキストをカーソルを…介し…スクラップボックスに…書く
レファレンス
takker.iconさんが追加した場所で行われている処理について
GPT-4.icon
このコードは insertText という関数を定義し、その中で特定のテキスト入力フィールドに対して操作を行っています。一行ずつ解説します。
関数の定義:
code:javascript
export function insertText(text) {
insertText という名前の関数を定義し、外部のファイルからこの関数を利用できるように export キーワードを使用しています。この関数は text という引数を取ります。
今回だと外部ファイルから関数を利用する必要は(現状)ないcFQ2f7LRuLYP.icon
テキストフィールドの選択:
code:javascript
const cursor = document.getElementById("text-input");
HTMLドキュメントからIDが "text-input" である要素(この場合はテキスト入力フィールド)を取得し、それを cursor という変数に格納します。 このテキスト入力フィールドという箇所をがそうであることを確認するために何を使えばよいか?(自問)cFQ2f7LRuLYP.icon フォーカスの設定:
code:javascript
cursor.focus();
取得したテキスト入力フィールドにフォーカス(カーソルの位置を設定)を当てます。これにより、ユーザーが次に入力するテキストはこのフィールドに入力されるようになります。
テキストの挿入:
code:javascript
cursor.value = text;
テキストフィールドの value プロパティ(フィールド内のテキスト)を引数 text の値に設定します。これにより、フィールドに新しいテキストが挿入されます。
イベントの作成:
code:javascript
const event = new InputEvent("input", { bubbles: true });
新しい InputEvent オブジェクトを作成します。このイベントは "input" タイプのもので、bubbles: true オプションにより、イベントがDOMツリーをバブリング(上方に伝播)することを許可しています。
イベントの発行:
code:javascript
cursor.dispatchEvent(event);
最後に、作成した InputEvent をテキストフィールドに対して発行(ディスパッチ)します。これにより、プログラムによるテキストの変更が発生したことがブラウザやその他のリスナーに通知され、通常のユーザー入力のように扱われます。
全体として、この関数は指定されたテキストフィールドにテキストを挿入し、その変更をブラウザに通知することを目的としています。これにより、ページの他の部分がこの変更を適切に処理できるようになります。
ステップ実行がグレーアウトしているのはなぜだ?
https://gyazo.com/862e6ce313bdca09f6fb48d66a95767a
デベロッパーツールを見ることは出来たが、ここで問題のスクリプトを動かす方法が現在不明(開発環境構築)
insertText()の詳細は掘らないでいいですtakker.icon
scrapboxの内部処理に関わっていて、コード内容も2割方実験的に書いたもの
これで動くとわかるまで1年以上かかってます
短く説明すると<textarea>に入力命令を飛ばしています
scrapboxのエディタ構造にあわせているので、ほかのwebサイトでは動作しません
insertText("hello")を実行するとカーソル位置にhelloが入力されることだけわかっていればOKです
再開
他の方法でJavascriptをテストする方法はあるか?
GPT-4.icon
JavaScriptの構文エラーを確認するためには、いくつかの方法があります。主に以下の環境を利用できます。
ブラウザの開発者ツール: ほとんどのモダンブラウザには、JavaScriptのコードを実行しデバッグするための開発者ツールが組み込まれています。コンソールタブでJavaScriptコードを実行し、構文エラーや実行時エラーを確認できます。
これがうまくいっていない
オンラインのJavaScriptエディタ: JSFiddleやCodePenのようなオンラインエディタは、リアルタイムでコードを書き、実行結果を確認できる環境を提供します。これらのツールは構文エラーをハイライト表示する機能も備えています。 使えた
統合開発環境 (IDE): Visual Studio CodeやWebStormのようなIDEを使用すると、構文エラーをリアルタイムで検出し、修正を支援する機能を活用できます。
Node.js: サーバーサイドのJavaScript環境であるNode.jsを使うと、コンソールから直接JavaScriptコードを実行し、エラーを確認できます。
どの方法を選ぶかは、あなたのニーズや利用シーンによって異なりますが、これらは一般的に使われる主要なオプションです。
HTML、CSS、JavaScriptのそれぞれをこの環境に合わせる必要がある?
この簡単なテストのために改変する腕前が今の私にはない
ポモドーロの時が過ぎゆく……
scrapboxというobjectはscrapbox.ioのサイトにしか生えてないので、ほかのサイトで動かしても動作しませんtakker.icon
scrapboxを起動すると、assets/index.jsがwindow.scrapboxを生成し、scrapbox.ioのUIスレッドのどこからでもscrapboxにアクセスできるようになる で、UserScriptをテストする方法は、残念ながらscript.jsを書き換えてreloadを繰り返すしかありませんtakker.icon
有志がこれを解決するすばらしいツールを作ってくれることに期待しましょう
ただし、部分的にテストすることは可能です
静的解析
コードを実行せずにチェックするやつ
構文チェック
}抜けなど、文法がミスってないかチェックするやつ
javascript 構文チェッカーとかで調べると出てくるはず
linter
構文に加え、お行儀のわるい書き方を指摘してくれる
型チェック
数値型に文字列を入れているとか、存在しないプロパティにアクセスしているとかを検出する
単体テスト
関数やクラスごとに、実行時に正常な値を吐いているかどうか調べるやつ
今回のミスはlinterを走らせるか単体テストを組むと検出できる
ただいずれも現状のcFQ2f7LRuLYP.iconさんには敷居が高いと思う
まだ見ぬ強敵、または先の街で手に入る装備感cFQ2f7LRuLYP.icon
読み返して思ったけど、ここ外野が勝手にcFQ2f7LRuLYP.iconさんの限界を規定している感じがして気持ち悪いtakker.icon
敷居が高い根拠がない
もしかしたら簡単かもしれない
実際限界に近そうcFQ2f7LRuLYP.icon
今回だと「このスクリプトを動かす」というのが目標なので、環境構築ルートに行くのは回り道
手作業で問題点を洗い出す方が早いかも