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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

2459閲覧

Vue.jsで画像遅延読み込みとスムーズスクロールを両立させたい

yuixiang

総合スコア0

Vue.js

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/10/01 06:59

編集2020/10/01 07:34

前提・実現したいこと

画像遅延読み込み(v-lazy-image)を使用しているページでスムーズスクロールするページ内リンクを実装したいです。

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

Vue.jsで画像遅延読み込み(v-lazy-image)を使用しているページでスムーズスクロール(vue-scrollto)でページ内リンクを実装すると、表示しきれない画像の分ずれてしまいました。

該当のソースコード

Vue

1<template> 2 <div> 3 <atom-button 4 tag="a" 5 v-scroll-to="'#sumple1'"> 6 <p>sumple1</p> 7 </atom-button> 8 <atom-button 9 tag="a" 10 v-scroll-to="'#sumple2'"> 11 <p>sumple2</p> 12 </atom-button> 13 <atom-button 14 tag="a" 15 v-scroll-to="'#sumple3'"> 16 <p>sumple3</p> 17 </atom-button> 18 <sumple1 id="sumple1" /> 19 <sumple2 id="sumple2" /> 20 <sumple3 id="sumple3" /> 21 </div> 22</template> 23 24<script> 25import AtomButton from ~ 26import Sumple1 from ~ 27import Sumple2 from ~ 28import Sumple3 from ~ 29 30export default { 31 name: 'Sumple', 32 components: { 33 'atom-button': AtomButton, 34 'sumple1': Sumple1, 35 'sumple2': Sumple2, 36 'sumple3': Sumple3 37 } 38} 39</script>

各Sumple内に

Vue

1<figure> 2 <v-lazy-image 3 :src="require('@sumple.png')" /> 4</figure>

のようなv-lazy-imageを使用した画像があります。

[補足]AtomButtonはリンクボタンのコンポーネントです。

Vue

1<template> 2 <atom-link 3 :to="to" 4 :tag="tag" 5 class="button" 6 :class="classObject"> 7 <span> 8 <slot /> 9 </span> 10 </atom-link> 11</template> 12 13<script> 14import Link from '@/components/atoms/Link' 15export default { 16 name: 'AtomButton', 17 components: { 18 'atom-link': Link 19 }, 20 props: { 21 to: { 22 type: String, 23 default: null 24 }, 25 tag: { 26 type: String, 27 default: null 28 }, 29 classObject: { 30 type: [String, Array, Object], 31 default: null 32 } 33 } 34} 35</script>

ここで使っているコンポーネントLinkの中身は下記の通りです。

Vue

1<template> 2 <component 3 :is="element" 4 v-bind="{ [attribute]: to }"> 5 <slot /> 6 </component> 7</template> 8 9<script> 10export default { 11 name: 'Link', 12 props: { 13 to: { 14 type: String, 15 default: null 16 }, 17 tag: { 18 type: String, 19 default: null 20 } 21 }, 22 data: () => ({ 23 element: 'div', 24 attribute: null 25 }), 26 mounted () { 27 this.element = this.checkElement() 28 this.attribute = this.checkAttribute() 29 }, 30 methods: { 31 checkElement () { 32 if (this.tag) return this.tag 33 if (!this.to) return 'div' 34 if (this.to.startsWith('http')) return 'a' 35 if (this.to.startsWith('/static') || this.to.startsWith('/assets')) return 'a' 36 return 'router-link' 37 }, 38 checkAttribute () { 39 if (this.element === 'a') return 'href' 40 if (this.element === 'router-link') return 'to' 41 } 42 } 43} 44</script> 45 46<style lang="scss" scoped> 47</style> 48

試したこと

調べているとそもそも画像遅延読み込みとスムーズスクロールの相性が悪いということはなんとなくわかりました。
https://kaiteki-chokin.com/anchor-link-lazy-loading/
にたどり着き、これならいけるかなと思いましたが、
書き方が悪いのかスクロールしない普通のリンクになってしまいました。

Vue

