teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

もう1つ試したこととしてsetTimeoutを追加しました。

2019/10/22 00:08

投稿

退会済みユーザー
title CHANGED
File without changes
body CHANGED
@@ -1,3 +1,4 @@
1
+ 恐れ入りますが、ご教授いただければ助かります。
1
2
  imgタグを複数含む要素をjQueryベースで複製するコードを実行したところ、Firefoxでは高さが正しく取得できないことがあります。以下のようなHTMLで500×500pixelの画像を10個含むul要素を複製しています。
2
3
 
3
4
  ```HTML
@@ -25,60 +26,63 @@
25
26
  <li><img src="images/test/09.jpg"></li>
26
27
  <li><img src="images/test/10.jpg"></li>
27
28
  </ul>
29
+ <!-- 以下のjavascriptが続きます -->
30
+ ```
31
+ ```jQuery
28
32
  <script type="text/javascript" src="js/jquery-1.9.1.js"></script>
29
33
  <script type="text/javascript">
30
34
  $(document).ready(function() {
31
35
  $('button.copy').click(function() {
32
- var ul_org = $('ul.images');
36
+ var ul_src = $('ul.images');
33
- var ul_new1 = ul_org.clone().appendTo('body');
37
+ var ul_new1 = ul_src.clone().appendTo('body');
34
- var ul_new2 = $(ul_org.prop('outerHTML')).appendTo('body');
38
+ var ul_new2 = $(ul_src.prop('outerHTML')).appendTo('body');
35
39
  alert(
36
- 'ul_org.height=' + ul_org.getHeight() + '\n' +
40
+ 'ul_src.height=' + ul_src.getHeight() + '\n' +
37
41
  'ul_new1.height=' + ul_new1.getHeight() + '\n' +
38
42
  'ul_new2.height=' + ul_new2.getHeight());
39
43
  });
40
- })
44
+ });
41
- ```
42
- ```jQuery
43
- $.extend(true, $.prototype, {
45
+ $.extend(true, $.prototype, {
44
46
  getHeight: function() {
45
- return this.height();
47
+ return this.height();
46
48
  }
47
- });
49
+ });
48
50
  ```
49
- 以下は成功した時です。
51
+ 以下は成功した時です。※時々、成功します。
50
52
  ![成功](7c996c38662d843d5c808ee5b99066b7.jpeg)
51
53
 
52
- 以下は失敗した時です。
54
+ 以下は失敗した時です。※大抵、失敗します。
53
55
  ![イメージ説明](a1136397a89b37c32973427cb8ebb1eb.jpeg)
54
56
 
55
- Chromeでは問題が起きないのですが、おそらく画像のキャッシュが働いているせいかと思います。
57
+ Chromeでは問題が起きないのですが、それはおそらく画像のキャッシュが働いているせいかと思います。
56
58
  ![イメージ説明](c7766179e9b2f39642c73d4c4ccfdd85.jpeg)
57
59
 
58
- Firefoxでは要素を複製する時に、img.src先をロードする処理が走り、そのタイムラグがあるだと思いますが、ロードが完了するまで待つ良い方法が思いつきません。
60
+ Firefoxでは要素を複製する時に、img.src先をロードする処理が走り、そのタイムラグがあるせいだと思っていますが、ロードが完了するまで待つ良い方法がわかりません。
59
- 以下のコードを入れて試してみたのですが、「too much recursion」(再帰呼び出しオーバー)となってしまいます。
61
+ 以下のコードに変えて試してみたのですが、「too much recursion」(再帰呼び出しオーバー)となってしまいます。
60
62
  ```jQuery
61
- $.extend(true, $.prototype, {
63
+ $.extend(true, $.prototype, {
62
64
  getHeight: function() {
63
- var imgNum = this.find('img').length;
65
+ var imgNum = this.find('img').length;
64
- var imgLoad = 0;
66
+ var imgLoad = 0;
65
- var callback = this.getHeight.bind(this);
67
+ var callback = this.getHeight.bind(this);
66
- while (imgLoad < imgNum) {
68
+ while (imgLoad < imgNum) {
67
- this.find('img').each(function() {
69
+ this.find('img').each(function() {
68
- if (this.complete || /* for IE */ $(this).height > 0) {
70
+ if (this.complete || /* for IE */ $(this).height > 0) {
69
- imgLoad++;
71
+ imgLoad++;
70
- }
72
+ }
71
- });
73
+ });
72
- if (imgLoad == imgNum) {
74
+ if (imgLoad == imgNum) {
73
- break;
75
+ break;
74
- }
75
- this.find('img').one('load', function() {
76
- callback();
77
- }).load();
78
76
  }
77
+ this.find('img').one('load', function() {
78
+ callback();
79
+ }).load();
80
+ // もしくは、setTimeoutで少し待ってみる
81
+ //setTimeout(callback, 100);
82
+ }
79
- return this.height();
83
+ return this.height();
80
84
  }
81
- });
85
+ });
82
86
  ```
83
87
 
84
88
  どのようにすれば、画像のロード完了を待った後に、要素の高さを取得することができるでしょうか?