当前位置: 首页 > article >正文

HTMLElement、customElements及元素拓展

文章目录

    • HTMLElement 与 customElements
    • customElements.define() 方法说明
    • HTML 元素方法拓展

HTMLElement 与 customElements

  1. HTMLElement
    • 概述
      • HTMLElement是一个接口,它表示所有HTML元素。几乎所有的HTML标签(如<div><p><a>等)在DOM(文档对象模型)中都是HTMLElement接口的实例。它继承自Element接口,提供了一系列用于操作HTML元素的属性和方法。
    • 属性示例
      • id:用于获取或设置元素的唯一标识符。例如,在HTML中有<div id="myDiv"></div>,可以通过JavaScript访问document.getElementById('myDiv').id来获取或修改这个id属性。
      • classList:这是一个只读属性,返回一个DOMTokenList,包含了元素的类名。可以使用add()remove()toggle()等方法来操作类名。比如,document.querySelector('p').classList.add('highlight')会给选中的<p>元素添加一个名为highlight的类。
      • style:用于获取或设置元素的内联样式。例如,document.getElementById('myDiv').style.backgroundColor = 'blue';会将idmyDiv的元素的背景色设置为蓝色。
    • 方法示例
      • getAttribute()setAttribute():用于获取和设置元素的属性。例如,对于<img src="image.jpg" alt="An image">,可以通过document.querySelector('img').getAttribute('alt')获取alt属性的值,也可以通过document.querySelector('img').setAttribute('title', 'This is an image')来添加一个title属性。
      • appendChild():用于将一个节点添加到当前元素的子节点列表的末尾。例如,创建一个新的<span>元素并添加到<div>元素中:
        let div = document.createElement('div');
        let span = document.createElement('span');
        div.appendChild(span);
        
  2. customElements
    • 概述
      • customElements是一个用于定义自定义HTML元素的API。它允许开发者创建自己的HTML标签,这些自定义元素可以像原生HTML元素一样在HTML文档中使用,并且可以有自己的行为、样式和属性。
    • 自定义元素定义方法
      • 使用customElements.define()方法来定义一个自定义元素。这个方法接受两个参数:元素的名称(必须包含一个连字符,以区别于原生HTML元素)和一个类,这个类用于定义元素的行为。例如:
        class MyCustomElement extends HTMLElement {
          constructor() {
            super();
            this.textContent = 'This is my custom element';
          }
        }
        customElements.define('my-custom-element', MyCustomElement);
        
      • 在HTML中就可以像使用其他元素一样使用<my - custom - element></my - custom - element>,它会显示文本This is my custom element
    • 相关方法扩展及元素定义示例 - 生命周期回调方法
      • connectedCallback:当自定义元素被添加到文档DOM时调用。例如,可以在这个方法中设置元素的初始样式或添加事件监听器。
        class MyCustomElement extends HTMLElement {
          constructor() {
            super();
          }
          connectedCallback() {
            this.style.backgroundColor = 'yellow';
            this.addEventListener('click', () => {
              console.log('Element clicked');
            });
          }
        }
        customElements.define('my-custom-element', MyCustomElement);
        
      • disconnectedCallback:当自定义元素从文档DOM中移除时调用。可以用于清理资源,如移除事件监听器。
        class MyCustomElement extends HTMLElement {
          constructor() {
            super();
          }
          connectedCallback() {
            this.addEventListener('click', this.clickHandler.bind(this));
          }
          clickHandler() {
            console.log('Clicked');
          }
          disconnectedCallback() {
            this.removeEventListener('click', this.clickHandler.bind(this));
          }
        }
        customElements.define('my - custom - element', MyCustomElement);
        
      • attributeChangedCallback:当自定义元素的属性发生变化时调用。需要先定义一个observedAttributes静态方法来指定要观察的属性。例如:
        class MyCustomElement extends HTMLElement {
          static get observedAttributes() {
            return ['data-value'];
          }
          constructor() {
            super();
          }
          attributeChangedCallback(name, oldValue, newValue) {
            if (name === 'data-value') {
          console.log(`Attribute data-value changed from ${oldValue} to ${newValue}`);
            }
          }
        }
        customElements.define('my-custom-element', MyCustomElement);
        
        当在HTML中改变<my -custom-element data-value="1"></my-custom-element>data-value属性时,attributeChangedCallback方法就会被触发。

