▲Dart-‘dart:html’库
Posted itzyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了▲Dart-‘dart:html’库相关的知识,希望对你有一定的参考价值。
dart:html
- 基于浏览器应用
使用dart:html库编程浏览器,操作DOM中的对象和元素,并访问HTML5 APIs。DOM代表文档对象模型(Document Object Model),它描述HTML页面的层次结构。
dart:html的其他常见用途包括操纵样式(CSS)、使用HTTP请求获取数据以及使用WebSocket交换数据。HTML5(和dart:html)有许多本节没有介绍的附加API。
只有web应用程序可以使用dart:html,而不是命令行应用程序。
备忘:
对于更大的应用程序,或者如果已经有了Flutter应用程序,请考虑使用Flutter for web进行Web处理。
1. 操作DOM
为了使用DOM,你需要知道:windows
,documents
,elements
,nodes
。
➊Window
一个Window对象代表一个Web浏览器的实际窗口。每个Window都有一个Document对象,它指向当前被加载的文档。Window对象还具有各种API的访问器,如IndexedDB(存储数据)、requestAnimationFrame(动画)等等。在选项卡式浏览器中,每个选项卡都有自己的窗口对象。
➋Document & Element
使用Document对象,你可以在文档中创建和操作Element对象。注意,文档本身也是一个Element,也可以被操作。
➌Nodes
DOM建模了一个节点树:Nodes。这些节点通常是elements,但它们也可能是attributes,text,comments或者其他DOM类型。除了根节点——没有父元素,每个DOM中的节点都有一个父元素并且可能有许多子元素。
- 查找元素:
为了操作一个元素,你首先需要一个能代表这个元素的对象。你可以通过使用query来得到这个对象。
查找一个或多个元素,可使用顶级函数querySelector()
和querySelectorAll()
。你可以通过ID、class、tag、name或这几个的结合来实现query操作。CSS选择器规范指南(CSS Selector Specification guide)定义了选择器格式,如通过“#”前缀指定IDs、通过“.”前缀指定classes。
querySelector()
返回匹配选择器的第一个元素;querySelectorAll()
返回匹配选择器的元素集合。
// Find an element by id (myid).
Element idElement = querySelector('#myid')!;
// Find an element by class (myclass).
Element classElement = querySelector('.myclass')!;
// Find all elements by tag (<div>).
List<Element> divElements = querySelectorAll('div');
// Find all text inputs.
List<Element> textInputElements = querySelectorAll('input[type="text"]',);
// Find all elements with the CSS class 'myclass' inside of a <p>
// that is inside an element with the ID 'myid'.
List<Element> specialParagraphElements = querySelectorAll('#myid p.myclass');
- 操作元素:
你可以使用属性来改变元素的状态。Node和它的子类型元素都定义了通用的元素属性。例如,所有元素都有classes
、hidden
、id
、style
、title
,你可以用这些属性去设置元素的状态。Element的子类定义了一些额外的属性,例如AnchorElement的href
属性。
下面示例指定了一个HTML的锚点元素:
<a id="example" href="/another/example">link text</a>
此<a>标记指定具有href
属性的元素和包含字符串“link text”的文本节点(可通过text
属性访问)。要更改链接指向的URL,可以使用AnchoreElement的href属性:
var anchor = querySelector('#example') as AnchorElement;
anchor.href = 'https://dart.dev';
通常需要在多个元素上设置属性。例如,下面的代码设置了所有元素的hidden
属性,这些元素的class为“mac”、“win”或“linux”。将hidden
属性设置为true与向CSS添加display:none
具有相同的效果。
<p>
<span class="linux">Words for Linux</span>
<span class="macos">Words for Mac</span>
<span class="windows">Words for Windows</span>
</p>
const osList = ['macos', 'windows', 'linux'];
final userOs = determineUserOs();
// For each possible OS...
for (final os in osList)
// Matches user OS?
bool shouldShow = (os == userOs);
// Find all elements with class=os. For example, if
// os == 'windows', call querySelectorAll('.windows')
// to find all elements with the class "windows".
// Note that '.$os' uses string interpolation.
for (final elem in querySelectorAll('.$os'))
elem.hidden = !shouldShow; // Show or hide.
当右属性不可用或不方便时,可以使用元素的attributes
属性。此属性是一个Map<String, String>,其中键是属性名。有关属性名称及其含义的列表,请参见MDN Attributes page。下面是设置属性值的示例:
elem.attributes['someAttribute'] = 'someValue';
- 创建元素:
你可以通过创建新元素并将它们附加到DOM来添加到现有HTML页面。下面是创建段落(<p>)元素的示例:
var elem = ParagraphElement();
elem.text = 'Creating is easy!';
你还可以通过解析HTML文本来创建元素。任何子元素也会被解析和创建。
var elem2 = Element.html(// 对于上例,elem2是ParagraphElement。
'<p>Creating <em>is</em> easy!</p>',
);
通过为元素指定父元素,将新创建的元素附加到文档。可以将元素添加到任何现有元素的子元素中。在下面的示例中,body是一个元素,其子元素可以从children
属性访问(作为List<Element>)。
document.body!.children.add(elem2);
- 添加,替换,删除节点:
回想一下,elements只是一种node。你可以使用node的nodes
属性查找节点的所有子节点,该属性返回一个List<Node>(与children
属性相反,children
属性忽略非元素节点(non-Element nodes)。nodes
包括元素节点和文本节点,而children
只包括元素节点。)。拥有此列表后,可以使用常用的列表方法和运算符来操作节点的子节点。
要将节点添加为其父节点的最后一个子节点,请使用List
add()
方法:
querySelector('#inputs')!.nodes.add(elem);
替换一个节点,使用Node
replaceWith()
方法:
querySelector('#status')!.replaceWith(elem);
删除一个节点,使用Node
remove()
方法:
// Find a node by ID, and remove it from the DOM if it is found.
querySelector('#expendable')?.remove();
- 操作CSS样式:
CSS级联样式表(cascading style sheets)定义DOM元素的表示样式。可以通过向元素附加ID和class属性来更改元素的外观。
每个元素都有一个classes
字段,它是一个列表。添加和删除CSS class只需在此列表中添加和删除字符串。例如,以下示例将警告class添加到元素中:
var elem = querySelector('#message')!;
elem.classes.add('warning');
通过ID查找元素通常非常有效。你可以使用id
属性动态设置元素ID:
var message = DivElement();
message.id = 'message2';
message.text = 'Please subscribe to the Dart mailing list.';
你可以使用方法级联来减少冗余文本:
var message = DivElement()
..id = 'message2'
..text = 'Please subscribe to the Dart mailing list.';
使用IDs和classes将元素与一组样式关联是最佳做法,但有时你希望将特定样式直接附加到元素:
message.style
..fontWeight = 'bold'
..fontSize = '3em';
- 处理事件:
要响应外部事件,如单击、焦点更改和选择,请添加事件侦听器。你可以向页面上的任何元素添加事件侦听器。事件调度与传播是一个复杂的课题,更详细请参见:research the details。
添加一个事件处理,使用element.onEvent.listen(function)
,其中Event是事件名称,function是事件处理器。
// Find a button by ID and add an event handler.
querySelector('#submitInfo')!.onClick.listen((e)
// When the button is clicked, it runs this code.
submitData();
);
事件可以通过DOM树上下传播。为找到最初触发事件的元素,可使用e.target
:
document.body!.onClick.listen((e)
final clickedElem = e.target;
// ...
);
要查看可以注册事件侦听器的所有事件,请在Element及其子类的API文档中查找“onEventType
”属性。一些常见事件包括:change、blur、keyDown、keyUp、mouseDown、mouseUp
2. 用HttpRequest使用HTTP资源
以前称为XMLHttpRequest,HttpRequest类允许你从基于浏览器的应用程序中访问HTTP资源。传统上,AJAX风格的应用程序大量使用HttpRequest。使用HttpRequest从web服务器动态加载JSON数据或任何其他资源。你还可以动态地将数据发送到web服务器。
- 从服务器获取数据:
HttpRequest静态方法getString()
是从web服务器获取数据的一种简单方法。在getString()调用中使用await
,以确保在继续执行之前拥有数据。
Future<void> main() async
String pageHtml = await HttpRequest.getString(url);
// Do something with pageHtml...
使用try-catch指定一个错误处理器:
try
var data = await HttpRequest.getString(jsonUri);
// Process data...
catch (e)
// Handle exception...
如果你需要访问HttpRequest,而不仅仅是它检索的文本数据,那么可以使用request()
静态方法而不是getString()。下面是一个读取XML数据的示例:
Future<void> main() async
HttpRequest req = await HttpRequest.request(url, method: 'HEAD');
if (req.status == 200)
// Successful URL access...
// ···
你还可以使用完整的API来处理更有趣的情况。例如,可以设置任意headers。
使用HttpRequest的完整API的一般流程如下:
1.创建HttpRequest对象。
2.使用GET或POST打开URL。
3.附加事件处理程序。
4.发送请求。
var request = HttpRequest();// 1.
request
..open('POST', url)// 2.
..onLoadEnd.listen((e) => requestComplete(request))// 3.
..send(encodedData);// 4.
- 发送数据到服务器:
HttpRequest可以使用HTTP POST方法向服务器发送数据。例如,你可能希望向表单处理程序动态提交数据。向RESTful web服务发送JSON数据是另一个常见的例子。
向表单处理程序提交数据需要提供name-value对作为URI编码字符串。如果希望向表单处理程序发送数据,还必须将Content-type
header设置为application/x-www-form-urlencoded
。
String encodeMap(Map<String, String> data) => data.entries
.map((e) => '$Uri.encodeComponent(e.key)=$Uri.encodeComponent(e.value)')
.join('&');
Future<void> main() async
const data = 'dart': 'fun', 'angular': 'productive';
var request = HttpRequest();
request
..open('POST', url)
..setRequestHeader(
'Content-type',
'application/x-www-form-urlencoded',
)
..send(encodeMap(data));
await request.onLoadEnd.first;
if (request.status == 200)
// Successful URL access...
// ···
3. 用WebSockets发送和接收实时数据
WebSocket
允许你的web应用与服务器交互交换数据,无需轮询。服务器创建WebSocket并侦听以ws://
开头,例如,[ws://127.0.0.1:1337/myws]的URL上的请求。通过WebSocket传输的数据可以是字符串或二进制。通常,数据是JSON格式的字符串。
要在web应用程序中使用WebSocket,请首先创建WebSocket对象,并将WebSocket URL作为参数传递:
var ws = WebSocket('ws://echo.websocket.org');
- 发送数据:
在WebSocket上发送字符串数据,使用send()
方法:
ws.send('Hello from Dart!');
- 接收数据:
接收来自WebSocket的数据,注册消息事件的监听器:
ws.onMessage.listen((MessageEvent e)
print('Received message: $e.data');
);
消息事件处理程序接收MessageEvent对象。此对象的data
字段包含来自服务器的数据。
- 处理WebSocket事件:
你的应用程序可以处理以下WebSocket事件:打开(open)、关闭(close)、错误(error)、消息(message)。下面是一个创建WebSocket对象并注册打开、关闭、错误和消息事件处理程序的方法示例:
void initWebSocket([int retrySeconds = 1])
var reconnectScheduled = false;
print('Connecting to websocket');
void scheduleReconnect()
if (!reconnectScheduled)
Timer(Duration(seconds: retrySeconds), () => initWebSocket(retrySeconds * 2));
reconnectScheduled = true;
ws.onOpen.listen((e)
print('Connected');
ws.send('Hello from Dart!');
);
ws.onClose.listen((e)
print('Websocket closed, retrying in $retrySeconds seconds');
scheduleReconnect();
);
ws.onError.listen((e)
print('Error connecting to ws');
scheduleReconnect();
);
ws.onMessage.listen((MessageEvent e)
print('Received message: $e.data');
);
4. 更多
这一部分仅仅触及了使用dart:html库的皮毛。有关更多信息,请参阅dart:html的文档。Dart为更专业的web API(如web audio、IndexedDB和WebGL)提供了额外的库。
有关Dart web库的更多信息,请参阅web library overview。
以上是关于▲Dart-‘dart:html’库的主要内容,如果未能解决你的问题,请参考以下文章
未找到:“dart:html”导入“dart:html”;我不需要 dart:html 我也没有使用过,但我尝试通过导入它,但错误不会发生