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

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

新規登録して質問してみよう
ただいま回答率
86.12%
JavaScript

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

解決済

javascriptでthisが効かなくて困っています

suzu1234
suzu1234

総合スコア39

JavaScript

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

3回答

0グッド

1クリップ

332閲覧

投稿2022/10/06 14:48

前提

”青いボタンにマウスを乗せた時に画像を拡大する” という動作を実装したいと考えています。現状のコードではボタンにマウスを載せて画像を拡大するところまではできたのですが、1つのボタンにマウスを乗せると3つある画像がすべて拡大してしまいます。

thisを使えば自分が乗せたボタンのみ拡大できるという事は分かったのですが、”ボタンにマウスを載せて画像を拡大”という動作の関係で画像にaddeeventlistenerが使えずthisの使いどころが分からず困っています。

該当のソースコード

<div class="sectionContainer"> <div class="imgParent"> <img class="img" id="img1" src="http://presnt.jp/img/top/24.jpg" alt=""> </div> <div class="scrollBtn"> <a href="#" class="scrollBtnBefore"></a> <a href="#" class="scrollBtnAfter"></a> </div> </div> <div class="sectionContainer"> <div class="imgParent"> <img class="img" id="img2" src="http://presnt.jp/img/top/23.jpg" alt=""> </div> <div class="scrollBtn"> <a href="#" class="scrollBtnBefore"></a> <a href="#" class="scrollBtnAfter"></a> </div> </div> <div class="sectionContainer"> <div class="imgParent"> <img class="img" id="img3" src="http://presnt.jp/img/top/21.jpg" alt=""> </div> <div class="scrollBtn"> <a href="#" class="scrollBtnBefore"></a> <a href="#" class="scrollBtnAfter"></a> </div> </div>
.sectionContainer { margin: 0 auto 50px auto; width: 950px; max-width: 100%; position: relative; } .imgParent { margin: 0 auto; overflow: hidden; width: 100%; position: relative; } .img { width: 100%; transition: all 1.3s ease 0s; } .img:hover { transform: scale(1.05, 1.05); } .scrollBtn { display: flex; position: absolute; bottom: 0; right: -63px; } .scrollBtnBefore, .scrollBtnAfter { display: block; height: 53px; width: 63px; background-color: #0000CD; }
const btns = document.getElementsByClassName('scrollBtn'); for (let i = 0; i < btns.length; i++) { const imgs = document.getElementsByClassName('img'); btns[i].addEventListener('mouseover', () => { for (let i = 0; i < imgs.length; i++) { imgs[i].style.transform = "scale(1.05, 1.05)"; } }); btns[i].addEventListener('mouseout', () => { for (let i = 0; i < imgs.length; i++) { imgs[i].style.transform = "scale(1, 1)"; } }); }

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

3

ベストアンサー

「ホバーしたボタンの親の子孫の class="img"」を操作すればよいでしょう。

ボタンの情報はイベントオブジェクトから取れるので、実のところ this を使う必要はありません。以下のような感じです。

js

1 btns[i].addEventListener('mouseover', event => { 2 const img = event.target.closest('.sectionContainer').querySelector('.img'); 3 img.style.transform = "scale(1.05, 1.05)"; 4 });

投稿2022/10/06 15:07

int32_t

総合スコア17085

miyabi_takatsuk, m.ts10806👍を押しています
._.😍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

ボタンにカスタムデータ属性を付与し、その値と同じid名をもつimgを拡大縮小する方法はいかがでしょうか?

  • <div class="scrollBtn" data-scale-img="img1"> ←これをクリックしたら
    • data-scale-img="img1"なので、
  • <img class="img" id="img1" src="http://presnt.jp/img/top/24.jpg" alt="">  ←idがimg1の画像を対象とする

また、mouseoverとmouseoutの時の処理内容がほぼ同じなので、1つの関数でどちらも対応できるようifで分岐させてみました。

コード例

html

1<div class="sectionContainer"> 2 <div class="imgParent"> 3 <img class="img" id="img1" src="http://presnt.jp/img/top/24.jpg" alt=""> 4 </div> 5 6 <!-- データ属性に対象の画像のid名をかく --> 7 <div class="scrollBtn" data-scale-img="img1"> 8 <a href="#" class="scrollBtnBefore"></a> 9 <a href="#" class="scrollBtnAfter"></a> 10 </div> 11</div> 12 13<div class="sectionContainer"> 14 <div class="imgParent"> 15 <img class="img" id="img2" src="http://presnt.jp/img/top/23.jpg" alt=""> 16 </div> 17 18 <!-- データ属性に対象の画像のid名をかく --> 19 <div class="scrollBtn" data-scale-img="img2"> 20 <a href="#" class="scrollBtnBefore"></a> 21 <a href="#" class="scrollBtnAfter"></a> 22 </div> 23</div> 24 25<div class="sectionContainer"> 26 <div class="imgParent"> 27 <img class="img" id="img3" src="http://presnt.jp/img/top/21.jpg" alt=""> 28 </div> 29 30 <!-- データ属性に対象の画像のid名をかく --> 31 <div class="scrollBtn" data-scale-img="img3"> 32 <a href="#" class="scrollBtnBefore"></a> 33 <a href="#" class="scrollBtnAfter"></a> 34 </div> 35</div>

javascript

1// ボタン要素を取得 2const btns = document.getElementsByClassName('scrollBtn'); 3 4// それぞれのボタンにホバー時とホバー解除時のイベントを設定 5[...btns].forEach(btn => { 6 btn.addEventListener('mouseover', changeScale); 7 btn.addEventListener('mouseout', changeScale); 8 } 9); 10 11// 画像を拡大・元のサイズに戻す関数 12function changeScale(e) { 13 const eventType = e.type; // 発生したイベントの種類が、mouseover か mouseoutか取得 14 const targetId = e.currentTarget.dataset.scaleImg; // 対象ボタンのデータ属性の値を取得=画像のid名と同じ 15 const targetImg = document.getElementById(targetId); // 対象の画像をidで取得 16 17 if (eventType === 'mouseover') { // mouseoverイベントの時実行 18 targetImg.style.transform = 'scale(1.05, 1.05)'; 19 } else if(eventType === 'mouseout') { // mouseoutイベントの時実行 20 targetImg.style.transform = 'scale(1, 1)'; 21 } 22}

thisじゃなくて…

ちなみに、addEventListener(イベントの種類, コールバック関数)でイベントが発生した要素を取得する方法はthisではありません。

例)

