jQuery animate/scroll 仅部分适用于第二次点击
jQuery animate/scroll only partially works on second click
当我使用 jQuery 为滚动行为设置动画时,第一次单击将导致视图直接跳转到单击的锚元素。
第二次点击,如果在动画延迟内发出,将完美运行。
如果动画延迟 运行 结束后再次发出点击,则会再次直接跳转到该元素。
这是演示该问题的简短 gif:
如你所见,我点击services
,瞬间跳转。我等到动画延迟运行s关闭后点击portfolio
,又是瞬间跳转。但随后我再次快速单击 services
(动画延迟尚未 运行 关闭)并且它按预期工作。
我的 Elm 应用程序已将 onClick
事件分配给某些元素。触发时,元素的 href
通过端口传递给 JavaScript 函数,如下所示:
-- partial view
view =
div []
[ nav [ class "navbar navbar-default navbar-fixed-top" ]
[ div [ class "container" ]
[ div [ class "navbar-header page-scroll" ]
[ button [ class "navbar-toggle", attribute "data-target" "#bs-example-navbar-collapse-1", attribute "data-toggle" "collapse", type' "button" ]
[ span [ class "sr-only" ]
[ text "Toggle navigation" ]
, span [ class "icon-bar" ]
[]
, span [ class "icon-bar" ]
[]
, span [ class "icon-bar" ]
[]
]
, a [ class "navbar-brand page-scroll", href "#page-top", onClick (Update.ClickedElem "#page-top") ]
[ text "Start Bootstrap" ]
]
, div [ class "collapse navbar-collapse", id "bs-example-navbar-collapse-1" ]
[ ul [ class "nav navbar-nav navbar-right" ]
[ li [ class "hidden" ]
[ a [ href "#page-top" ]
[]
]
, li []
[ a [ class "page-scroll", href "#services", onClick (Update.ClickedElem "#services") ]
[ text "Services" ]
]
, li []
[ a [ class "page-scroll", href "#portfolio", onClick (Update.ClickedElem "#portfolio") ]
[ text "Portfolio" ]
]
, li []
[ a [ class "page-scroll", href "#about", onClick (Update.ClickedElem "#about") ]
[ text "About" ]
]
, li []
[ a [ class "page-scroll", href "#team", onClick (Update.ClickedElem "#team") ]
[ text "Team" ]
]
, li []
[ a [ class "page-scroll", href "#contact", onClick (Update.ClickedElem "#contact") ]
[ text "Contact" ]
]
]
]
, text " "
]
]
, section [ id "services" ]
[-- More content
]
-- Much more content
, section [ id "contact" ]
[-- More content
]
]
-- partial update
case msg of
ClickedElem elem ->
-- Sends the clicked element '#services' to the JS world
( model, clickedElem elem )
ChangeLocation newLocation ->
( { model
| location = newLocation
}
, Cmd.none
)
-- the port
port clickedElem : String -> Cmd msg
port changeLoc : (String -> msg) -> Sub msg
-- subscription
subscriptions model =
Sub.batch
[ Window.resizes Update.Resize
, Update.changeLoc Update.ChangeLocation
]
然后在 JS 端使用 jQuery animate / scrollTo 函数,如下所示:
<script>
app.ports.clickedElem.subscribe(function(id){
console.log("Scrolling.");
// Why isn't this working properly?
$('html, body').animate({
scrollTop: $(id).offset().top
}, 2000);
// return false;
app.ports.changeLoc.send(id);
});
</script>
最后,新位置通过一个名为 changeLoc
的端口传回了 Elm,它刚刚更新了我的模型。
我在这里错过了什么?这是由于 Elm 的 virtual-dom 导致的问题吗?我似乎无法弄清楚这一点。
提供的锚点的偏移量都很好,函数得到了预期的调用。
解决此问题的方法如下:
我没有使用 onClick
,而是使用了@ChadGilbert 的提示,并选择了 onWithOptions
,我将 preventDefault
设置为 True
。
结果:
onWithOptions "click" { stopPropagation = True, preventDefault = True } (Json.succeed (Update.ClickedElem "#anchor"))
而不是
onClick (Update.ClickedElem "#anchor")
谢谢!
您 header 中的链接是使用 onClick
创建的,并且由于您设置了 href
参数,事件将冒泡由浏览器处理,即为什么你会立即跳转。
在Javascript中,禁用默认浏览器行为和事件传播的方法是使用event.stopPropagation()
和event.preventDefault()
。
在 Elm 中,您可以使用 onWithOptions
创建设置这些值的事件属性。您可以使用以下而不是 onClick
来抑制在您的 Elm 代码处理后对点击事件的任何进一步处理:
onClickFullStop : msg -> Html.Attribute msg
onClickFullStop =
let fullStop = { stopPropagation = True, preventDefault = True }
in onWithOptions "click" fullStop << Json.Decode.succeed
当我使用 jQuery 为滚动行为设置动画时,第一次单击将导致视图直接跳转到单击的锚元素。 第二次点击,如果在动画延迟内发出,将完美运行。 如果动画延迟 运行 结束后再次发出点击,则会再次直接跳转到该元素。
这是演示该问题的简短 gif:
如你所见,我点击services
,瞬间跳转。我等到动画延迟运行s关闭后点击portfolio
,又是瞬间跳转。但随后我再次快速单击 services
(动画延迟尚未 运行 关闭)并且它按预期工作。
我的 Elm 应用程序已将 onClick
事件分配给某些元素。触发时,元素的 href
通过端口传递给 JavaScript 函数,如下所示:
-- partial view
view =
div []
[ nav [ class "navbar navbar-default navbar-fixed-top" ]
[ div [ class "container" ]
[ div [ class "navbar-header page-scroll" ]
[ button [ class "navbar-toggle", attribute "data-target" "#bs-example-navbar-collapse-1", attribute "data-toggle" "collapse", type' "button" ]
[ span [ class "sr-only" ]
[ text "Toggle navigation" ]
, span [ class "icon-bar" ]
[]
, span [ class "icon-bar" ]
[]
, span [ class "icon-bar" ]
[]
]
, a [ class "navbar-brand page-scroll", href "#page-top", onClick (Update.ClickedElem "#page-top") ]
[ text "Start Bootstrap" ]
]
, div [ class "collapse navbar-collapse", id "bs-example-navbar-collapse-1" ]
[ ul [ class "nav navbar-nav navbar-right" ]
[ li [ class "hidden" ]
[ a [ href "#page-top" ]
[]
]
, li []
[ a [ class "page-scroll", href "#services", onClick (Update.ClickedElem "#services") ]
[ text "Services" ]
]
, li []
[ a [ class "page-scroll", href "#portfolio", onClick (Update.ClickedElem "#portfolio") ]
[ text "Portfolio" ]
]
, li []
[ a [ class "page-scroll", href "#about", onClick (Update.ClickedElem "#about") ]
[ text "About" ]
]
, li []
[ a [ class "page-scroll", href "#team", onClick (Update.ClickedElem "#team") ]
[ text "Team" ]
]
, li []
[ a [ class "page-scroll", href "#contact", onClick (Update.ClickedElem "#contact") ]
[ text "Contact" ]
]
]
]
, text " "
]
]
, section [ id "services" ]
[-- More content
]
-- Much more content
, section [ id "contact" ]
[-- More content
]
]
-- partial update
case msg of
ClickedElem elem ->
-- Sends the clicked element '#services' to the JS world
( model, clickedElem elem )
ChangeLocation newLocation ->
( { model
| location = newLocation
}
, Cmd.none
)
-- the port
port clickedElem : String -> Cmd msg
port changeLoc : (String -> msg) -> Sub msg
-- subscription
subscriptions model =
Sub.batch
[ Window.resizes Update.Resize
, Update.changeLoc Update.ChangeLocation
]
然后在 JS 端使用 jQuery animate / scrollTo 函数,如下所示:
<script>
app.ports.clickedElem.subscribe(function(id){
console.log("Scrolling.");
// Why isn't this working properly?
$('html, body').animate({
scrollTop: $(id).offset().top
}, 2000);
// return false;
app.ports.changeLoc.send(id);
});
</script>
最后,新位置通过一个名为 changeLoc
的端口传回了 Elm,它刚刚更新了我的模型。
我在这里错过了什么?这是由于 Elm 的 virtual-dom 导致的问题吗?我似乎无法弄清楚这一点。 提供的锚点的偏移量都很好,函数得到了预期的调用。
解决此问题的方法如下:
我没有使用 onClick
,而是使用了@ChadGilbert 的提示,并选择了 onWithOptions
,我将 preventDefault
设置为 True
。
结果:
onWithOptions "click" { stopPropagation = True, preventDefault = True } (Json.succeed (Update.ClickedElem "#anchor"))
而不是
onClick (Update.ClickedElem "#anchor")
谢谢!
您 header 中的链接是使用 onClick
创建的,并且由于您设置了 href
参数,事件将冒泡由浏览器处理,即为什么你会立即跳转。
在Javascript中,禁用默认浏览器行为和事件传播的方法是使用event.stopPropagation()
和event.preventDefault()
。
在 Elm 中,您可以使用 onWithOptions
创建设置这些值的事件属性。您可以使用以下而不是 onClick
来抑制在您的 Elm 代码处理后对点击事件的任何进一步处理:
onClickFullStop : msg -> Html.Attribute msg
onClickFullStop =
let fullStop = { stopPropagation = True, preventDefault = True }
in onWithOptions "click" fullStop << Json.Decode.succeed