عند حدوث حدث "تمويه"، كيف يمكنني معرفة العنصر الذي تم التركيز عليه *إلى*؟

StackOverflow https://stackoverflow.com/questions/121499

  •  02-07-2019
  •  | 
  •  

سؤال

لنفترض أنني أرفق blur وظيفة لمربع إدخال HTML مثل هذا:

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

هل هناك طريقة للحصول على معرف العنصر الذي تسبب في حدوث ذلك blur حدث لإطلاق (العنصر الذي تم النقر عليه) داخل الوظيفة؟كيف؟

على سبيل المثال، لنفترض أن لدي فترة مثل هذا:

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

إذا قمت بالنقر فوق الامتداد مباشرة بعد التركيز على عنصر الإدخال، فسيفقد عنصر الإدخال تركيزه.كيف تعرف الدالة أنه كان mySpan تم النقر عليه؟

ملاحظة:إذا حدث حدث onclick للامتداد قبل حدث onblur لعنصر الإدخال، فسيتم حل مشكلتي، لأنه يمكنني تعيين بعض قيم الحالة التي تشير إلى أنه تم النقر فوق عنصر معين.

pps:خلفية هذه المشكلة هي أنني أريد تشغيل عنصر تحكم الإكمال التلقائي AJAX خارجيًا (من عنصر قابل للنقر) لإظهار اقتراحاته، دون أن تختفي الاقتراحات على الفور بسبب blur حدث على عنصر الإدخاللذلك أريد التحقق من blur إذا تم النقر على عنصر محدد، وإذا كان الأمر كذلك، فتجاهل حدث التمويه.

هل كانت مفيدة؟

المحلول

همم...في فايرفوكس، يمكنك استخدام explicitOriginalTarget لسحب العنصر الذي تم النقر عليه.توقعت toElement أن تفعل الشيء نفسه بالنسبة لـ IE، ولكن يبدو أنه لا يعمل ...ومع ذلك، يمكنك سحب العنصر الذي تم التركيز عليه حديثًا من المستند:

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 تمت معالجة الحدث، وقد لا تكون له قيمة صالحة على الإطلاق أثناء المعالجة!يمكن التخفيف من ذلك من خلال الاختلاف في التقنية التي انتهى ميشيل باستخدامها:

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 لا يضبط التركيز على الأزرار الموجودة تم النقر عليه (ضد.مبوبة إلى).

نصائح أخرى

إجابة 2015:وفق أحداث واجهة المستخدم, ، يمكنك استخدام ال 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 (علة 962251, MDN).

لقد قمت بحلها في النهاية من خلال انتهاء مهلة حدث onblur (بفضل نصيحة صديق ليس StackOverflow):

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

يعمل على حد سواء في FF وIE.

من الممكن استخدام حدث mousedown للمستند بدلاً من التمويه:

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

نوع FocusEvent الحالات لديها relatedTarget السمة، ومع ذلك، حتى الإصدار 47 من FF، على وجه التحديد، ترجع هذه السمة فارغة، من 48 تعمل بالفعل.

يمكنك رؤية المزيد هنا.

أحاول أيضًا جعل برنامج الإكمال التلقائي يتجاهل التعتيم إذا تم النقر على عنصر معين ولدي حل عملي، ولكن لمتصفح Firefox فقط بسبب صريحOriginalTarget

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);
                }
            }
        }
    );

يلتف هذا الرمز على طريقة onBlur الافتراضية لبرنامج الإكمال التلقائي ويتحقق من تعيين معلمات تجاهلBlurEventElement.إذا تم تعيينه، فإنه يتحقق في كل مرة لمعرفة ما إذا كان العنصر الذي تم النقر عليه هو تجاهلBlurEventElement أم لا.إذا كان الأمر كذلك، فإن برنامج الإكمال التلقائي لا يستدعي onBlur، وإلا فإنه يستدعي onBlur.المشكلة الوحيدة في هذا هو أنه يعمل فقط في Firefox لأن خاصية صريحةOriginalTarget خاصة بموزيلا.الآن أحاول العثور على طريقة مختلفة عن استخدام صريحOriginalTarget.الحل الذي ذكرته يتطلب منك إضافة سلوك onclick يدويًا إلى العنصر.إذا لم أتمكن من حل مشكلة plainOriginalTarget، فأعتقد أنني سأتبع الحل الذي تقدمه.

هل يمكنك عكس ما تقوم بفحصه ومتى؟هذا إذا كنت تتذكر ما كان غير واضح في الماضي:

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