html

1<div class="btn"><a href="#">button 1</a></div> 2<div class="btn"><a href="#">button 2</a></div> 3<div class="btn"><a href="#">button 3</a></div>

javascript

1const btns = document.getElementsByClassName('btn'); 2[...btns].forEach(btn => btn.addEventListener('click', whichElement)); 3 4function whichElement(event) { 5 // イベント情報 6 console.log(event); // PointerEvent{...} 7 8 // イベントの発生した要素 9 console.log(event.target); // <a href="#">button 1</a>など 10 11 // イベントが登録されている要素 12 console.log(event.currentTarget); // <div class="btn"><a href="#">button 1</a></div>など 13} 14

addEventListener()でイベントが発生すると、呼び出されたコールバック関数の引数には、自動的に発生したイベント情報が渡されます。
ですのでコールバック関数の引数の中には分かりやすくするためfunction myFunction(e)とかfunction myFunction(event)などと書かれます。

  • eventで、発生したイベント情報を全て取得でき、
  • event.targetで、eventの情報の中にある、イベントが発生した実際の要素を取得でき、
  • event.currentTargetで、eventの情報の中にある、発生したイベントを登録しておいた要素が取得できます。

投稿2022/10/06 15:26

編集2022/10/06 16:04
Cocode

総合スコア2098

m.ts10806👏を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Cocode

2022/10/06 16:04

コードを修正しました。

0

回答ではないですが、ご参考までに。
CSS の :has()を使えば、CSSのみで実装可能です。
下記を追加するだけです。

css

1.imgParent:has(+ .scrollBtn:hover) .img { 2 transform: scale(1.05, 1.05); 3}

:has() - CSS: カスケーディングスタイルシート | MDN

ただし、現在のところ Firefox は非対応です。

HTMLを変更してもいいのなら、下記のようにscrollBtnを前に移動させて、

HTML

1<div class="sectionContainer"> 2 <div class="scrollBtn"> 3 <a href="#" class="scrollBtnBefore"></a> 4 <a href="#" class="scrollBtnAfter"></a> 5 </div> 6 <div class="imgParent"> 7 <img class="img" id="img1" src="http://presnt.jp/img/top/24.jpg" alt=""> 8 </div> 9</div>

下記のCSSを追加します。

css

1.scrollBtn:hover + .imgParent .img { 2 transform: scale(1.05, 1.05); 3} 4.scrollBtn { 5 z-index: 1; 6}

これなら Firefoxでも動作します。

投稿2022/10/07 02:27

hatena19

総合スコア32001

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

JavaScript

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