▲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,你需要知道:windowsdocumentselementsnodes

Window
一个Window对象代表一个Web浏览器的实际窗口。每个Window都有一个Document对象,它指向当前被加载的文档。Window对象还具有各种API的访问器,如IndexedDB(存储数据)、requestAnimationFrame(动画)等等。在选项卡式浏览器中,每个选项卡都有自己的窗口对象。
Document & Element
使用Document对象,你可以在文档中创建和操作Element对象。注意,文档本身也是一个Element,也可以被操作。
Nodes
DOM建模了一个节点树:Nodes。这些节点通常是elements,但它们也可能是attributes,text,comments或者其他DOM类型。除了根节点——没有父元素,每个DOM中的节点都有一个父元素并且可能有许多子元素。

  1. 查找元素:
    为了操作一个元素,你首先需要一个能代表这个元素的对象。你可以通过使用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');
  1. 操作元素:
    你可以使用属性来改变元素的状态。Node和它的子类型元素都定义了通用的元素属性。例如,所有元素都有classeshiddenidstyletitle,你可以用这些属性去设置元素的状态。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';
  1. 创建元素:
    你可以通过创建新元素并将它们附加到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);
  1. 添加,替换,删除节点:
    回想一下,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();
  1. 操作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';
  1. 处理事件:
    要响应外部事件,如单击、焦点更改和选择,请添加事件侦听器。你可以向页面上的任何元素添加事件侦听器。事件调度与传播是一个复杂的课题,更详细请参见: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服务器。

  1. 从服务器获取数据:
    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.
  1. 发送数据到服务器:
    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');
  1. 发送数据:
    在WebSocket上发送字符串数据,使用send()方法:
ws.send('Hello from Dart!');
  1. 接收数据:
    接收来自WebSocket的数据,注册消息事件的监听器:
ws.onMessage.listen((MessageEvent e) 
    print('Received message: $e.data');
);

消息事件处理程序接收MessageEvent对象。此对象的data字段包含来自服务器的数据。

  1. 处理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 audioIndexedDBWebGL)提供了额外的库。
有关Dart web库的更多信息,请参阅web library overview

以上是关于▲Dart-‘dart:html’库的主要内容,如果未能解决你的问题,请参考以下文章

★Dart-2-Dart工具集

WebStorm-Dart导入错误

dart:io 或 dart:html 的条件导入

未找到:“dart:html”导入“dart:html”;我不需要 dart:html 我也没有使用过,但我尝试通过导入它,但错误不会发生

#yyds干货盘点#dart系列之:HTML的专属领域,除了javascript之外,dart也可以

颤振构建找不到'dart:html'