IE8 アクティブタブの取得方法と非同期リクエストのタイミング

このQ&Aのポイント
  • WIN8.1のIE11でIE8をエミュレートして開発しています。現在IEウィンドウタブのアクティブ/非アクティブ状態を取得したいと思います。タブブラウザで複数のページを表示して切り替えた場合に、仕込んだイベントが発生する予定ですが、同一ウィンドウ内でのフォーカス移動でもonblurが発生しています。
  • アクティブタブの取得方法や、タイミングのイベントの取得方法を教えてください。
  • 最終目標は、カレントのタブのみ非同期リクエストを行い、非アクティブ時には内部フラグのみ更新し、アクティブになった瞬間に非同期リクエストの処理を呼び出すことです。
回答を見る
  • ベストアンサー

IE8 アクティブタブの取得

------------------------------------------------------ WIN8.1の IE11で、IE8をエミュレートして開発しています。 ------------------------------------------------------ 現在IEウィンドウタブのアクティブ/非アクティブ状態を取得したいと思い、以下のようにイベントに関数を仕込んでいます。 ----------------------------- window.onfocus = function () { focusChg(true); } window.onblur = function () { focusChg(false); } function focusChg(flg) { document.title = (flg) ? "あ" : "い"; document.title += formatDate(new Date(), 'hh:mm:ss.SSS'); } ※補足 function formatDate() は日時の書式を整える関数 ----------------------------- ※タブブラウザですので、タブで複数のページを表示した場合(パターン1) 「タブページA ⇔ タブページB」と切り替えた場合 ※または(パターン2) 「タブページA ⇔ エクスプローラ等の別アプリケーション」へ切り替えた場合 に、仕込みのイベントが発生する予定でした。 ところが ページ内には「input/a/div」等が存在していいるのですが、 そのページ内のinput等にフォーカスを当てると、その親windowのonblurが発生しています。 同一WIndowのhtml→body→form→input へのフォーカス移動では、onblurが発生しない想定で考えていたので、困ってしまいました。 どなたかアクティブタブの取得方法や、またその切替を行ったタイミングのイベントの取得方法を教えてください。 最終目標は、、、 5分おきにDBへの問い合わせを行う非同期リクエストを、タブがカレントの時だけ行いたい。 またアクティブではない時に5分のタイミングがやってきた場合は、内部フラグだけを立てておき、アクティブになった瞬間に問い合わせを行う非同期リクエストの処理を呼び出したい。 という事をしようとしております。 非同期リクエストは出来ておりますが、これらの呼び出すタイミングがうまくいかないような状態です。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • think49
  • ベストアンサー率59% (285/482)
回答No.1

blur は DOM L2 Events ではバブルしないイベントですが、IE8 ではバブルしているんですかね…。 http://www.y-adagio.com/public/standards/tr_dom2_events/events.html#Events-eventgroupings-htmlevents-h3 event.srcElement の値はどうなっていますか? event.srcElement の値から処理を分岐できませんか? # Re: 1050YENさん

1050YEN
質問者

お礼

think49さん 早速の回答、ありがとうございます。 window.onfocus/window.onblur 共にevent.srcElementはnullを返すようですね。。。 しかし回答から 全Elementに対してのonfocus/onblurイベントを、jQueryを利用したセレクタ指定のハンドリングするとかしか方法がないのかな? と方法を思いつきました。 が、、、 あまりやりたくない方法ではあります。。。 でもそれしかない??? うーん、、、 悩ましいところです。

その他の回答 (3)

  • think49
  • ベストアンサー率59% (285/482)
回答No.4

#1,2,3 です。 > windowのonfocus/onblurのイベントでは、fromElementもtoElementもやはり値が入ってないようですね。 そうでしたか。 となると、私にはスマートな解決策を思いつきません。お力にならず、申し訳ありません。 > //* @remarks:イベント関連付け停止 ご存知ならいいのですが、event.preventDefault(); はデフォルトアクションの抑止、event.stopPropagation(); はバブリングの停止であり、両者は別物です。 デフォルトアクションの抑止の為に両コードをまとめて指定する方をたまに見かけるので念のため。 > 全てのElementにイベントを個々にレガシーなJavaScriptで仕込みを入れるのは、メンテナンス面からも現実的ではないため、イベントハンドラの登録はjQueryが好ましいように思いますがいかがでしょう? 余計なものを入れないシンプルなコードで検証した方がいいので先程は jQuery を推奨しませんでしたが、実際の運用で jQuery を使うのは問題ないと思います。 # Re: 1050YENさん

