我想在寓言中有一个琐碎的显示/隐藏内容行为。 类似于this。
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<button onclick="myFunction()">Click Me</button>
<div id="myDIV">
This is my DIV element.
</div>
最合适的方法是什么?
答案 0 :(得分:5)
这是一个比您意识到的要大得多的问题,因为在下面是“我应该如何最好地安排我的寓言应用程序”的问题?您在答案中采用的方法与在Javascript应用程序中使用JQuery大致平行:您编写直接操纵DOM以获得所需结果的代码。如果那是您选择的建筑风格-对于真正简单的应用程序,这是一个完美的选择-那么您的答案就不会有太多改善。 “直接操作DOM”方法唯一会遇到问题的情况是,您的应用程序的大小会变得比平凡大。届时,您将需要一个更好的体系结构。稍后我将推荐一个更好的体系结构,但首先,我建议对您的代码进行一些细微调整。将toggle
函数移到toggleButton
之外将使其更加通用:
module Markup
open System
open Fable.Helpers.React
open Fable.Helpers.React.Props
open Fable.Import
let toggleBlockElem id _ =
let contentElement = Browser.document.getElementById id
let display = if contentElement.style.display = "none" then "block" else "none"
contentElement.style.display <- display
let toggleButton text content =
let id = Guid.NewGuid().ToString()
div []
[
button [ OnClick (toggleBlockElem id) ] [ str text ]
div [ Id id ] [ str content ]
]
如果您发现自己需要这些功能,可以在toggleLink
或toggleCheckbox
之类的函数中重复使用此功能。
现在,我之前提到过,如果您的Web应用程序变大,我会建议使用其他体系结构。我推荐的架构是Elmish。它基于Elm中使用的体系结构;如果您不熟悉它,其基本思想类似于React。这是一个模型/更新/视图架构。 模型是一个不变的数据结构。还定义了消息类型;在Elmish中,这可能是F#歧视的工会。 更新函数将模型和消息作为两个参数,并返回一个新模型。 view 函数采用一个模型和一个“ dispatch ”函数作为其两个参数(Elmish将提供“ dispatch”函数,您不必编写它)并返回类似HTML元素的抽象树。然后,Elmish将这些元素传递给诸如React之类的东西,以进行实际的DOM更新。 (实际上,根据Elm的the one described here过程,反应将区分“旧” DOM树和“新” DOM树)。
所有这些都需要花很多钱,因此让我们看一个简单的示例,该示例仅切换div
的可见性。 注意:我尚未对此进行测试,只是将其输入到“堆栈溢出”答案框中。以下代码中可能存在错误;它仅是说明性示例,而不是工作示例。 (有关运行中的Elmish的一个非常详尽的工作示例,请参见https://mangelmaxime.github.io/fulma-demo/ -尽管请注意,该示例具有在数据模型中包含多个父子层次结构“层”的高级体系结构,可能很难包装您的乍一看。
让我们从定义数据模型开始。由于这是一个简单的示例,因此该模型同样是简单的。实际上,这很琐碎,我将向其中添加一些额外的数据,以便使用记录类型而不是单个布尔值实际上是有意义的:
type Model = { Visible: bool;
DataNotAppearingInThisFilm: int }
(更高级的模型可能涉及Map<string, bool>
类型,以跟踪多个div
的可见状态)。
消息类型也是微不足道的,因此为了使它有趣一点,我们将允许“显示”,“隐藏” 和“切换”消息:
type Msg =
| Show
| Hide
| Toggle
(更高级的版本是Show of string
等,将div的ID传递给显示)。
update
函数同样简单:
let update msg model =
match msg with
| Show -> { model with Visible = true }
| Hide -> { model with Visible = false }
| Toggle -> { model with Visible = not model.Visible }
最后,view
函数将如下所示:
let view model dispatch =
div []
[
button [ OnClick (fun _ -> dispatch Toggle) ] [ str (if model.Visible then "Hide" else "Show") ]
div [ Display (if model.Visible then "block" else "none") ] [ str "content" ]
]
或者,将toggleButton
拉出自己的功能,以便我可以演示其工作原理:
let toggleButton dispatch text content =
div []
[
button [ OnClick (fun _ -> dispatch Toggle) ] [ str text ]
div [ Display (if model.Visible then "block" else "none") ] [ str content ]
]
let view model dispatch =
div []
[
str "Other elements might go here"
toggleButton dispatch (if model.Visible then "Hide" else "Show") "content"
]
请注意我需要如何将dispatch
函数作为参数传递给toggleButton
,以便toggleButton
能够为其OnClick
构造正确的行为。
将所有这些放在一起看起来像这样:
open ALotOfModules
type Model = { Visible: bool;
DataNotAppearingInThisFilm: int }
type Msg =
| Show
| Hide
| Toggle
let update msg model =
match msg with
| Show -> { model with Visible = true }
| Hide -> { model with Visible = false }
| Toggle -> { model with Visible = not model.Visible }
let toggleButton dispatch text content =
div []
[
button [ OnClick (fun _ -> dispatch Toggle) ] [ str text ]
div [ Display (if model.Visible then "block" else "none") ] [ str content ]
]
let view model dispatch =
div []
[
str "Other elements might go here"
toggleButton dispatch (if model.Visible then "Hide" else "Show") "content"
]
答案 1 :(得分:0)
我的最佳尝试是从问题链接中愚蠢地翻译JavaScript:
module Markup
open System
open Fable.Helpers.React
open Fable.Helpers.React.Props
open Fable.Import
let toggleButton text content =
let id = Guid.NewGuid().ToString()
let toggle _ =
let contentElement = Browser.document.getElementById id
let display = if contentElement.style.display = "none" then "block" else "none"
contentElement.style.display <- display
div []
[
button [ OnClick toggle ] [ str text ]
div [ Id id ] [ str content ]
]
要像Markup.toggleButton "title" "a lot of content"