質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

6218閲覧

テキストエリアに特定の文字を追加したあとに、カーソルの位置が指定できない

utoc11

総合スコア15

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/08/14 08:57

編集2019/08/15 07:51

前提・実現したいこと

Nuxt.js(Vue.js)で、ハッシュタグの数を数える簡単なシステムを作っています。

その中でワンタップで入力画面(textarea)にハッシュタグ「#」や半角スペース「 」を追加する機能を実装しようとしているのですが、一部うまく行きません。

具体的には、カーソルの位置に合わせて#を追加したら、カーソルの位置をその位置に残したいのですが、現状ではカーソルが外れるまたは一番後ろにフォーカスしてしまっています。

ハッシュタグ(#)を現在のカーソルの位置に追加して、追加したハッシュタグ(#)の後ろにカーソルを合わせたままにするにはどうすれば良いのでしょうか。

元のソースコードを踏まえても、全く別の方法でも構いませんのでご教示いただけると幸いです。

発生している問題・エラーメッセージ

コンソールにエラーは発生していません。

該当のソースコード

CSSフレームワークニVuetifyを利用しています。

Vue

1v-btn(@click="addHashtag(content)") # 2v-textarea(id="hashtag_input" ref="r" v-model="content" @input="updateValue" maxlength="500") 3 4<script> 5export default { 6 7 data () { 8 return { 9 content:'', 10 input_text:'', 11 }; 12 }, 13 14methods: { 15 // #をワンタップで追加する 16 addHashtag(content) { 17 18 var text_val = this.content 19 var all_len = text_val.length 20 var select_len = hashtag_input.selectionStart 21 var first = text_val.substr(0, select_len) 22 var insert = '#' 23 var latter = text_val.substr(select_len, all_len) 24 text_val = first + insert + latter 25 26 this.content = text_val 27 28 // 再描写してからフォーカスする(ここまではできている) 29 this.$nextTick(() => 30 this.$refs.r.focus(), 31 // フォーカスしてから再度カーソル位置を合わせたいがセレクションレンジが効かない 32 this.$refs.r.setSelectionRange(select_len+1,select_len+1), 33 ) 34 }, 35} 36</script> 37

補足情報(FW/ツールのバージョンなど)

Nuxt.js
Vuetify

###追加情報(2019/8/14 23時頃追記)

どうやら、setSelectionRangeがそもそもうまくいかないようです。

Vue

1v-btn(@click="cursorNow") テスト 2 3<script> 4 5methods: { 6 //これがダメ 7 cursorNow() { 8 this.$refs.r.focus(); 9 console.log('カーソルなう') 10 this.$refs.r.setSelectionRange(0,9999); 11 }, 12 13 //これでもダメ 14 cursorNow() { 15 this.$refs.r.focus(); 16 this.$nextTick(() => { 17 this.$refs.r.setSelectionRange(0,9999); 18 }); 19 }, 20} 21</script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

単にタイポしているだけのような気がします。

this.$refs.r.setSelectionRange(select_len+1,select_len+1)の処理が、this.$nextTick()の第2引数に入ってしまっているので実行されていないだけではないでしょうか?

以下のように書き換えてみてはどうでしょう?

js

1 this.$nextTick(() => { 2 this.$refs.r.focus(); 3 this.$refs.r.setSelectionRange(select_len + 1, select_len + 1); 4 });

2019/08/15 追記

以下にVueのプロジェクトを作って同じコードを試してみましたが、この環境だと setSelectionRange
はうまく動いてくれるようです。(Vuetifyは使っていませんが)

変更点はselect_lenをidではなく$refを使って取って来るようにしたぐらいですね。
後は、関係ないですがvarconstにしたりとか・・・

https://codesandbox.io/s/vue-template-oszsy?fontsize=14

投稿2019/08/14 10:53

編集2019/08/15 10:07
KuwabataK

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

utoc11

2019/08/14 14:23

ご回答まことにありがとうございます! 記述を変えてみたのですが、やっぱり動かなそうです。 そこでテストのボタンを用意してそもそもsetSelectionRangeが動作するのかを試したのですが、 これがうまくいっていなさそうでした。 もし可能でしたら、追記情報も見ていただけると大変助かります。
KuwabataK

2019/08/15 10:10

codesandboxにサンプルプロジェクトを作って試してみましたが、こちらの環境だとうまくいきました。もしかすると掲示されていないコード部分でなにかバグを踏んでいるのかもしれません サンプルプロジェクトへのリンクは追記したので確認してみてください
utoc11

2019/08/15 12:30

サンプルプロジェクトまで、本当にありがとうございます。 触ってみましたが、確かにしっかりと動作しますね・・・ 以下が私のGithubの該当コードなのですが、こちらで何かわかりますでしょうか・・・。 テキストエリア の入力部分の子コンポーネント https://github.com/yutoc11/hashtag-counter/blob/master/components/HashtagInput.vue 112行目:ハッシュタグ追加メソッド 質問に入れていないところだと、 32行目:@input="updateValue" で入力を監視して、 98行目以降でハッシュタグの数を数えているメソッドがあります。 https://github.com/yutoc11/hashtag-counter/blob/master/pages/index.vue 34行目でHashtagInput.vueを読み込み お手数をおかけしますが、ご確認くださいますと大変嬉しいです。
utoc11

2019/08/15 12:41

理由がわからないのですが、試しにvuetifyのテキストエリア であるv-textareaを廃止したところ、正しく動作しました・・・! ひとまずのご報告です・・・!
KuwabataK

2019/08/15 13:34 編集

チョット調べてみましたが、たぶん<v-textarea>がhtmlの標準タグである<textarea>をラップしてしまっているので、上記のコードだとsetSelectionRangeとselectionStartが参照できないのが原因っぽいですね StackOverFlowを参考にして、それぞれ以下のように書き換えると<v-textarea>のままでも動きました const select_len = this.$refs.r.selectionStart ⇓ const select_len = this.$refs.r.$el.querySelector('textarea').selectionStart this.$refs.r.setSelectionRange(select_len + 1, select_len + 1); ⇓ this.$refs.r.$el.querySelector('textarea').setSelectionRange(select_len + 1, select_len + 1) https://stackoverflow.com/questions/52333594/vuetify-how-to-make-setselectionrangeint-int-work-in-v-textarea-when-its-mo <v-textarea>の内部のDOMを参照するコードなので、<v-textarea>の実装が変わると壊れる可能性があるのであまり良くないですが・・・ まあこれやるぐらいなら自分で<textarea>をCSSで装飾するほうが安全かもしれません
utoc11

2019/08/15 13:45

ご提示いただいたコードで、正しく動作することが確認できました! 確かにそうですよね・・・! ご丁寧に本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問