1050YEN
質問者

お礼

think49さん 毎度、ありがとうございます。m(_ _)m >私にはスマートな解決策を思いつきません。お力にならず、申し訳ありません。 いえいえ!全くそんな事無いです。 質問をする事で、「ズバッとの答え」をいただくだけが回答だと思っておりません。 またこちらで調査していた事と同様の回答を得られた場合にあっても、結果としてそれは 「逆にそれしか方法がない」 という事になると思います。 ですので ----------------------------------------------- think49さんが「解決策を思いつきません」と発言し →→【それにレスが付かない事】 ----------------------------------------------- がある意味その状態が回答なんだと思います。 それと補足でいただいた「イベント関連付け停止」については、すいません。Common系のjsソースのコピペの範囲を誤り、デッドコードの部分まで張り付けてしまったようです。 使っていない関数ですのでご安心を(^^;) ありがとうございました。

  • think49
  • ベストアンサー率59% (285/482)
回答No.3

#1,2 です。 event.srcElement が使えなかったとしても、event.fromElement, event.toElement 辺りは使えないでしょうか。 jQuery を使っているようですが、jQuery は event オブジェクトを独自操作していはずなので素の JavaScript で試してみて下さい。 --- function handleBlur (event) { var target = event.target || event.srcElement; console.log(event.type); console.log(target); console.log(event.fromElement); console.log(event.toElement); } function handleFocus (event) { var target = event.target || event.srcElement; console.log(event.type); console.log(target); console.log(event.fromElement); console.log(event.toElement); } attachEvent('onfocus', handleFocus); attachEvent('onblur', handleBlur); ---

1050YEN
質問者

お礼

think49さん 幾度もの回答、ありがとうございます。m(_ _)m #2の補足前にお礼で書いたはずの内容が、、、 どうやら「確認」後の「確定」をせずにブラウザを閉じてしまったようです。 すいません。ここにその内容も継ぎ足して書きます。 #1のサンプル実行や質問前には、よく巷にあるブラウザ対応を考慮した関数を用意してあるので、それに準拠したハンドラ登録を行っています。 勿論IE8の時は「attachEvent」を必然的に利用するようになっています。 質問で書いてある通り、当方の環境はIE11を利用したIE8のエミュレートですので、以下のようなイベントレジスタ関数を利用する手法を取っています。 ----------------------- //* //* @name :addEvent //* @remarks:イベント関連付け設定 //* var addEvent = (document.addEventListener) ? function (elem, type, listener) { elem.addEventListener(type, listener, false); } : function (elem, type, listener) { elem.attachEvent("on" + type, listener); }; //* //* @name :stopEvent //* @remarks:イベント関連付け停止 //* var stopEvent = function (event) { if (event.stopPropagation) { event.stopPropagation(); event.preventDefault(); } else { event.returnValue = false; event.cancelBubble = true; } return false; }; //* //* @name :removeEvent //* @remarks:イベント関連付け解除 //* var removeEvent = (document.addEventListener) ? function (elem, type, listener) { elem.removeEventListener(type, listener, false); } : function (elem, type, listener) { elem.detachEvent("on" + type, listener); }; ----------------------- #2の補足で書いた内容は、#2までにいただいた内容を確認して、通常のJavaScriptで試した内容をお伝えしております。 さらに#3で書いてある内容を試しました。 windowのonfocus/onblurのイベントでは、fromElementもtoElementもやはり値が入ってないようですね。 折角何度も回答をいただいておりますが、、、 ブラウザ内のElementにフォーカスが移動すると、やはりWindowのblurが起動してしまい、現在アクティブWindowかどうかの判定は、この手法では厳しいように思います。 全てのElementにイベントを個々にレガシーなJavaScriptで仕込みを入れるのは、メンテナンス面からも現実的ではないため、イベントハンドラの登録はjQueryが好ましいように思いますがいかがでしょう?

  • think49
  • ベストアンサー率59% (285/482)
