Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 20.04.2015, 10:33
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Нашел способ как обойти этот нюанс. Правда способ не хороший на вид. Ибо в дереве DOM болтается лишний input (который приходится скрывать, причем скрывать нехорошим способом, ибо если его скрыть нормальным способом, то механизм не работает).

Вот код:

https://fiddle.sencha.com/#fiddle/lgr

console.clear();

Ext.FocusManager.enable(true);

Ext.define("MyComponent", {
    extend: "Ext.Component",
    
    focusable: true,
    focusEl: null,
    
    privates: {
    	getFocusEl: function() {
        	return this.focusEl;
    	},
    },
    
    initFocusable: function() {
        this.focusEl = Ext.create("Ext.Element", document.createElement("input"));
        this.focusEl.appendTo(Ext.getBody());
        this.focusEl.applyStyles({
            position: "absolute",
            top: "-5000px",
            left: "-5000px"
        });
    }
    
});

var comp = Ext.create("MyComponent", {
    renderTo: Ext.getBody(),
    html: "Тестовый компонент"
});

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

comp.on("focus", function() {
    console.log("FOCUS");
});

comp.on("blur", function() {
    console.log("BLUR");
});

comp.focus();
comp.blur();
Ответить с цитированием
  #12 (permalink)  
Старый 20.04.2015, 10:37
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Теперь вопрос, как сделать фокусируемый компонент для случая, когда DOM-элемент компонента не является фокусируемый и при этом не использовать "грязные" способы, подобные тем, что я использовал выше? Например для окошек, которые построены на DIV-ах.
Ответить с цитированием
  #13 (permalink)  
Старый 20.04.2015, 10:55
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Ура, нашел способ без грязных методов.

Вот код:

https://fiddle.sencha.com/#fiddle/lgs

console.clear();

Ext.FocusManager.enable(true);

Ext.define("MyComponent", {
    extend: "Ext.Component",
    
    focusable: true,
    
    initFocusable: function() {
        var me = this;
        
        me.on("render", function() {
            Ext.override(this.getEl(), {
                focus: function() {
                    this.callParent(arguments);
                    me.onFocus();
                },
                blur: function() {
                    this.callParent(arguments);
                    me.onBlur();
                }
            });
        });
        
    }
    
});

var comp = Ext.create("MyComponent", {
    renderTo: Ext.getBody(),
    html: "Тестовый компонент"
});

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

comp.on("focus", function() {
    console.log("FOCUS");
});

comp.on("blur", function() {
    console.log("BLUR");
});

comp.focus();
comp.blur();


Здесь я внедрил в элемент компонента недостающий функционал, а именно вызовы методов me.onFocus() и me.onBlur() и все заработало без всяких левых тегов типа инпута.

Остался последний штрих - оформить этот код в виде миксина, чтобы можно было одной строчкой его внедрять в любой компонент.
Ответить с цитированием
  #14 (permalink)  
Старый 20.04.2015, 12:50
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Проблема решена полностью, чисто!
Миксин писать не надо.

Итак, чтобы компонент сделать фокусируемый нужно добавить в него всего лишь две строчки.

Вот код компонента с этими двумя строчками:

Ext.define("MyComponent", {
    extend: "Ext.Component",
    focusable: true,
    tabIndex: 0, // без этой строчки не работает механизм фокусировки
});


Полдня блин убил чтобы выяснить, что обязательно нужно прописать tabIndex: 0!

Последний раз редактировалось khusamov, 20.04.2015 в 17:15. Причина: Проблему решил, нужна была строка tabIndex: 0
Ответить с цитированием
  #15 (permalink)  
Старый 21.05.2015, 22:23
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Почти правильно, но не совсем. Устанавливая tabIndex: 0 вы тем самым не только делаете компонент фокусируемым, но ещё и добавляете его в tab order. Обычно это как раз то, что и нужно, но не всегда. Чтобы сделать компонент просто фокусируемым, но без возможности клавиатурной навигации, присвойте ему негативный tabIndex (обычно -1).

Более подробное объяснение: компоненты в Ext JS имеют отображение в DOM. Есть такое понятие: главный элемент; этот элемент содержит в себе всю остальную разметку компонента. Конфигурация главного элемента задаётся свойством autoEl компонента, и по умолчанию тегом является DIV.

