「ぼかし」イベントが発生したときに、どの要素フォーカスが*に*移動したかを知るにはどうすればよいですか?


187

次のblurように、HTML入力ボックスに関数をアタッチするとします。

<input id="myInput" onblur="function() { ... }"></input>

blur関数内でイベントを発生させた要素(クリックされた要素)のIDを取得する方法はありますか?どうやって?

たとえば、次のようなスパンがあるとします。

<span id="mySpan">Hello World</span>

入力要素にフォーカスがある直後にスパンをクリックすると、入力要素のフォーカスが失われます。関数はどのようにそれがそうであったことを知っていますかmySpanがクリックれたですか?

PS:スパンのonclickイベントが入力要素のonblurイベントの前に発生する場合、特定の要素がクリックされたことを示すステータス値を設定できるため、問題は解決されます。

PPS:この問題の背景は、AJAXオートコンプリートコントロールを外部で(クリック可能な要素から)トリガーblurして、入力要素のイベントのために提案がすぐに消えることなく、その提案を表示したいということです。したがって、blur特定の要素が1つクリックされたかどうかを関数にチェックインし、そうであれば、ぼかしイベントを無視します。


これは、私が推論したい興味深い質問です。つまり、なぜこれをしているのですか?コンテキストとは何ですか?
Rahul

Rahulとroosteronacid、私はあなたのコメント(PPS)への反応として質問を更新しました。
Michiel Borkent、2008

1
この情報は少し古いですとして、新しい答えをここに参照してください。stackoverflow.com/questions/7096120/...
ジョナサン・M

回答:


86

うーん... Firefoxでは、explicitOriginalTargetクリックした要素をプルするために使用できます。toElementIEでも同じことを期待していましたが、動作しないようです...ただし、新しくフォーカスした要素をドキュメントからプルすることができます。

function showBlur(ev)
{
   var target = ev.explicitOriginalTarget||document.activeElement;
   document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
}

...

<button id="btn1" onblur="showBlur(event)">Button 1</button>
<button id="btn2" onblur="showBlur(event)">Button 2</button>
<button id="btn3" onblur="showBlur(event)">Button 3</button>
<input id="focused" type="text" disabled="disabled" />

警告:この技術はないではないフォーカスのための仕事はによって引き起こさ変更タブ移動キーボードでフィールドを、とChromeやSafariですべての仕事をしません。使用しての大きな問題activeElement(IE以外では)それは一貫まで更新されないことです後にblurイベントが処理されており、処理中に全く有効な値を持つことはできません!これは、Michielが最終的に使用た手法のバリエーションで軽減できます。

function showBlur(ev)
{
  // Use timeout to delay examination of activeElement until after blur/focus 
  // events have been processed.
  setTimeout(function()
  {
    var target = document.activeElement;
    document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
  }, 1);
}

これは、ほとんどの最近のブラウザー(Chrome、IE、Firefoxでテスト済み)で機能するはずですが、Chromeではクリックされた(タブではなく)ボタンにフォーカスが設定されないことに注意してください。


1
私は、explicitOriginalTargetのようなものを長い間探していました。どのようにしてそれを発見しましたか?
Kev

3
FireBugのイベントオブジェクトを調べました。FWIW、プロパティはMozilla固有であり、MDCに文書化されています:developer.mozilla.org/en/DOM/event.explicitOriginalTarget
Shog9

2
これは、Firefox 3.6およびWindowsのSafari 4.0.3では機能しません(または機能しなくなりましたか?)。
Chetan S 2010

1
@ジョナサン:プロパティは使用可能ですが、blurイベントが発生しても更新されません。回答を詳細に更新しました。ChromeまたはFirefoxでこれにactiveElementを使用してみましたか?それはぼやけている要素をあなたに与えます...
Shog9 '17

1
FF 31では実際には機能しません。explicitOriginalTargetは現在のぼかしターゲットを表示し、blurイベントではdocument.activeElementがnullになります。
Adrian Maire、2014

75

2015年の回答UIイベントによるとrelatedTarget、イベントのプロパティを使用できます。

EventTargetイベントのタイプに応じて、フォーカスイベントに関連するセカンダリを識別するために使用されます。

