JavaScript ドラックアンドドロップがうまくいかない

この記事を作った動機 drag and drop の実装について毎回いちいち調べなおしている気がするので、自分用に記録を残したいと思った。 引っかかった内容 drop イベントの受け取り方 単に、dropイベントを設定しただけでは、全く発火しない。dragoverの時点で、preventDefaultする必要があるようである。 ... acceptDropTag(){ // dragover で preventDefault しないことには機能しない this.info.addEventListener("drop",(event) => { this.dragedTagName = event.dataTransfer.getData("text/plain") if(this.dragedTagName != null){ this.setTag(this.dragedTagName) } }) // drop イベントが発火するようにする this.info.addEventListener("dragover",(event) => { event.preventDefault() }) } ... コンソールでは基本dataTransferの中身は見えないことがあるらしい dataTransferの中身は、ブラウザのコンソール内では正しく見えないようである。しかししばらくいろいろ実装を試してみたところ、すでに既存のスクリプト側でdragoverでpreventDefaultして何かしらdropイベントでdataTransferについて読み出したりしている状況において、ブラウザのコンソール側から以下のようなコードを実行してみると内容を見ることができた。 document.querySelector("#videoTable > a:nth-child(5) > div.videoInfoContainer > div.tagInfo").addEventListener("drop",(event) => {console.log(event.dataTransfer.getData("text/plain"))}) // 何かしら内容が表示される。今回はタグ名として、`drive`という文字列を送るようにしていたので、以下のようにコンソールに出てきた。 // drive <- 取得したデータとしてコンソールに出力された内容 dragenter や dragleave では、datatransfer の中身が見えない? dropイベントの発火の仕方が分からないときに、dragenterやdragleaveは発火して、その中にdataTransferの項目もイベントの引数の項目に含まれていたため、dataTransferの存在を知った当初はそれを使おうとしていた。 しかし、自分で試してみたところ、どんなにdragstartでデータを設定しても、event.dataTransfer.items[0] とか event.dataTransfer.getData("text/string") してもエラーにはならないが、空の文字列が返ってきてしまったり何も得られなかった。 document.querySelector("#videoTable > a:nth-child(4) > div.videoInfoContainer > div.tagInfo").addEventListener("dragenter",(event) => {console.log(event)}) // DragEvent {isTrusted: true, dataTransfer: DataTransfer, screenX: 2366, screenY: 676, clientX: 830, …} // temp1 // コンソールで で "Store as global variables" をする。 temp1.dataTransfer.getData("text/plain") '' drag and drop に関する内容 よく使うイベント一覧 dragstart dragover drop 基本的なこと ドラッグされる側 (event はイベントをリッスンするときの引数を意味する) draggable="true"属性を何かしらの形でHTMLタグ側に設定する。 dragstartイベントでドロップされた要素に渡したいデータを設定する。以下二つの選択肢がある。 event.dataTransfer.items.add(data,fromat) する。 event.dataTransfer.setData(format,data) する。 ドロップされる側 (event はイベントをリッスンするときの引数を意味する) dragoverでpreventDefaultして、dropイベントが発火するようにする。 dropイベントで、event.dataTransfer にアクセスしてデータを受け取る。 event.dataTransfer.items[indexNum]する。 event.dataTransfer.getData(format)する。 format 引数で指定する内容 dataTransferでデータをセットしたり読み出すには、データが何であるかタイプを指定する必要がある。ドキュメントのサンプルコードなどを見る限り、それはMIME typeを参照して文字列として指定すればいいと思われる。 ...

November 11, 2025

JavaScript でクラス内の変数にアクセスできない

この記事を作った動機 JavaScript で何度か連発して起こった問題があったので、それを記録する。 問題点 クラス内の関数を何かしらのコールバック関数として直接指定し、呼び出した場合に問題が起こる。その呼び出された関数内では、クラスに付属している変数を参照したり利用することができない。 import { tagListForIndexPage } from "./getTagInfo.js"; class sidebar{ constructor(){ new tagListForIndexPage() this.sidebarElem = document.querySelector(".sidebar") this.showAndHideButton = document.querySelector(".headMenu .headItemContainer .sidebarShowAndHide") this.currentState = "show" this.showAndHideButton.addEventListener("click",() => { if(this.currentState == "hide"){ this.show() }else{ this.hide() } }) // 問題が起こらない部分 // 問題が起こらない部分 this.clacUI() // 問題が起こらない部分 // 問題が起こらない部分 // 問題の部分 // 問題の部分 addEventListener("resize",this.clacUI) // 問題の部分 // 問題の部分 this.hide() } clacUI(){ // 直接クラス内から呼び出されたときは、this.sidebarElemは参照できるが、 // クラス外のコールバックとして”直接”この関数を呼び出すと、this.sidebarElemが参照できずにundefinedでこける。 this.sidebarElem.style.height = String(window.innerHeight - 60) + "px" } show(){ this.currentState = "show" const replacement = this.sidebarElem.getAttribute("class").replaceAll(" hide","") this.sidebarElem.setAttribute("class",replacement) } hide(){ this.currentState = "hide" let replacement = this.sidebarElem.getAttribute("class") if(!replacement.includes("hide")){ replacement += " hide" this.sidebarElem.setAttribute("class",replacement) } } } new sidebar() 解決としたこと 直接this.clacUIをaddEventListenerなどのコールバックとして呼び出すのではなく、匿名関数を一つはさんでからその内部で関数を呼び出すようにした。 ...

November 11, 2025

Date クラスで躓いたこと

この記事を作った動機 Date クラスの仕様で、引っかかった部分があるのでそのことについて記録をする。具体的には、getMonthメンバ関数を使おうとしたとき、思っているのとは違う結果になったというのがある。 内容 Date クラスの getMonth関数は、MDNに書かれているように、ゼロからスタートする値である。1月は、この関数の戻り値として、0 と表現され、12月は 11 として表現される。 The return value of getMonth() is zero-based, which is useful for indexing into arrays of months, for example: 具体的に引っかかったところ createDateStringという関数を作っていて、文字列として"YYYY/MM/DD"のような形式で今いつかということを返すようにしようとしていた時、月の部分が一つ前になっていることに気づいた。 createDateStringを実行した日を2025/10/29として、問題のあるコードと、そうでないコードの違いを以下に示す。 問題のコード 帰ってくる戻り値は、2025/9/29。 export function createDateString(){ // yyyy/mm/dd const currentDate = new Date() let dateString = "" dateString += String(currentDate.getFullYear()) + "/" dateString += String(currentDate.getMonth()) + "/" dateString += String(currentDate.getDate()) return dateString } 修正したコード 帰ってくる戻り値は、2025/10/29。 export function createDateString(){ // yyyy/mm/dd const currentDate = new Date() let dateString = "" dateString += String(currentDate.getFullYear()) + "/" dateString += String(currentDate.getMonth() + 1) + "/" dateString += String(currentDate.getDate()) return dateString } 参考にしたサイトとか Date - JavaScript | MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date (2025年10月29日)

October 29, 2025

JavaScript の条件分岐でわかりにくいミスをした

この記事を作った動機 MMD Viewer を作っているときに、地味にあとから効いてきそうなミスをすることを発見したのでそれを記録するだけ。 問題点 if 文の条件判定の書き方を間違えると、条件判定をする代わりに、判定に使った変数にブール型の結果を代入してしまう。 間違っている例 問題の部分だけ if(zipName =! null){ // <---- 問題の箇所 // これでは、zipName の中身が true になってしまう。 全体像 // try to find zip file let zipName = null zipName = findZipFile(modelFile) // try to find pmx or pmd file let modelName = null modelName = findPmxAndPmdFileName(modelFile) let fileMap = new Map() if(zipName =! null){ // <---- 問題の箇所 // set modelName is required readZipForModelFile(modelFile,zipName,fileMap) alert("zip read function on development.") return } 間違っていない例 問題を修正した部分だけ if(zipName != null){ // <---- 問題の箇所 // この場合は、通常どうり zipName の中身が null でないか判定しているということになり、zipName 自体の中身は判定前と同様に保持される。 全体像 // try to find zip file let zipName = null zipName = findZipFile(modelFile) // try to find pmx or pmd file let modelName = null modelName = findPmxAndPmdFileName(modelFile) let fileMap = new Map() if(zipName != null){ // <---- 問題の箇所 // set modelName is required readZipForModelFile(modelFile,zipName,fileMap) alert("zip read function on development.") return } 関連の記事 MMD Viewer 参考にしたサイトとか 気づいたことを書いただけなので特になし。

August 26, 2025

MMD Viewer

このページは、まだ未完成です。。。 nicotalk&キャラ素材配布所 http://www.nicotalk.com/charasozai_kt.html (2024年5月16日) ツール本体 モデルとテクスチャをまとめて指定 モーションファイルを指定(vmd) UTF-8 Shift-JIS ...

August 9, 2025