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

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

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

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

jQuery

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

Q&A

解決済

2回答

14282閲覧

jsで、任意のタイミングで「1度だけ」処理を実行したい

uroboros

総合スコア20

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2016/08/17 12:27

###スクロール時に、任意の要素が画面内に入ってきた時に「1度だけ」処理を実行したい

  1. スクロールする
  2. 任意の要素が画面内に入っているか確認する
  3. 入っていれば処理を行い、以降は処理を行わない

※jquery の one() のようなイメージです。

javascript(jquery)にて、上記のようなことを実現したいのですが、
下記のコードでは、スクロールするたびに処理が発生してしまいます。

###該当のソースコード

javascript

1 $(window).scroll(function(){ 2 var scrollTop = $(window).scrollTop(); 3 4 $('.hoge').each(function() { 5 var top = $(this).offset().top; 6 if(scrollTop > top){ 7 console.log('once!'); // 一度だけ実行させたい処理 8 } 9 }); 10 11 });

###試したこと
そこで実行済みであることを保存する変数を試してみましたが、うまく動かず。。。
やり方もスマートでない気がします。

javascript

1 $(window).scroll(function(){ 2 var scrollTop = $(window).scrollTop(); 3 4 $('.hoge').each(function() { 5 var top = $(this).offset().top; 6 var used = false; 7 if(scrollTop > top && used === false){ 8 console.log('once!'); 9 used = true; 10 } 11 }); 12 13 });

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

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

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

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

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

guest

回答2

0

変数usedを外側のスコープに置いてやればいいんじゃないでしょうか。

コードをシンプルにするために、空配列を宣言し、配列の範囲外にアクセスした時、undefined(falsy)を返すという性質を利用します。

JavaScript

1$(window).on("scroll", function(eve){ 2 var usedList = this; 3 var scrollTop = $(eve.currentTarget).scrollTop(); 4 5 $('.hoge') 6 .filter(function(i, e){ 7 var top = $(e).offset().top; 8 return (scrollTop > top); 9 }) 10 .filter(function(i, e){ 11 if(usedList[i]) return false; 12 return (usedList[i] = true); 13 }) 14 .each(function(i, e){ 15 // 以下に一度だけ実行させたい処理を書く 16 }); 17}.bind([])); // thisを空配列に束縛する(IE8以前への対応が必要など、気に入らなければ素直にクロージャ作ってください)

投稿2016/08/17 13:53

編集2016/08/17 15:28
gaogao_9

総合スコア103

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

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

uroboros

2016/08/17 15:14

ありがとうございます! 実装してみたのですが、動かず。。。 通常のスクロールでは何も起こらず、 スクロールした状態でページリロードすると、スクロールで過ぎた .hoge 要素の数だけ、処理が実行されるという挙動です。。。 空要素とfilterの使い方、目からウロコで勉強になりました。
gaogao_9

2016/08/17 15:28

これは…失礼しました。 既にベストアンサーは決まっていますが、後から読む人のために一応コードの方を修正しておきました。
uroboros

2016/08/18 09:16

ありがとうございます! こちらも動作しました。
guest

0

ベストアンサー

現在書かれているやり方では used が常に false になります。「実行済みであることを保存する」のであればこういうやり方でどうでしょう。

JavaScript

1$( window ).scroll( function() { 2 var scrollTop = $( window ).scrollTop(); 3 $( '.hoge' ).each( function() { 4 var top = $( this ).offset().top; 5 var used = $( this ).prop( 'used' ); 6 if ( scrollTop > top && used === false ) { 7 console.log( 'once!' ); 8 $( this ).prop( 'used', true ); 9 } 10 } ); 11} ); // 未テスト

追記:

こっちのほうが良いかも。

JavaScript

1$( window ).scroll( function() { 2 var scrollTop = $( window ).scrollTop(); 3 $( '.hoge:not(.fire)' ).each( function() { 4 var top = $( this ).offset().top; 5 if ( scrollTop > top ) { 6 console.log( 'once!' ); 7 $( this ).addClass( 'fire' ); 8 } 9 } ); 10} ); // 未テスト

投稿2016/08/17 13:04

編集2016/08/17 13:09
kei344

総合スコア69400

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

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

uroboros

2016/08/17 15:10

ありがとうございます! こちら期待した動きができました! クラスで管理、思いつきませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問