blurイベントについては、

relatedTarget:フォーカスを受け取るイベントターゲット

例:

function blurListener(event) {
  event.target.className = 'blurred';
  if(event.relatedTarget)
    event.relatedTarget.className = 'focused';
}
[].forEach.call(document.querySelectorAll('input'), function(el) {
  el.addEventListener('blur', blurListener, false);
});
.blurred { background: orange }
.focused { background: lime }
<p>Blurred elements will become orange.</p>
<p>Focused elements should become lime.</p>
<input /><input /><input />

FirefoxはrelatedTargetバージョン48までサポートしません(バグ962251MDN)。


Firefoxはサポートしていませんが、チケットがあります:bugzilla.mozilla.org/show_bug.cgi
id

3
今ではあります。こちらをご覧ください
rplaurindo 16

ウェブコミュニティを愛し、今ではすべてがはるかに簡単になりました^ _ ^
am05mhz 2017年

6
素晴らしいソリューション。残念ながら、フォーカスを受け取るターゲットが入力要素でない場合はrelatedTargetが返されnullます。
Pedro Hoehl Carvalho 2017

5
受信フォーカス要素が入力要素ではない場合、それにtabIndex="0"属性を追加すると機能します
Dany

19

私は最終的にonblurイベントのタイムアウトでそれを解決しました(StackOverflowではない友人のアドバイスに感謝します):

<input id="myInput" onblur="setTimeout(function() {alert(clickSrc);},200);"></input>
<span onclick="clickSrc='mySpan';" id="mySpan">Hello World</span>

FFとIEの両方で動作します。


9
これはJavaScriptの世界では悪い習慣と考えられていますか?
Michiel Borkent、2008

1
古い投稿ですが、同じ質問があります。とにかく、それはクロスブラウザーで仕事を成し遂げたように見える唯一のものです。
joshs 2010年

この回答は、他の問題を解決することで私のTONを助けました...マイケルに感謝します!
アレックス

@MichielBorkentイベント駆動型ではないため、これは不適切な実装です。あなたは一定の時間待って、それが十分な長さであることを願っています。安全に待つ時間が長ければ長いほど、待ち時間を長くする必要がなかったとしたら、無駄になる時間も多くなります。たぶん、誰かが本当に古い/遅いデバイスを使用していて、このタイムアウトでは十分ではないかもしれません。残念ながら、FireFoxでiframeがクリックされているかどうかを判断するために必要なイベントがイベントから提供されていないため、ここにいますが、他のすべてのブラウザーでは機能します。これは悪い習慣ですが、今はこの方法を使いたくなります。
CTS_AE 2018

1
この質問はかなり古く、2008年にさかのぼります。その間、より良いアプローチがあったかもしれません。2015年の回答をお試しいただけますか?
Michiel Borkent、2018

16

ぼかしの代わりにドキュメントのmousedownイベントを使用することが可能です:

$(document).mousedown(function(){
  if ($(event.target).attr("id") == "mySpan") {
    // some process
  }
});

8

FocusEventインスタンスにはrelatedTarget属性がありますが、FFのバージョン47までは、具体的には、この属性はnullを返します。48はすでに機能しています。

あなたはここでもっと見ることができます


2

また、特定の要素がクリックされて機能する解決策がある場合、オートコンプリートがぼかしを無視するようにしようとしていますが、explicitOriginalTargetによりFirefoxのみが対象です

Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap( 
        function(origfunc, ev) {
            if ($(this.options.ignoreBlurEventElement)) {
                var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode : ev.explicitOriginalTarget);
                if (!newTargetElement.descendantOf($(this.options.ignoreBlurEventElement))) {
                    return origfunc(ev);
                }
            }
        }
    );

