#angular #hover #internet-explorer-11 #ng-bootstrap
#angular #наведите #internet-explorer-11 #ng-bootstrap
Вопрос:
Наш клиент обнаружил «ошибку». Ошибка заключается в том, что одна кнопка застряла на синем фоне (зависла) даже после того, как указатель был перемещен наружу.
Я создал MWE локально и переместил его в Stackblitz (извините, не работает в IE, lol).
Я также добавил ссылки на видеоролики YouTube, чтобы показать проблему, поскольку оказалось, что вам было трудно воспроизвести ее.
Чтобы воспроизвести локально, просто создайте новый проект Angular , ng add @ng-bootstrap/ng-bootstrap
.
Angular 11, «@ng-bootstrap / ng-bootstrap»: «^ 9.0.2», «bootstrap»: «^ 4.6.0»,
Вот просмотр app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
toggle: boolean;
}
Вот вид app.component.html:
<div [ngSwitch]="toggle">
<button *ngSwitchCase="true" type="button" class="btn btn-primary" (click)="toggle = !toggle" ngbPopover="You see, I show up on hover1!" placement="right" triggers="mouseenter:mouseleave">Primary1</button>
<button *ngSwitchDefault type="button" class="btn btn-outline-primary" (click)="toggle = !toggle" ngbPopover="You see, I show up on hover2!" placement="right" triggers="mouseenter:mouseleave">Primary2</button>
</div>
Ключевые моменты:
- наличие двух кнопок
- кнопка 1 при нажатии будет скрыта, кнопка 2 будет показана
- кнопка 2 при нажатии будет скрыта, кнопка 1 будет показана
- кнопки 1 и 2 имеют разные стили начальной загрузки, чтобы упростить задачу
- обе кнопки отображают всплывающую подсказку при наведении, отклоняют их при оставлении
Как воспроизвести:
- нажмите на кнопку
- сразу после щелчка наведите курсор мыши на всплывающую подсказку (но вам нужно быть очень, очень быстрым)
Эффект:
- кнопка 1 скрыта (удалена из DOM),
- показана кнопка 2 (добавлена в DOM),
- кнопка 2 не зависает,
- всплывающие подсказки отклоняются
- IE по-прежнему применяется
.btn-outline-primary:hover
, даже кнопка не наведена, - наведение курсора мыши на кнопку и перемещение указателя устраняют проблему — IE будет применяться
.btn-outline-primary
, как и ожидалось.
Что мы думаем? Что IE после добавления кнопки 2 не знает, что пользователь уже переместил курсор (поэтому IE «думает», что состояние наведения не было изменено, поэтому он сохраняет стиль:hover, но кнопка отличается). НО mouseleave
и mouseout
запускается для новой кнопки.
Мы не смогли воспроизвести его в Chrome после многих попыток.
Что мы пробовали:
- мы отключили transisions — Chrome по умолчанию добавляет медиа-запрос preferences-reduced-motion, IE не поддерживается. Это исправило эффект мигания, но проблема с наведением остается.
- мы попытались отделить кнопку от компонента и вызвать
detectChanges
с / безsetTimeout
, чтобы позволить IE «переосмыслить» ситуацию, а затем повторно отобразить кнопку с соответствующими стилями — не помогло - в конечном счете я добавил такой переключатель, как этот:
<div [ngSwitch]="forceRefresh">
<div *ngSwitchCase="true">...</div>
<div *ngSwitchDefault>...</div>
</div>
и я меняю forceRefresh
значение с false
на true
in setTimeout
, чтобы заставить IE думать, что он должен отображать совершенно другой DOM (в обоих случаях отображается одна и та же кнопка). Это сработало.
Я хотел бы знать, есть ли более элегантный способ обойти эту проблему, связанную с IE?
Примечание: В нашем проекте это происходит даже после удаления всплывающих окон, поэтому я сомневаюсь, что это связано с всплывающими окнами начальной загрузки. Я предполагаю, что это можно легко исправить, сохранив только одну кнопку, но тогда нам придется применять много условных выражений для каждого атрибута для такой кнопки. Использование ng-templates
для группировки кнопок гораздо предпочтительнее.
Видео (из home, MWE, Chrome, IE11, Edge): https://www.youtube.com/watch?v=oeG-11TzS-Q
Комментарии:
1. Вы имеете в виду, что проблема в том, что фон Primary2 по-прежнему остается синим при наведении указателя мыши? Поправьте меня, если я ошибаюсь. Если это так, я провел несколько тестов в IE 11, но, похоже, результат такой же, как у Chrome. Вы можете проверить мой скриншот: i.stack.imgur.com/eXEPc.gif . Я не могу воспроизвести проблему. Я тестирую с помощью Angular10, «@ng-bootstrap / ng-bootstrap»: «^ 8.0.4», «bootstrap»: «^ 4.5.0».
2. Именно в этом и заключается проблема здесь. Я знаю, что это трудно воспроизвести. Это еще сложнее для полностью пустого компонента. Я загружу на него видео (lol). На работе мы используем Angular 9, у нас есть ветка с 10, я тестировал дома на 11, так что это, вероятно, не имеет значения.
3. Я добавил ссылки на видео, которые иллюстрируют проблему в IE.
4. Теперь я могу воспроизвести его. Это довольно сложно воспроизвести, поскольку иногда это работает. Теперь я думаю, что это не связано с версией Angular и версией bootstrap. Это больше похоже на проблему с ng-bootstrap в IE. Я полагаю, что вы также можете поднять проблему в ng-bootstrap github.
5. Хочу ли я внести свой вклад в долгоживущего короля браузеров, которого каждый разработчик хотел бы похоронить заживо? Но я думаю, просто ради любопытства, это какая-то идея. В любом случае, спасибо, что проявили некоторый интерес и приложили усилия для воспроизведения