Facendo clic su un elemento con tabindex = 0 in IE comporterà l'elemento guadagnando attenzione invisibile. Il modo per ottenere una messa a fuoco visibile è chiamando a fuoco a livello di codice() mentre l'elemento non ha già una messa a fuoco invisibile. Dal fuoco avviene subito dopo mousedown, questo significa che abbiamo bisogno di:
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
Se il bambino è in linea o un blocco con nessun set di larghezza, l'effetto è lo stesso che cliccando direttamente sul genitore. Tuttavia, se il bambino è un blocco in linea o un blocco con una larghezza impostata e il genitore ha già messo a fuoco, allora il genitore si sfocherà() subito dopo l'esecuzione dei gestori di mouse. Abbiamo tre diversi modi di procedere, con diversi compromessi.
Un'opzione consiste semplicemente nel sopprimere la sfocatura con preventDefault(); la virtù di questo approccio è che blur() non sparerà mai e focus() non sparerà in modo ridondante, il che ci consente di scrivere una logica diretta nei nostri focalizzatori e sfocati; il vizio di questo approccio è che disabilita la selezione del testo:
$('#child').mousedown(function(e){
e.preventDefault()
})
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
Se non vogliamo disabilitare la selezione del testo, un'altra opzione è quella di concentrarsi sul padre dal gestore mouseup del bambino; tuttavia, in questo modo il genitore sfocatura e quindi concentrarsi ancora una volta, che ci impedisce di sapere quando una messa a fuoco o sfocatura è "reale" piuttosto che semplicemente una conseguenza transitoria della nostra logica messa a fuoco propagazione:
$('#child').mouseup(function(e){
$(e.currentTarget).closest('[tabindex]').focus()
})
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
La terza opzione ha le virtù di entrambi gli approcci di cui sopra, ma è il più complicato logicamente:
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
var parentWasClicked = parent.is(e.target)
var parentHasFocus = parent.is(':focus')
if (parentWasClicked && !parentHasFocus) {
parent.focus()
} else if (parentHasFocus && !parentWasClicked) {
window.ignoreFocusChanges = true
}
})
.mouseup(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
})
.blur(function(e){
if (window.ignoreFocusChanges) {
return
}
console.log('blurred')
})
.focus(function(e){
if (window.ignoreFocusChanges) {
window.ignoreFocusChanges = false
return
}
console.log('focused')
})
ben peggiore delle ipotesi, si può sempre definire un codice per IE solo per aggirare il problema – Huangism