このコードは、AutocompleterのデフォルトのonBlurメソッドをラップし、ignoreBlurEventElementパラメータが設定されているかどうかを確認します。設定されている場合、クリックされた要素がignoreBlurEventElementかどうかを毎回チェックします。そうであれば、オートコンプリーターはonBlurを調整せず、それ以外の場合はonBlurを呼び出します。これに関する唯一の問題は、explicitOriginalTargetプロパティがMozilla固有であるため、Firefoxでのみ機能することです。今、私はexplicitOriginalTargetを使用するのとは異なる方法を見つけようとしています。あなたが言及したソリューションでは、要素にonclick動作を手動で追加する必要があります。explicitOriginalTargetの問題を解決できなかった場合、私はあなたの解決策に従うと思います。


2

あなたがチェックしているものをいつ逆にすることができますか?それはあなたが最後にぼかされたものを思い出す場合です:

<input id="myInput" onblur="lastBlurred=this;"></input>

次に、スパンのonClickで、両方のオブジェクトでfunction()を呼び出します。

<span id="mySpan" onClick="function(lastBlurred, this);">Hello World</span>

次に、関数はAjax.AutoCompleterコントロールをトリガーするかどうかを決定できます。関数には、クリックされたオブジェクトぼかされたオブジェクトがあります。onBlurはすでに発生しているため、提案が消えることはありません。


1

このようなものを使用してください:

var myVar = null;

そしてあなたの関数の中で:

myVar = fldID;

その後:

setTimeout(setFocus,1000)

その後:

function setFocus(){ document.getElementById(fldID).focus(); }

最終コード:

<html>
<head>
    <script type="text/javascript">
        function somefunction(){
            var myVar = null;

            myVar = document.getElementById('myInput');

            if(myVar.value=='')
                setTimeout(setFocusOnJobTitle,1000);
            else
                myVar.value='Success';
        }
        function setFocusOnJobTitle(){
            document.getElementById('myInput').focus();
        }
    </script>
</head>
<body>
<label id="jobTitleId" for="myInput">Job Title</label>
<input id="myInput" onblur="somefunction();"></input>
</body>
</html>

1

私はそれは可能ではないと思います、IEではあなたが使用しようとすることができますがwindow.event.toElement、Firefoxでは動作しません!


ChromeまたはSafariでは機能しません。たぶん、より標準に準拠した新しいバージョンのIEでは動作しないでしょう。
robocat 2015年

1

この回答で述べたように、の値を確認できますdocument.activeElementdocumentグローバル変数なので、onBlurハンドラーで使用するために特別なことをする必要はありません。

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}

1
  • document.activeElementは親ノードである可能性があります(たとえば、ターゲットから別のターゲットへの一時的なフェーズ切り替えであるため、ボディノード)。そのため、スコープでは使用できません。
  • ev.explicitOriginalTargetは常に評価されるとは限らない

したがって、最良の方法は、あなたのノード(event.target)がぼやけていることを間接的に理解するために、onclick on bodyイベントを使用することです


1

Google Chrome v66.x、Mozilla v59.x、Microsoft Edgeで動作します... jQueryを使用したソリューション。

Internet Explorer 9でテストしましたが、サポートされていません。

$("#YourElement").blur(function(e){
     var InputTarget =  $(e.relatedTarget).attr("id"); // GET ID Element
     console.log(InputTarget);
     if(target == "YourId") { // If you want validate or make a action to specfic element
          ... // your code
     }
});

他のInternet Explorerバージョンでテストにコメントします。


0

編集: それを行うためのハッキーな方法は、気になるすべての要素のフォーカスを追跡する変数を作成することです。したがって、 'myInput'がフォーカスを失ったことを気にする場合は、変数をフォーカスに設定します。

<script type="text/javascript">
   var lastFocusedElement;
</script>
<input id="myInput" onFocus="lastFocusedElement=this;" />

元の答え: 'this'を関数に渡すことができます。

<input id="myInput" onblur="function(this){
   var theId = this.id; // will be 'myInput'
}" />

これは質問の答えにはなりません。うまくいけば、私は追加の例で明確にした
Michiel Borkent '23 / 09/23

0

グローバル変数blurfromとblurtoを使用することをお勧めします。次に、必要なすべての要素を構成して、フォーカスを失ったときにDOM内の位置を変数blurfromに割り当てます。さらには、configure彼らはそうフォーカスを獲得することは、変数blurtoを設定することをその DOM内の位置。次に、別の関数を使用して、blurfromデータとblurtoデータを分析できます。


