¿Cómo enfocar un elemento en Elm?
¿Cómo puedo poner el foco en un elemento Html en Elm? Traté de establecer el atributo de enfoque automático en el elemento y solo establece el enfoque en la carga de la página.
4 answers
La función focus
en el paquete elm-lang/dom se usa para establecer el foco con un Task
(sin usar ningún port
s o JavaScript).
Internamente utiliza requestAnimationFrame
para asegurarse de que cualquier nueva actualización DOM se procese antes de intentar encontrar el nodo DOM en el que centrarse.
Un ejemplo de uso:
type Msg
= FocusOn String
| FocusResult (Result Dom.Error ())
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
FocusOn id ->
( model, Dom.focus id |> Task.attempt FocusResult )
FocusResult result ->
-- handle success or failure here
case result of
Err (Dom.NotFound id) ->
-- unable to find dom 'id'
Ok () ->
-- successfully focus the dom
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-26 17:04:05
Una solución para esto es usar Observadores de Mutaciones. Inserte este JavaScript en su página HTML principal o en la vista principal de su código Elm:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
handleAutofocus(mutation.addedNodes);
});
});
var target = document.querySelector('body > div');
var config = { childList: true, subtree: true };
observer.observe(target, config);
function handleAutofocus(nodeList) {
for (var i = 0; i < nodeList.length; i++) {
var node = nodeList[i];
if (node instanceof Element && node.hasAttribute('data-autofocus')) {
node.focus();
break;
} else {
handleAutofocus(node.childNodes);
}
}
}
Luego cree elementos HTML incluyendo Html.Attributes.attribute "data-autofocus" ""
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-29 00:13:09
Pasé bastante tiempo explorando esto recientemente. Desafortunadamente, no creo que sea posible con la biblioteca elm-html
existente. Sin embargo, se me ocurrió un truco que utiliza animaciones CSS para desencadenar un evento e incrustarlo en js puro.
Aquí está mi hack en Elm usando un nodo script
y un nodo style
. Es muy feo en mi opinión.
import Html exposing (div, button, text, input, node)
import Html.Events exposing (onClick)
import Html.Attributes exposing (type', class)
import StartApp.Simple
main =
StartApp.Simple.start { model = model, view = view, update = update }
model = []
view address model =
-- View now starts with a <style> and <script> (hacky)
(node "style" [] [ Html.text style ]) ::
(node "script" [] [Html.text script ]) ::
(button [ onClick address AddInput ] [ text "Add Input" ]) ::
model |>
div []
type Action = AddInput
update action model =
case action of
AddInput -> (Html.p [] [input [type' "text", class "focus"] []]) :: model
-- Use pure string css (hacky)
style = """
.focus {
animation-name: set-focus;
animation-duration: 0.001s;
-webkit-animation-name: set-focus;
-webkit-animation-duration: 0.001s;
}
@-webkit-keyframes set-focus {
0% {color: #fff}
}
@keyframes set-focus {
0% {color: #fff}
}
"""
-- Cheating by embedding pure javascript... (hacky)
script = """
var insertListener = function(event){
if (event.animationName == "set-focus") {
event.target.focus();
}
}
document.addEventListener("animationstart", insertListener, false); // standard + firefox
document.addEventListener("MSAnimationStart", insertListener, false); // IE
document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari
"""
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-28 13:00:18
Con elm/html 0.19 puede configurar el Html.Attrbutes autofocus a Verdadero
input [ onInput Code, autofocus True ] []
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-03 09:44:22