2015-01-12 3 views
7

Я пишу компонент предложения, которые в основном будут иметь следующие функциональные возможности:Обнаружение focusOut всей компонента

  • Он имеет ввод текста
  • После того, как этот ввод текста получает сосредоточены он будет отображаться в DIV под это с некоторой информацией и ссылками
  • Этот div имеет много p-тегов на нем и некоторые теги.
  • Когда фокус выходит из ВСЕЙ компоненты он должен скрыть DIV

Я попытался написать событие focusOut моего компонента, как это:

focusOut: function(event, view){ 
    if (!$.contains(this.$('.autocomplete-group')[0], event.relatedTarget)) 
    this.set('showingSuggestions', false) 
} 

В основном это будет видеть, если новый сфокусированный элемент (event.relatedTarget) находится внутри внешнего DIV моего компонента (у которого есть класс группы автозаполнения).

Это отлично работает на Chrome, но не на Firefox и IE. Оказывается, FF не заполняет связанное свойство Target.

Затем я попробовал решение, которое не делало e happy (цитируется here). Это не сделало меня счастливым, потому что привязка события ко всему документу кажется неправильным. Так или иначе, это не сработало.

Мой вопрос заключается в том, что есть хороший, простой, кросс-браузерный способ просто определить, удалился ли фокус из моего всего компонента.

+0

Я только что проверил activeElement в другом runloop. К этому времени очередь рендеринга будет выполнена. https://github.com/blessenm/ember-cli-bm-select/blob/master/addon/components/bm-select.js#L155 – blessenm

+0

Благодарим вас за благословение, ваше решение отлично сработало для меня. –

ответ

7

Запустите код в новой runloop, используя Em.run.later. Вот пример кода для одного моего дополнения. Я скрываю выпадающее меню, когда фокус выходит из компонента.

lostFocus: function() { 
    if(this.get('isOpen')) { 
     Em.run.later(this, function() { 
     var focussedElement = document.activeElement; 
     var isFocussedOut = this.$().has(focussedElement).length === 0 
       && !this.$().is(focussedElement); 

     if(isFocussedOut) { 
      this.closeOptions({focus:false}); 
     } 
     }, 0); 
    } 
    }.on('focusOut'), 

Выполнение кода в отдельном runloop будет гарантировать, что вы получите document.activeElement правильно

Смежные вопросы