それはほとんど解決策ですが、onblurイベントハンドラーでは、どの項目がクリックされたかを知る必要があったため、onblurのタイムアウトでそれが行われました。
Michiel Borkent、2008

0

explicitOriginalTargetを使用したソリューションは、テキスト入力からテキスト入力へのジャンプでは機能しないことに注意してください。

ボタンを次のテキスト入力に置き換えようとすると、違いがわかります。

<input id="btn1" onblur="showBlur(event)" value="text1">
<input id="btn2" onblur="showBlur(event)" value="text2">
<input id="btn3" onblur="showBlur(event)" value="text3">

0

私はこれと同じ機能を使用していて、FF、IE、Chrome、Operaにはイベントのソース要素を提供する機能があることがわかりました。私はSafariをテストしていませんが、似たようなものがあると思います。

$('#Form').keyup(function (e) {
    var ctrl = null;
    if (e.originalEvent.explicitOriginalTarget) { // FF
        ctrl = e.originalEvent.explicitOriginalTarget;
    }
    else if (e.originalEvent.srcElement) { // IE, Chrome and Opera
        ctrl = e.originalEvent.srcElement;
    }
    //...
});

これはうまくいきますが、なぜダウン投票ですか?originalEventを削除するだけです!
fekiri malek 16

0

JavaScriptをコーディングするときにタイムアウトを使用したくないので、Michiel Borkentとは逆の方法で行います。(背後にあるコードを試さなかったが、アイデアを得る必要がある)。

<input id="myInput" onblur="blured = this.id;"></input>
<span onfocus = "sortOfCallback(this.id)" id="mySpan">Hello World</span>

頭の中でそのようなもの

<head>
    <script type="text/javascript">
        function sortOfCallback(id){
            bluredElement = document.getElementById(blured);
            // Do whatever you want on the blured element with the id of the focus element


        }

    </script>
</head>

0

あなたはIEを修正することができます:

 event.currentTarget.firstChild.ownerDocument.activeElement

FFの「explicitOriginalTarget」のように見えます。

アントワーヌとJ


0

代替ソリューションを書いたどの要素がフォーカス可能と「blurable」ようにする方法。

これは、要素をとして作成し、contentEditable視覚的に非表示にし、編集モード自体を無効にすることに基づいています。

el.addEventListener("keydown", function(e) {
  e.preventDefault();
  e.stopPropagation();
});

el.addEventListener("blur", cbBlur);
el.contentEditable = true;

デモ

注:Chrome、Firefox、Safari(OS X)でテストされています。IEについてはわかりません。


関連:私はとても好奇心/興味がどのようにVueのFocusableのディレクティブを使用して、このような機能を実装するために人のために、VueJsのためのソリューションを探していた、してください見てみましょう


-2

こちらです:

<script type="text/javascript">
    function yourFunction(element) {
        alert(element);
    }
</script>
<input id="myinput" onblur="yourFunction(this)">

または、JavaScript(この例ではjQuery)を介してリスナーをアタッチする場合:

var input = $('#myinput').blur(function() {
    alert(this);
});

編集:ごめんなさい。質問を読み間違えました。


3
これが質問の答えではないことに気づき、誤って読んだ場合は、それに応じて更新するか、削除してください。
TJ

-2


「this」でonblurイベントを発生させるフィールドの参照を渡すことにより、jqueryを介して簡単に可能になると思います。
例えば

<input type="text" id="text1" onblur="showMessageOnOnblur(this)">

function showMessageOnOnblur(field){
    alert($(field).attr("id"));
}

ありがとう
Monika


-2

次のようにすることができます:

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>

-2

答えはハックだけですが、実際には非常に使いやすい組み込みのソリューションがあります。基本的には、次のようにフォーカス要素をキャプチャできます。

const focusedElement = document.activeElement

https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement


少なくとも私の場合、activeElementが本体であるため、これは機能しません。次のレンダー/ティックでチェックすると、正しく設定されます。しかし、目盛りが押し寄せていることを確認するため、shog9のソリューションが唯一の適切なソリューションであるようです。
Mathijs Segers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.