JavaScriptで任意の要素の座標取得/要素移動/スクロールIT系おじさんのチラシの裏2018年10月~プロフィールAUTHOR:とっちら書きたくなったときに書きたいことを書く雑記ブログ。IT系のネタが多いかも知れません。11:57とっちら1年前の記事に助けられました。14:28とっちらこの記事のお陰で60分録画できるようになりました。16:01とっちらライセンスを明示して貰えると使いやすいのですが。14:37ご回答いただきどうもありがとうございます。21:56とっちら超初心者です。)「JavaScriptでのページ内スクロールとDOCTYPE宣言でハマった話」の続きみたいなものですが、今回はページ最上部/最下部へのスクロールではなく、任意の要素位置へのスクロールについてサンプルを交えて語ってみたいと思います。要素の座標取得やスクロール方法について解説する前に、なぜそんなことが必要になるのか、について軽く触れます。wikiのコメント欄などで見られるラジオボックスを使った例wikiのコメント欄などで見られるラジオボックスを使った例wikiのコメント欄などで見られるラジオボックスを使った例ゲーム系の攻略wikiを利用したことがある方なら見慣れたUIだと思いますが、ページ最下部にコメント欄が配置されており、そのコメントへのコメント(いわゆるリプライ)をする際に、ラジオボタンで返信先を選択してからコメントを書くようなUIです。本来、wikiでページ内にコメントを付ける場合、ほんの一言二言だったり、最新のコメントに対する返信をする程度なので、このUIでもあまり不便は感じないかも知れませんが、質問掲示板や雑談掲示板などを実装する際、このコメントシステムをそのまま採用してしまって使いづらくなっているケースがあります。質問掲示板などの場合、文章量が多くなる傾向がありますし、いくつかレスが進んだ後に、過去のコメントにリプライするとなると、返信先とコメント欄が離れていて使いづらいと感じることはないでしょうか?■具体例wikiのコメント欄などで見られるラジオボックスを使った例こんなふうに途中に文章量が多いコメントがあると前の文章を読みながら返信するのが難しいwikiのコメント欄などで見られるラジオボックスを使った例この場合、一番上のコメントを読みながらコメント欄に文字を入力するのはかなりしんどいと思います。PCで表示している場合、上の例は大げさに思えるかも知れませんがPC/スマホ両対応のHPが当たり前の昨今、PCでは問題なかったUIもスマホだと文章がたくさん折り返されて使いづらくなってしまうケースが増えています。動的にテキストボックスを移動してしまおう実行例ここをクリックすると直下にテキストボックスが現れますここをクリックすると直下にテキストボックスが現れますこんなふうに途中に文章量が多いコメントがあってもテキストボックスが返信先の位置に現れるので問題ないここをクリックすると直下にテキストボックスが現れますここをクリックすると直下にテキストボックスが現れますどうでしょう。このUIなら文章を読みながらの返信もやりやすいのではないでしょうか。テキストボックスを任意の要素(この例ではLI要素)の下に移動するにはappendChildを使うだけなのですが、縦長になってしまい、コメント欄が画面外に表示されてしまった場合を想定すると、要素位置へのスクロールも必要となってきます。style="width:1em;">こんなふうに途中に文章量が多いコメントがあってもテキストボックスが返信先の位置に現れるので問題ない</p></li><li>ここをクリックすると直下にテキストボックスが現れます</li><li>ここをクリックすると直下にテキストボックスが現れます</li></ul>リストはUL/LIで書き、LI要素の好きな位置にDIV要素(id="bbs_reply")で囲んだテキストエリアを配置しています。{width:100%;}</style>CSSではコメント欄を角丸で囲ったり、クリックできるとわかるようにマウスカーソルをpointerにしたり、と見た目をいじっているだけで動作関係(hover等)のギミックは使っていません。要素で、罫線(┗)を描いているくらいですかね。::beforeは疑似要素で、その要素の直前に何かを挿入したり装飾するのに使います。この例ではテキストエリアの手前に線を描画したかったので追加していますが、わざわざDIVで囲っているのはTEXTAREAやINPUT等の入力パーツには疑似要素を付けられないため、です。{event.stopPropagation();});});</script>どうでしょう。短くないですか?テキストエリアの位置変更に至っては↓コレだけです。onclickイベントを追加そのイベント内ではid=bbs_replyの要素を、クリックされたLI要素の下に移動(appendChild)テキストエリアのクリック時にLI要素のイベントまで発火してしまうため、event.stopPropagation();でイベントを止める基本コレだけでテキストエリアの移動という目標は達成しているのですが、クリック時にテキストエリアが画面外にあった場合、ページに変化が現れないのでユーザーにはわかりづらいですよね?返信しようと思ったのにページでは何も起こらない.........ように見える。画面外だった場合はテキストエリアのあたりまでスクロールwindow.scrollByの部分という処理を追加した感じです。注意点としては、getBoundingClientRectで取得できる座標はページ内の絶対座標ではなく相対座標である点。(=現在のスクロール位置からの座標)そして前回の「JavaScriptでのページ内スクロールとDOCTYPE宣言でハマった話」で書いたとおり、documentElement.clientHeightはブラウザで現在見えている範囲内の高さなので、この値よりもrect.topが大きければ入力欄が画面外にあるな、と判断できます。windows.scrollToを使ってスクロール........................でも良かったのですが、scrollToは絶対座標指定のため、相対座標を絶対座標へ変換してやる必要があります。これが面倒...というわけでもないのですが、window.pageYOffsetを足すだけだし...座標の取得も、位置の把握も相対座標で計算しているのだから、スクロールの移動量も相対指定で良くね?と思い、scrollByのほうを使っています。rect.height);テキストエリアのY座標(rect.top)から、現在ブラウザで表示している高さを引けばテキストエリアの上辺のY座標が取得できます。そこにテキストエリアの高さ(rect.height)を加算したのが相対スクロール量、というわけです。実際に使ってみるとページ最下部にぴったりテキストエリアが来るのはやや窮屈に感じるため、スクロール量を+100~200くらいしてテキストエリアの位置を少しばかり持ち上げると入力しやすいです。まとめ前回の「JavaScriptでのページ内スクロールとDOCTYPE宣言でハマった話」に引き続き、今度は任意の要素の座標を取得して、その位置へスクロールする例を取り上げてみました。毎度思うんですが、いちいち長い説明書かんでもソース見ればわかるよね...。前回のDOCTYPEの例のように、サンプルコードをコピペしても動かん!などとハマってしまったとき、もしかしたら、も~し~か~し~た~ら~、万に一つでも長たらしい説明文が役に立つかも知れない、と考えるとついつい文章量が多くなってしまいます。今回は掲示板のようなツリー形式がわかりやすいかなーと思って例題に出しましたが、実際ぼくが使うのはECサイトの管理画面などで商品分類別のツリーを表示し、任意の位置に新しい商品を挿入するようなUIですね。書いたとおり、ツリー形式での一覧性の良さを求められるケースは多く、入力作業の効率化を求められた場合、今回のような動的な要素移動と共にUIに組み込むこともあります。それでは、今回は以上ですが、ここに書いたコードや解説がどこかの誰かのお役に立てたなら幸いです。いつもどおり、ソースコードは(大したものじゃないので...)お好きにお使いください。関連記事JavaScriptでファイル名順に複数ファイルを読み込む方法INPUTタグで複数ファイルを読み込む際、ブラウザ内で処理するときはFileReaderオブジェクトを使うことが多いと思います。これは非同期処理なので、はてファイル名順に処理する場合はど02024-06-13JavaScriptのcanvasで縦書きを行う際の備忘録canvas上に縦書きの文章を出力して画像化しようと考えてちょっとハマったので忘れないうちにメモしておきます。結論から先に書くと、基本的にcanvasにはwriting-modeの設定が効くの02024-06-11JavaScriptのWebAudioAPIで楽曲の口パクをしてみる以前、ソフトウェアの解説動画を作った際、おっさんの声だけ流れてるのもアレだし、最近流行りのアバターにしゃべらせるやつやってみよう、と思ったことがあります。vtuberとかおじさんよくわからない02023-11-20jQuery不要なLightbox代替スクリプトLuminousが本当に軽量jQueryって...重いですよね。各種ブラウザへの対応が面倒くさかった時代には本当にありがたかったのですが、モダンブラウザ全盛の今、jQueryの必要性を感じないことが多くなってきました。前回の記事「JavaScriptで画像を連続表示してコマ撮りムービー風の表示をしてみる」では連続して画像を表示することで、コマ撮りムービーのようなものをブラウザ上に表示することに成功しました。82023-01-24Amazonアソシエイトのレポート作成とダウンロードを自動化するAmazonのアフィリエイトプログラムを使っている方ならわかってもらえると思いますが、Amazonアソシエイトページのレポート画面ってすっっっっっごく使いづらいですよね。コメント投稿直後ならコメントの編集/削除が可能です。※24時間経過するか、新しく投稿した場合は古い投稿の編集や削除は出来ません。※ブラウザでCookieが受け入れられない場合はこの機能は使えません。非公開にチェックを入れたコメントは管理人のみ閲覧できます。コメント投稿のガイドライン誰もが閲覧できるコメント欄ですので個人が特定できる情報等は書き込まないようにしましょう。他人のHPやブログの文章を掲載する場合は著作権法第32条「引用」の条件を満たすかご確認ください。誹謗中傷にあたる表現などは場合によっては法的な責任を問われる可能性があるためご注意ください。とっちらか~るTOP。