1<template> 2 <div> 3 <atom-button 4 tag="a" 5 to="#sumple1"> 6 <p>sumple1</p> 7 </atom-button> 8 <atom-button 9 tag="a" 10 to="#sumple2"> 11 <p>sumple2</p> 12 </atom-button> 13 <atom-button 14 tag="a" 15 to="#sumple3"> 16 <p>sumple3</p> 17 </atom-button> 18 <sumple1 id="sumple1" /> 19 <sumple2 id="sumple2" /> 20 <sumple3 id="sumple3" /> 21 </div> 22</template> 23 24<script> 25import $ from 'jquery' 26import AtomButton from ~ 27import Sumple1 from ~ 28import Sumple2 from ~ 29import Sumple3 from ~ 30 31export default { 32 name: 'Sumple', 33 components: { 34 'atom-button': AtomButton, 35 'sumple1': Sumple1, 36 'sumple2': Sumple2, 37 'sumple3': Sumple3 38 }, 39 mounted: { 40 function() { 41 this.$nextTick(function () { 42 $('a[href^="#"]').click(function(e) { 43 const href = $(this).attr("href"); 44 const target = $(href == "#" || href == "" ? 'html' : href); 45 const position = target.offset().top; 46 $.when( 47 $("html, body").animate({ 48 scrollTop: position 49 }, 500, "swing"), 50 e.preventDefault(), 51 ).done(function() { 52 const diff = target.offset().top; 53 if (diff === position) { 54 } else { 55 $("html, body").animate({ 56 scrollTop: diff 57 }, 10, "swing"); 58 } 59 }); 60 }); 61 }) 62 } 63 } 64} 65</script>

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

コードの意味を理解できていないまま書いている部分もあるため、
要領を得ない質問になりすみません。
足りない情報がありましたらお申し付けください。
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

なにかVue.jsi以外で機能追加していますね?
(Vue.jsで<atom-button>タグは情報がない)
<atom-button>てなんですか?

クリックイベント自体設定できなくなっていますね
ここは

javascript

1 $('a[href^="#"]').click(function(e) { 2 const href = $(this).attr("href");

一応こうでは?
(atom-buttonが別のタグに変更になるようだが、どうなるか不明の為動作確認できません)

~~ $('a[href^="#"]').click(function(e) { ~~
~~ const href = $(this).attr("to"); ~~
実行した後のHTMLじゃないと判断つきません。
追記 変換内容

HTML

1<a href="#sumple1" class="button"><span><p>sumple1</p></span></a>

この変換が全て完了したあとに処理なのですが

Javascript

1 mounted: { 2 function() { 3 this.$nextTick(function () {

この時点で全て変換されていてthis.$nextTickは反応していますか?

素直に

Javascript

1 mounted: { 2 function () {

でタイミングがとれそうですが...

投稿2020/10/01 07:22

編集2020/10/01 08:18
kuma_kuma_

総合スコア2506

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

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

yuixiang

2020/10/01 07:42

ご回答とご指摘ありがとうございます。 <atom-button>は自作のコンポーネントなので、中身の説明が必要でした…。 追記いたしました。 上記のコードを試してみたのですが、動作変わらずでした。
kuma_kuma_

2020/10/01 07:48

> <atom-button>は自作のコンポーネント ええと<atom-button>は何かのタグに変換されているんですよね?<a>? その後に $('a[href^="#"]').click... を動かいて下さい そうすればclickイベントが設定されます。 あとこの場合変換後のHTMLを載せて下さい。(再現できなければ回答できません。)
yuixiang

2020/10/01 08:04 編集

何度もお手数おかけしてすみません。 <atom-button tag="a" to="#sumple1"> <p>sumple1</p> </atom-button> は、ページ上では <a href="#sumple1" class="button"><span><p>sumple1</p></span></a> に変換されるのですが、この回答でよかったでしょうか…? また、<atom-button>には $('a[href^="#"]').click...が効かないのであればと <a href="#sumple1">sumple1</a>でも試してみたのですが、ダメでした。
guest

0

自己解決

お返事が遅れました。

そもそも上記の状態ではjQuery自体が動いていませんでした…。
importの順番を変えることで動作しましたが、なぜ動いたかは理解できておらず…。

Vue

1import AtomButton from ~ 2import Sumple1 from ~ 3import Sumple2 from ~ 4import Sumple3 from ~ 5import $ from 'jquery'

ひとまずこれで動くようになりました。

this.$nextTick(function () {については、
リンクタグが<a href="#sumple1">sumple1</a>であれば必要ありませんでしたが、
コンポーネント<atom-button>の中身のリンクに効かせたい場合は必要でした。

kuma_kuma_様、ご回答くださりありがとうございました!

投稿2020/10/02 01:34

yuixiang

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問