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

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

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

KnockoutJSは、Model-ViewView-Model(MVVM)を用いたダイナミックなHTML ULのためのオープンソースのJavaScriptライブラリです。

JavaScript

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

3回答

3557閲覧

setTimeout()で一瞬だけ文字を表示したい

hinata_t

総合スコア8

Knockout.js

KnockoutJSは、Model-ViewView-Model(MVVM)を用いたダイナミックなHTML ULのためのオープンソースのJavaScriptライブラリです。

JavaScript

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2018/09/04 14:42

前提・実現したいこと

Knockout.jsを使用して、サイトを作っています。
一瞬だけ文字を表示する機能を作成したいのですが、
EdgeやFirefoxで表示されないときがあります。
Chromeでは問題なく表示できます。

該当のソースコード

HTML

1<div class="hide" deta-bind="css:{'hide': !visible()}"> 2 <span>hoge</span> 3</div> 4 5<style> 6 .hide { 7 display:none; 8 } 9</style>

JavaScript

1this.visible(true); // 表示!! 2setTimeout(function () { 3 _this.visible(false); // 非表示!! 4}, 1);

質問

  1. ブラウザやバージョンによって、

display:noneが適用されなくなる(hogeが表示される)までの時間に差があるのでしょうか?
※表示しようとしたときに、時間が来て「非表示」の処理が走っているのではないかと予想しています。

  1. EdgeやFirefoxでも、hogeを確実に表示することは可能でしょうか?

※ただし、表示する時間は0.001秒としたい。

上記ご教示いただけると助かります。
よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

Knockout.js 日本語ドキュメント
"visible" バインディングによると、
HTMLのstyle属性でdisplay: noneを設定しているだけらしいので同期的な処理に思われます。

GitHubのリポジトリに全ソースコードが上がってるようなので、落として全文検索していけば見つかると思います。


表示する時間は0.001秒としたい。

パソコンやディスプレイ、人間の構造上のスペックの問題で不可能です。
結論はsetTimeoutじゃなくてrequestAnimationFrame使えなんですがその理由を説明していきます。

そもそも0.001秒という数字が出る時点で、今から解説する内容は一部既知であっても何故関係あるかの紐づけまで至ってないと思うので、根本から解説していきます。

まず機械の話をしていきます。
映像を表示するのは光ですが、映画館の映写機のようなもので似たような画像を1秒間に何十回もの間隔でカシャカシャ切り替えて実現しています。
機械版のパラパラ漫画ですね。
パソコンのディスプレイの主流は液晶ディスプレイですが、映写機と同じく「即興のフィルムを作ってカシャカシャ切り替える」事を実現する為の装置です。

このカシャカシャは一般的にフレームと呼ばれ、カシャカシャタイミングがフレームレートと呼ばれています。
格闘ゲームの波動拳は全体40フレーム(40f/60秒=0.67秒)みたいな感じで親しまれています。

このフレームレートですが、一般的にテレビ放送は秒間30フレーム、ゲームやパソコン等の能動的な操作を伴うものは秒間60フレームがベースになります。
秒間60フレームのルールは多くの場所で採用されており、例えば多くの液晶ディスプレイのリフレッシュレート(更新間隔)は60Hz(秒間60回書き換え)ですし、
Chromeを始めとする多くのブラウザのフレームレートは60FPS(秒間60回書き換え)です。

この秒間60回書き換えをミリ秒に換算すると、16.67msのタイミングで1度書き換える計算となります。
つまり、0.001秒という一瞬だけ表示させようとした場合、液晶ディスプレイやChromeの画面更新間隔は約0.017秒ですので、16/17の確率で何も表示されないことになります。

また、JavaScriptのsetTimeoutの仕様の問題もあります。
そもそもイベントとして登録された関数は条件を満たした時にフラグが立つだけで、実際に実行されるのは次回のイベントループで回ってきたタイミングであり、若干のタイムラグが発生します。
setTimeoutに関してもブラウザ毎に最小値が異なるようで、10ms以下を設定しても意味が無いケースが多いようです。

また、人間の一瞬に関しても定義が必要です。
人間の脳はアスリートクラスでも認知するまでに0.1秒が必要で、そこから行動速度で競う形になります。
参考サイト: https://games.yahoo.co.jp/qa/detail?qid=13115770323

従って、0.001秒にこだわる必要は一切なく、100msくらい表示してから逃げれば人の脳は目にも止まらない一瞬の速度で消えたと判断することでしょう。
フレーム数でいえば6〜7Fで、その程度を目安にしてやれば十分といえます。

とはいえ、0.001秒としたと言うことは出来るだけ小さい時間だけ表示させたいという技術的挑戦だと思いますので、
requestAnimationFrameを紹介して締めます。
Chromeなどのブラウザは約60FPSで駆動しているらしいのですが、常にではなく負荷を検知して勝手に30FPSに落としたり、バックグラウンド動作させた場合は勝手に1FPSに落としたりするようです。
つまり、何時画面が更新するかは誰にもわかりません。

JSはゲームやアニメーションにも使われる言語ですから、画面の更新タイミングがわからずアニメーションがカクカクしては意味がないわけですね。
その問題への回答としてrequestAnimationFrameが用意されています。
Chromeの画面更新が終わったと同時にこれで登録したイベントが確実に発火しますので、
次の更新までに終わるような処理を組み込む事で確実に等間隔で描画することが可能です。
1フレーム目で削除する事で最速で消すという事も実現出来るでしょう。

投稿2018/09/04 22:55

miyabi-sun

総合スコア21158

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

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

hinata_t

2018/09/05 13:52 編集

丁寧な回答、ありがとうございました。m(_ _)m 結局、1ミリ秒ではなく、もっと長い秒数で実装することにしましたが、 機会があれば、requestAnimationFrameについても勉強してみたいと思います。
ikadzuchi

2018/09/05 16:14

requestAnimationFrameを使っても1フレームの描画はできませんよ。 ブラウザの描画が負荷で30FPSになったりするのは何を使っても変わりません。
miyabi-sun

2018/09/06 03:38

30FPSになっても1フレームは1フレームかつ、最小の単位だと思いますが、 Chromeが30FPSに制限しているのに、16.7msだけ表示する事が可能であるという指摘でしょうか?
ikadzuchi

2018/09/06 12:50

> 30FPSになっても1フレームは1フレーム なるほどそういう意味でしたか。1フレームというのはディスプレイにおけるフレームのことを指して言っているのかと思った次第です。
guest

0

[1について]
タイマーの最小解像度の問題で、多少の差はでるようです。
JavaScriptの1msは4ms(Qiita)

また、当然ですが、ブラウザやOSが過剰に処理を抱えている場合はsetTimeout の処理は後回しにされるかもしれません。

そもそも、最小の時間単位だとモニタのリフレッシュレートの関係で描画される間もなく……ということはよくあると思います。

そのほか、あなたの体調次第では、視認できないレベルの短さに見えます。

[2について]
おそらく1/1000秒で確実に描画する方法はないと思います。というかそんなの描画されていても視認すできないのでは……?

投稿2018/09/04 15:02

R.Mizukami

総合スコア1077

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

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

0

※ただし、表示する時間は0.001秒としたい。

普通のOSとブラウザ環境では無理です。そもそも、モニターのリフレッシュレート(画面更新タイミング)自体が60Hzとか120Hzなので、1ミリ秒単位で表示を切り替えることができません。

投稿2018/09/04 22:06

maisumakun

総合スコア145121

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問