无法将 JavaScript 翻译成 ReScript
Trouble translating JavaScript to ReScript
我想使用 ReScript 实现交互式滑块,所以我想将此 JavaScript 转换为 ReScript(礼貌:https://www.w3schools.com/howto/howto_js_rangeslider.asp):
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value; // Display the default slider value
// Update the current slider value (each time you drag the slider handle)
slider.oninput = function() {
output.innerHTML = this.value;
}
其中目标 HTML (slider.html
) 是:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #04AA6D;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #04AA6D;
cursor: pointer;
}
</style>
</head>
<body>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<script src="./bundled.bs.js"></script>
</body>
</html>
其中 bundled.bs.js
是将已编译的 .bs.js
代码与 Browerify
.
捆绑在一起的结果
到目前为止,我已经使用 rescript-webapi 编写了以下代码:
open Webapi.Dom
open Belt.Option
@val external document: Document.t = "document"
let slider = getExn(Document.getElementById("myRange", document))
let output = getExn(Document.getElementById("demo", document))
Element.setInnerText(output, getExn(Element.getAttribute("value", slider)))
Element.addEventListener("value", _ =>
Element.setInnerHTML(output, getExn(Element.getAttribute("value", slider))), slider)
但是,这并没有达到预期效果;我可以看到滑块并四处滑动,但输入标签的值没有更新:
我的 ReScript 翻译缺少什么?
+更新:
@glennsl 为我提供了以下代码:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.getAttribute("value")->Option.getExn
output->Element.setInnerHTML(value)
})
我可以看到 Value:
具有正确的初始值 50
。
但是,即使我重新定位滑块,该值也不会更新:
如上所述,我将这段代码(称为slider.res
)编译成slider.bs.js
并与browserify slider.bs.js -o bundled.bs.js
捆绑在一起。
没有名为 value
的活动。您正在翻译的 JavaScript 代码使用的是 input
(oninput
).
您还在混淆“数据优先”和“数据最后”。 rescript-webapi
使用“数据优先”,而 bs-webapi
是 rescript-webapi
的分支,使用“数据最后”。您可能基于 bs-webapi
.
中的示例代码
无论如何,这应该适用于 rescript-webapi
:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.getAttribute("value")->Option.getExn
output->Element.setInnerHTML(value)
})
呃,主要问题有两个:
正如@glennsl 所指出的,事件名称是错误的。应该是"input"
,不是"value"
.
我把this.value
误认为是this
的value
属性,也就是slider
。实际上,这是将 slider
视为 HTML 输入元素,并引用其 输入值 .
由于我们不能直接将 Dom.Element.t
转换为 Dom.HtmlInputElement.t
,我们首先将其转换为 Dom.Node.t
,然后再转换为 Dom.HtmlInputElement.t
。因此,基于@glennsl 的代码,代码是:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.asNode->HtmlInputElement.ofNode->Option.getExn->HtmlInputElement.value
output->Element.setInnerHTML(value)
})
我想使用 ReScript 实现交互式滑块,所以我想将此 JavaScript 转换为 ReScript(礼貌:https://www.w3schools.com/howto/howto_js_rangeslider.asp):
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value; // Display the default slider value
// Update the current slider value (each time you drag the slider handle)
slider.oninput = function() {
output.innerHTML = this.value;
}
其中目标 HTML (slider.html
) 是:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #04AA6D;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #04AA6D;
cursor: pointer;
}
</style>
</head>
<body>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<script src="./bundled.bs.js"></script>
</body>
</html>
其中 bundled.bs.js
是将已编译的 .bs.js
代码与 Browerify
.
到目前为止,我已经使用 rescript-webapi 编写了以下代码:
open Webapi.Dom
open Belt.Option
@val external document: Document.t = "document"
let slider = getExn(Document.getElementById("myRange", document))
let output = getExn(Document.getElementById("demo", document))
Element.setInnerText(output, getExn(Element.getAttribute("value", slider)))
Element.addEventListener("value", _ =>
Element.setInnerHTML(output, getExn(Element.getAttribute("value", slider))), slider)
但是,这并没有达到预期效果;我可以看到滑块并四处滑动,但输入标签的值没有更新:
我的 ReScript 翻译缺少什么?
+更新:
@glennsl 为我提供了以下代码:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.getAttribute("value")->Option.getExn
output->Element.setInnerHTML(value)
})
我可以看到 Value:
具有正确的初始值 50
。
如上所述,我将这段代码(称为slider.res
)编译成slider.bs.js
并与browserify slider.bs.js -o bundled.bs.js
捆绑在一起。
没有名为 value
的活动。您正在翻译的 JavaScript 代码使用的是 input
(oninput
).
您还在混淆“数据优先”和“数据最后”。 rescript-webapi
使用“数据优先”,而 bs-webapi
是 rescript-webapi
的分支,使用“数据最后”。您可能基于 bs-webapi
.
无论如何,这应该适用于 rescript-webapi
:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.getAttribute("value")->Option.getExn
output->Element.setInnerHTML(value)
})
呃,主要问题有两个:
正如@glennsl 所指出的,事件名称是错误的。应该是
"input"
,不是"value"
.我把
this.value
误认为是this
的value
属性,也就是slider
。实际上,这是将slider
视为 HTML 输入元素,并引用其 输入值 .
由于我们不能直接将 Dom.Element.t
转换为 Dom.HtmlInputElement.t
,我们首先将其转换为 Dom.Node.t
,然后再转换为 Dom.HtmlInputElement.t
。因此,基于@glennsl 的代码,代码是:
open Webapi.Dom
open Belt
let slider = document->Document.getElementById("myRange")->Option.getExn
let output = document->Document.getElementById("demo")->Option.getExn
output->Element.setInnerText(slider->Element.getAttribute("value")->Option.getExn)
slider->Element.addEventListener("input", _ => {
let value = slider->Element.asNode->HtmlInputElement.ofNode->Option.getExn->HtmlInputElement.value
output->Element.setInnerHTML(value)
})