回答No.2

#1 です。 確認ですが、attachEvent を使用している前提で合っているでしょうか。 (質問文にあるコード window.onblur では第一引数で event オブジェクトを取れなかったと記憶しているので、念のため) --- function handleBlur (event) { console.log(event.srcElement); } function handleFocus (event) { console.log(event.srcElement); } function init () { attachEvent('onblur', handleBlur); attachEvent('onfocus', handleFocus); } --- 上記コードでも対応できないなら、label, input, select, textarea, button, *[tabindex] な要素をフックして判定させるぐらいしか思いつきません。 # Re: 1050YENさん

1050YEN
質問者

補足

ググってみると 「visibilitychangeイベント」 というのを知りました。 https://developer.mozilla.org/ja/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API https://w3g.jp/blog/ie_supportlist (最初からもっと調べてから質問しろという突っ込みは無しで^^;) IE10から対応になっていいうようですね。。。 ってことは、、、 それ以下のブラウザでは、先ほどお伝えした泥臭いやり方しか無いという事だと判断しました。 ↓このような感じ $("*").blur(ハンドラ); $("*").focus(ハンドラ); で、とりあえずは作成していきます。 こちらが「早とちりで決断している」という薄い期待を込めて、もう少し締め切らないで待ってみたいと思います。

関連するQ&A

  • 開いたタブ(ウィンドウ)にフォーカスが当たらない

    IE8 をタブモードで利用したとき、新しく開いた タブ(ウィンドウ)にフォーカスが当たりません。 JavaScript の window.open で別タブ(ウィンドウ)を 表示する処理を onload イベントで行うと、新しい タブ(ウィンドウ)にフォーカスがあたりません。 button のクリックイベントで表示した場合は、 新しいタブ(ウィンドウ)にフォーカスが当たります。 やりたいことは submit してページを再表示するときに 新しいタブ(ウィンドウ)を表示して、そちらにフォー カスを設定することです。 また、できればブラウザのバージョンによって処理を 切り替えるようなことはしたくありません。 何か原因や解決策などありましたらご教授ください。 よろしくお願いします。 <この現象が発生する環境> IE8 と IE7 で下記のように設定した場合 ツール → インターネットオプション → 全般タブ  → タブ → 設定  → ポップアップの発生時  の設定を   「常に新しいタブでポップアップを開く」  にする。 ※IE9 ではこの現象は発生せず、新しいタブ(ウィンドウ)に  フォーカスがあたります。 ※IE7, 8 でもタブモードではなく、別ウィンドウで開く  設定になっている場合は、新しいウィンドウにフォーカスが  あたります。 <サンプルソースと説明> (説明) test1.html から window.open で test2.html を表示します。 onload で表示したときは test2.html のタブ(ウィンドウ)に フォーカスがあたりません。 button のクリックイベントで表示したときは test2.html の タブ(ウィンドウ)にフォーカスがあたります。 ---(test1.html)---------------------------------- <html> <head runat="server"> <title></title> <script language="javascript" type="text/javascript"> window.onload = function () { OpenWindowTest(); } function OpenWindowTest() { var TestWin = window.open('test2.html'); TestWin.document.focus(); } </script> </head> <body> <form> <div> <input type="button" value="button" onclick="OpenWindowTest();" /> <br /> <input type="submit" value="submit" /> </div> </form> </body> </html> --------------------------------------------------- ---(test2.html)---------------------------------- <html> <body onload="window.focus();"> テストページ </body> </html> ---------------------------------------------------

  • window.openしたウィンドウのwindow.onblurについて

    window.openしたウィンドウのonloadに  window.onblur = function() { window.close(); } を設定しているのですがFirefox3.6、Opera10.51ではウィンドウからフォーカスが外れたらウィンドウが閉じるのですが(期待している動き通り)、 IE6のみwindow.openしたウィンドウをクリックしたと同時にウィンドウが閉じてしまいます。 どうすればIEでもFirefox,Operaと同じ動きをさせることが出来ますでしょうか・・・

  • イベント発生順序

    いつもお世話になっています。 JavaScriptの発生順序を制御する方法はありますでしょうか? 例えば、あるテキストボックスがあって、 A1→B2とフォーカスが移るときのイベントですが、 B2.onFocus→A2.onBlurの順番でイベントが発生していますが、これを A2.onBlur→B2.onFocusとしたいです。 IE限定でいいので、よろしくお願いします。

  • フォーカス移動抑止について

    お世話になっております。 ブラウザの画面項目(テキストボックス等)間でフォーカスを移動する場合、移動元でonblur、移動先でonfocusが発生しますが、移動元のonblurで、特定の条件の場合だけフォーカス移動を抑止し、移動先onfocusを発生させないようにしたいのですが、何か方法はないでしょうか? 【環境】 ・IE6 【現在うまくいっていない方法】 現在、フォーカス移動を抑止するため、移動元のonblur内の処理で、「event.srcElement.focus()」を実行してますが、移動先のonfocus()も走ってしまう。(2回フォーカス移動することで元の画面項目にフォーカスが戻る) 【補足】 ・問題になっているのは、画面項目のonblur、onfocusで入力値のチェックや他画面項目との連動、色変更、エラーメッセージ表示等を行っておりonblurやonfocusが何度も走ってしまうと想定外の動きをしてしまいます。(場合によってはフォーカス移動の無限ループ) ・グローバル変数を屈指すれば想定外の動きをしないようにすることはできるかと思いますが、それ以外の方法で制御したい。 【現在うまくいっていない方法の動作確認用のとりあえず作ったサンプルプログラム】 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>フォーカス遷移抑止検証</title> <script type="text/javascript"> var iEventCount = 0; function onElemBlur() { if (++iEventCount > 10) return true;// 無限ループ抑止用 debug("blur : " + event.srcElement.value); event.srcElement.focus(); } function onElemFocus() { if (++iEventCount > 10) return true;// 無限ループ抑止用 debug("focus : " + event.srcElement.value); } function debug(msg) { var obElem = document.getElementById("debugmsg"); obElem.innerHTML += msg + "<br/>"; } </script> </head> <body> <input type="text" value="hoge1" onblur="onElemBlur()" onfocus="onElemFocus()" /> <br/> <input type="text" value="hoge2" onblur="onElemBlur()" onfocus="onElemFocus()" /> <br/> <br/> <br/> <span id="debugmsg" rows="10" cols="50" ></span> <br/> </body> </html> 長々と申し訳ありません。 よろしくお願いいたします。

  • OnBlurとIE7での非互換解消方法について

    初心者ですが、申し訳ありません。 IE6では動作していたものがIE7で動作しない様になり、困窮しています。 親画面からポップアップでWindowをオープンさせ、そのWindowを必ず使わせるために、最前面に置こうとしています。  <BODY bgcolor="#FFFFFF" onBlur="window.focus()> このWindowの中ではテキストボックスが用意されており、その中から項目を選択して、同じWindowにあるボタンを押すと親画面に戻る様にしています。 IE6ではこれが動作をしますが、IE7になるとボタンが押せずに親画面に戻れません。しかし、もう一度選択するとボタンが効くようになりました。ところが再度選択するとまた効かなくなるというものです。 これを解消したいのですが、良策をご教示いただけませんでしょうか。 代替のscriptのヒントなどでも頂戴できればと思います。宜しくお願いいたします。

  • タブコントロールについて

    お世話になっております VB.NET 2010 Windows7 Windowsフォーム画面の開発をしています タブコントロールについてです 現在、タブページを使用しており、1ページ目で検索、2ページ目に検索結果一覧、3ページ目で詳細が見れるようになっています 1ページ目に検索条件を入れ2ページ目のタブを押すと、入力ミスがあったら2ページ目に遷移せずに入力ミスしたコントロールの場所にフォーカスが飛び、正常なら検索され2ページ目に遷移します ここで質問なのですが、今現在TabControl.Selection イベントに入力チェック、検索処理を書いています 入力チェックでミスがあった場合にタブページを移動しないこと、1ページから2ページ遷移で検索処理を起こすため、次のタブページを検知しなければいけないからです ですが、入力ミスが起こった際、フォーカスが入力ミスした項目に飛びません 1ページ目の最初の項目に飛んでしまいます おそらく、タブページ移動(2ページ目に飛ぶ)→入力ミスでフォーカス移動→タブページ移動キャンセル(2ページ目から1ページ目に飛ぶことでタブコントロールにフォーカス移動)→タブページの次の項目 となっていると思われます DeSelectingイベントに入れると、入力ミスした際にエラーのある項目に飛ぶのですが、そうすると2ページ目に移動しようとしたのか、3ページ目に移動しようとしたのかが分からなくなってしまいます 押したタブページが検知でき、なおかつキャンセルされたときにフォーカスが移動できるような方法ありますでしょうか よろしくお願いします

  • IEのイベントでのウインドウ位置の取得

    以前に、MdNの「リンクにマウスオーバーするとポップアップで説明が表示される」というサンプルの記述がうまく動作しないという質問で、FairefoxやSafariではその回答でうまく動作するようなのですが、IEの動作がまだ駄目なようなのです。 IEのイベントが発生した時のマウス座標の取得は、Javascriptで、 function OnScreenHelp(x,y){ if(document.all) { /* IEでの処理 */ document.getElementById(strID).style.left = event.x + document.body.scrollLeft + 15; document.getElementById(strID).style.top = event.y + document.body.scrollTop + 0; }else{             /* IE以外の処理 */ document.getElementById(strID).style.left = x + 15 + "px"; document.getElementById(strID).style.top = y + 0 + "px"; } } のような記述になっているのですが、関数OnScreenHelp(x,y)のx,yがbodyの本文内で、event.pageX、event.pageYのようにNN系の記述になっているため、IEではこのx,yの値は使えないので上記のような記述になっているようなのです。上記の記述ではうまくポップアップしてくれないので、 event.xやevent.yの所の記述がまずいのかな?と思って、ちょっと調べてみて、window.event.offsetXやwindow.event.offsetYに変更してやってみたのですが、うまくいきません。ここの所の、IEの記述としては、どのように記述したらよいか分かりかねています。ご経験のある方、ご教示願えたらと思います。 よろしくお願い致します。

  • 開いているWindowの高さと幅を取得したい

    現在開いているページのWindowの高さと幅を取得したいのですが window.outerHeightなどはIEでは使えないようです。 IEではWindowの高さと幅を取得する方法はないのでしょうか。

  • フォーカスを持っているコントロールを取得する方法はありますか?

    こんにちは。 JavaScriptで、イベントを使用せずに、任意のタイミングで現在フォーカスをもっているコントロールを取得することはできないでしょうか? プロパティでフォーカスされているかどうかを示すBool値を返すのとかはないですか?? どうぞ教えてください。

  • 子ウィンドウの情報を取得したい

    window.openを複数行い、各ウィンドウの情報を取得したいのですが 配列変数などで管理せずwindowなどで取得は可能でしょうか? 試しに作成したソースです --ココカラ(oya.html)-- <html> <head> <script type="text/javascript"> <!-- //この方法で取得ができるが var koList = new Array(); function openKoA(){ kowin = window.open("ko.html", "kowin" + koList.length); koList.push(kowin); } function koListA(){ for(i in koList){alert(koList[i].document.getElementById("t1").value);} } // 配列で管理せずにwindow等にある情報で取得したい function openKoB(){ window.open("ko.html"); } function koListB(){ alert("子供リストなど"); //window.childNodes とか } --> </script> </head> <body> <input type="button" value="openKoA" onclick="openKoA()"> <input type="button" value="koListA" onclick="koListA()"> <br> <input type="button" value="openKoB" onclick="openKoB()"> <input type="button" value="koListB" onclick="koListB()"> </body> </html> --ココマデ(oya.html)-- --ココカラ(ko.html)-- <html> <body> <input type="text" id="t1" value="aa"> </body> </html> --ココマデ(ko.html)-- 以上、よろしくお願いします。

専門家に質問してみよう