customElements.define() 方法说明

  1. 语法

    • customElements.define(name, constructor, options)。这是一个静态方法,用于在全局customElements对象上定义一个新的自定义HTML元素。
  2. 参数

    • name参数
      • 类型:字符串。
      • 描述:这是自定义元素的名称。它必须包含一个连字符(-),这是为了与原生HTML元素名称区分开来。例如,my - custom - element是一个有效的自定义元素名称,而mycustomelement(没有连字符)是不符合规范的。这是一种命名约定,有助于避免与未来可能添加的原生HTML元素名称冲突。
      • 示例
        customElements.define('my-special-button', MyButtonElement);
        
    • constructor参数
      • 类型:一个继承自HTMLElement的类(构造函数)。
      • 描述:这个类定义了自定义元素的行为和结构。在这个类中,可以通过定义构造函数(constructor)方法来初始化元素的内容,通过connectedCallback方法来定义元素插入到DOM后的行为,通过disconnectedCallback方法来定义元素从DOM中移除后的行为,以及通过attributeChangedCallback方法来响应元素属性的变化。
      • 示例
        class MyButtonElement extends HTMLElement {
          constructor() {
            super();
            const button = document.createElement('button');
            button.textContent = 'Click me';
            this.appendChild(button);
          }
        }
        customElements.define('my - button', MyButtonElement);
        
        在这个示例中,MyButtonElement类是自定义元素my - button的构造函数。当这个自定义元素在HTML中被使用时,它会包含一个带有文本Click me<button>子元素。
    • options参数(可选)
      • 类型:一个对象。
      • 描述:这个参数用于扩展自定义元素的定义。目前,它主要包含一个属性extends,用于创建继承自现有HTML元素的自定义元素。如果使用extends属性,自定义元素将继承指定原生HTML元素的所有属性和方法,并且可以在此基础上添加自己的功能。
      • 示例
        class MyStyledInput extends HTMLInputElement {
          constructor() {
            super();
            this.style.border = '1px solid red';
          }
        }
        customElements.define('my-styled-input', MyStyledInput, {extends: 'input'});
        
        在这个示例中,my-styled-input是一个自定义元素,它继承自原生的<input>元素。当在HTML中使用<my-styled-input>时,它会表现得像一个普通的<input>元素,但同时具有一个红色边框的样式。这种继承方式使得可以在原生HTML元素的基础上进行定制,而不是从头开始构建一个全新的元素。