ثم في onClick لامتدادك، قم باستدعاء الدالة() مع كلا الكائنين:

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

يمكن لوظيفتك بعد ذلك أن تقرر ما إذا كان سيتم تشغيل عنصر التحكم Ajax.AutoCompleter أم لا.تحتوي الدالة على الكائن الذي تم النقر عليه و الكائن غير واضح.لقد حدث onBlur بالفعل، لذلك لن يؤدي إلى اختفاء الاقتراحات.

استخدم شيئًا مثل هذا:

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>

أعتقد أنه ليس إمكانيًا ، مع IE يمكنك محاولة استخدامه window.event.toElement, ولكن لا يعمل مع الفايرفوكس!

كما لوحظ في هذه الإجابة, ، يمكنك التحقق من قيمة document.activeElement. document هو متغير عام، لذلك ليس عليك القيام بأي عملية سحرية لاستخدامه في معالج onBlur الخاص بك:

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}
  • يمكن أن يكون document.activeElement عقدة أصل (على سبيل المثال العقدة الأساسية لأنها في مرحلة مؤقتة من الهدف إلى آخر)، لذا فهو غير قابل للاستخدام في نطاقك
  • لا يتم دائمًا تقدير قيمة ev.explicitOriginalTarget

لذا فإن أفضل طريقة هي استخدام حدث onclick on body لفهم بشكل غير مباشر أن عقدتك (event.target) غير واضحة

يحرر:إحدى الطرق المتقنة للقيام بذلك هي إنشاء متغير يتتبع التركيز لكل عنصر يهمك.لذا، إذا كنت تهتم بأن "myInput" فقد التركيز، فقم بتعيين متغير له على التركيز.

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

الجواب الأصلي:يمكنك تمرير "هذا" إلى الوظيفة.

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

أقترح استخدام المتغيرات العالمية Blurfrom وBlurto.بعد ذلك، قم بتكوين جميع العناصر التي تهمك لتعيين موضعها في DOM للمتغير الضبابي عندما تفقد التركيز.بالإضافة إلى ذلك، قم بتكوينها بحيث يؤدي الحصول على التركيز إلى ضبط المتغير Blurto على هُم الموقف في DOM.بعد ذلك، يمكنك استخدام وظيفة أخرى تمامًا لتحليل بيانات التمويه والتشويش.

ضع في اعتبارك أن الحل باستخدام صريحOriginalTarget لا يعمل مع قفزات إدخال النص إلى إدخال النص.

حاول استبدال الأزرار بإدخالات النص التالية وسترى الفرق:

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

لقد كنت ألعب بنفس الميزة واكتشفت أن 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;
    }
    //...
});

لا أحب استخدام المهلة عند برمجة جافا سكريبت، لذا سأفعل ذلك بالطريقة المعاكسة لميشيل بوركينت.(لم تجرب الكود الموجود خلفك ولكن يجب أن تحصل على الفكرة).

<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>

يمكنك إصلاح IE باستخدام:

 event.currentTarget.firstChild.ownerDocument.activeElement

يبدو مثل "explicitOriginalTarget" لـ FF.

أنطوان و ج

لقد كتبت حل بديل كيفية جعل أي عنصر قابلاً للتركيز و"قابلاً للتعتيم".

يعتمد على صنع عنصر مثل contentEditable وإخفائه بصريًا وتعطيل وضع التحرير نفسه:

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

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

تجريبي

ملحوظة:تم اختباره في Chrome وFirefox وSafari (OS X).لست متأكدا من IE.


متعلق ب:كنت أبحث عن حل لـ VueJs، لذلك بالنسبة لأولئك المهتمين/الفضوليين حول كيفية تنفيذ هذه الوظيفة باستخدام توجيه Vue Focusable، من فضلك إلق نظرة.

يعمل في جوجل كروم v66.x وموزيلا v59.x ومايكروسوفت إيدج...الحل مع مسج.

أقوم باختبار 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 الأخرى.

لا أرى سوى اختراقات في الإجابات، ولكن يوجد في الواقع حل مدمج سهل الاستخدام للغاية:في الأساس يمكنك التقاط عنصر التركيز مثل هذا:

const focusedElement = document.activeElement

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

من هنا:

<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);
});

يحرر:آسف.لقد أخطأت في قراءة السؤال.


أعتقد أنه من الممكن بسهولة عبر jquery عن طريق تمرير مرجع الحقل الذي يسبب حدث onblur في "هذا".
على سبيل المثال.

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

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

شكرًا
مونيكا

يمكنك جعلها مثل هذا:

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top