Возвращаясь к фокусировке, DIV элементы по умолчанию не являются фокусируемыми, в отличие от INPUT. Чтобы сделать DIV фокусируемым, нужно присвоить ему атрибут tabindex; фреймворк делает это за вас, если вы укажете в свойствах компонента поле tabIndex. Свойство focusable отвечает за реакцию компонента на события фокусировки и на определённые внутренние механизмы, но не влияет на отображение в DOM. Именно поэтому вам и нужно было установить оба поля: focusable: true и tabIndex: 0, чтобы ваш компонент стал фокусируемым.

Ну и на добавку, учитывайте что в IE DOM события focus/blur/focusin/focusout являются асинхронными. ;)
Ответить с цитированием
  #16 (permalink)  
Старый 21.05.2015, 22:39
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Сообщение от nohuhu Посмотреть сообщение
Почти правильно, но не совсем. Устанавливая tabIndex: 0 вы тем самым не только делаете компонент фокусируе...

Ну и на добавку, учитывайте что в IE DOM события focus/blur/focusin/focusout являются асинхронными.
Спасибо за ответ! А откуда вы все это узнали? Очень хотелось бы подробнее почитать про принципы работы Ext.

Что значит асинхронные события? Неопределенность последовательности их появления?
Ответить с цитированием
  #17 (permalink)  
Старый 21.05.2015, 23:36
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Ну как откуда узнал, на практике изучил. ;) Когда два года назад на меня повесили разработку Accessibility, фреймворк пришлось изрядно отрефакторить, чтобы управление фокусом и клавиатурная навигация вообще заработали.

Про "принципы работы" часто люди спрашивают, но сам вопрос мне не очень понятен. Фреймворк сделан для того, чтобы вы могли его использовать и получать (более/менее) одинаково работающие приложения во всех браузерах, которые мы поддерживаем. Есть API документация, есть tutorials, есть курсы. Изучайте и используйте. ;) Зачем вам знание каких-то глубинных вещей? Обычно оно ничем не помогает, только грузит ненужными деталями. Хотя мне и не жалко никогда, так что если есть конкретные вопросы, то спрашивайте. ;)

Асинхронные это и значит, что асинхронные: события выстреливают не в том же цикле исполнения, что и собственно момент фокусирования.

Возьмём вот такой код, для примера:

Код:
Ext.onReady(function() {
    var btn = new Ext.button.Button({
        renderTo: document.body,
        text: 'bork!',
        listeners: {
            element: 'el',
            focus: function() {
                console.log('bork focused!');
            }
        }
    });
    
    setTimeout(function() {
        console.log('pre');
        btn.focus();
        console.log('post');
    }, 100);
});
В Chrome/Safari/Firefox/whatever консоль будет выглядеть так:

Код:
pre
bork focused!
post
В IE8-11 консоль будет выглядеть вот так:

Код:
pre
post
bork focused!
Вот конкретно за эту фигню я ненавижу Microsoft отдельно. Асинхронность фокусных событий это очень, очень больно для фреймворков. :(
Ответить с цитированием
  #18 (permalink)  
Старый 21.05.2015, 23:43
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

спасибо!
бум юзать

Правда в своем проекте отменил фокусировку.

Оказывается мне нужна была selectable, чего в Ext JS нету.

Пришлось самому писать миксин чтобы во всех компонентах появилась возможность выделения

А так я эту фичу видел лишь в гридах. Почему то они не сделали эту фичу для всех компонент.
Ответить с цитированием
  #19 (permalink)  
Старый 21.05.2015, 23:51
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Не совсем понятно, какое именно выделение вам нужно. В таблицах есть ячейки и строки, которые можно выделять. В обычных компонентах нет ни ячеек, ни колонок. В них и содержимого может не быть вовсе, кроме структурных элементов.
Ответить с цитированием
  #20 (permalink)  
Старый 21.05.2015, 23:55
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

У меня есть компоненты, которые наследуются от штатного контейнера, которые нужно выделять, причем с возможностью группового выделения при нажатой Shift. Эти компоненты просто обычные графические примитивы: линии, кружки, квадраты и прочее. Также среди них есть примитив Группа, которая может внутри себя содержать другие примитивы (потому и потребовалось наследоваться от контейнера). В общем это по сути графический редактор. Причем я сделал так, что эти примитивы у меня выступают как виды со своими контролерами вида. Очень удобно!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Blur и Focus Phoenix13 Events/DOM/Window 6 19.11.2014 00:01
Разметка для Google closure compiler monolithed Оффтопик 11 04.09.2013 00:50
Плагин PlantUML B~Vladi Оффтопик 49 22.08.2012 16:03
При повторном фокусе добавляются события blur и keydown sdaww Events/DOM/Window 2 05.07.2012 15:15
события focus и blur AdeL1ne jQuery 1 24.09.2011 09:26