HTML 元素方法拓展

  1. 原型链扩展
    • 概述
      • 可以通过修改HTMLElement.prototype来为所有HTML元素添加新的方法或属性。不过这种方式需要谨慎使用,因为它会影响到所有的HTML元素。
    • 示例
      • 为所有HTML元素添加一个highlight方法,用于改变元素的背景颜色为黄色。
        HTMLElement.prototype.highlight = function() {
          this.style.backgroundColor = 'yellow';
        };
        // 在HTML中有一个 <div id="myDiv"></div>
        let myDiv = document.getElementById('myDiv');
        myDiv.highlight();
        
  2. 使用Object.defineProperty()Object.defineProperties()
    • 概述
      • 这些方法可以在单个元素或一组元素上定义新的属性。可以精确地控制属性的可枚举性、可写性和可配置性等特性。
    • 示例 - 定义单个属性
      • 为一个特定的<p>元素定义一个data-custom-attribute属性。
        let pElement = document.querySelector('p');
        Object.defineProperty(pElement, 'data-custom-attribute', {
          value: 'This is a custom property',
          writable: true,
          enumerable: true,
          configurable: true
        });
        console.log(pElement['data-custom-attribute']);
        
    • 示例 - 定义多个属性
      • 为一个<span>元素同时定义两个属性。
        let spanElement = document.querySelector('span');
        Object.defineProperties(spanElement, {
          'data-property-1': {
            value: 'Value 1',
            writable: true,
            enumerable: true,
            configurable: true
          },
          'data - property - 2': {
            value: 'Value 2',
            writable: true,
            enumerable: true,
            configurable: true
          }
        });
        console.log(spanElement['data-property-1']);
        console.log(spanElement['data-property-2']);
        
  3. 创建自定义指令(在框架中,如Vue.js或Angular)
    • 概述
      • 在前端框架中,自定义指令是一种强大的方式来扩展HTML元素的行为。以Vue.js为例,自定义指令可以用来操作DOM元素,实现诸如自动聚焦、防抖、节流等功能。
    • 示例(Vue.js)
      • 创建一个自动聚焦的自定义指令。
        Vue.directive('autofocus', {
          inserted: function (el) {
            el.focus();
          }
        });
        // 在Vue组件模板中使用
        <template>
          <input v - autofocus>
        </template>
        
      • 当这个<input>元素被渲染到DOM中时,它会自动获得焦点。在Angular中也有类似的机制,通过创建自定义指令来扩展HTML元素的功能,只是语法和具体实现细节有所不同。
  4. 使用CSS自定义属性(变量)和@apply规则(在CSS中)结合JavaScript操作来间接扩展元素行为
    • 概述
      • 虽然CSS自定义属性本身主要是用于样式方面,但可以与JavaScript结合来实现一些元素行为的扩展。可以通过JavaScript动态地改变CSS自定义属性的值,从而影响元素的外观和一些相关的行为(例如,改变主题颜色、布局等)。
    • 示例
      • 首先在CSS中定义一个自定义属性和一个使用该属性的规则。
       :root {
         --primary - color: blue;
       }
      .my - element {
         background - color: var(--primary - color);
       }
      
    • 然后通过JavaScript来改变这个自定义属性的值。
	let root = document.documentElement;
    root.style.setProperty('--primary-color', 'red');

这样,所有具有my-element类的元素的背景颜色就会从蓝色变为红色,从而间接改变了元素的外观相关的行为。


http://www.kler.cn/a/470273.html

相关文章:

  • 大数据高级ACP学习笔记(2)
  • Vue项目中的问题汇总(持续更新中)
  • 数值分析速成复习笔记
  • Tableau数据可视化与仪表盘搭建-数据可视化原理
  • 实习总结(项目篇)
  • 运动相机拍摄的视频打不开怎么办
  • 在Linux中,如何配置负载均衡器以分配网络流量?
  • GIT 企业级开发学习 1_基本操作
  • 简洁安装配置在Windows环境下使用vscode开发pytorch
  • Harmony开发【笔记1】报错解决(字段名写错了。。)
  • 【SpringBoot】28 API接口防刷(Redis + 拦截器)
  • 代码随想录算法训练营第三十天 | hot30/100| 49.字母异位词分组、128.最长连续序列、283.移动零、11.盛最多水的容器、42.接雨水
  • 【模块系列】STM32RDA5807M模块
  • 高阶知识库搭建实战七、(知识库雏形开发:qianwen-plus+Faiss)(练习推荐)
  • 密码学复习
  • 第5章:Go语言错误处理和异常
  • 【LeetCode】:稀疏相似度【困难】
  • 多线程+Condition 对象模拟生产者/消费者问题
  • 【亲测有效】Kafka3.5.0分布式集群安装部署与测试-最新
  • 带内管理和带外管理
  • 【ACM出版 | 高录用 |快检索】2025年第二届机器学习与神经网络国际学术会议(MLNN 2025)
  • 前后端分离架构设计与实现:构建现代Web应用的基石
  • 《机器学习》——逻辑回归(过采样)
  • 机器翻译
  • [ECCV 2018]Receptive Field Block Net for Accurate and Fast Object Detection
  • 【python如何使用随机模块】