GL 创建的主题
  • Web API 43 0 1 发布

    概述

    图像处理API是通过Image对象来提供的。如上图所示,Image是一个封装了HTMLImageElement接口的构造器,和document.createElement('img')一样,返回一个 HTMLImageElement 实例。

    代码示例 图像预加载

    使用Image对象可以实现图像预加载功能。如下所示:

    function loadImage(url, callback) { var img = new Image(); //创建一个Image对象,实现图像的预下载 img.src = url; img.onload = function () { //图像下载完毕时异步调用callback函数。 callback(img); }; }; 获取图像的大小

    在图像加载完毕之后,我们可以在回调函数里获取图像的大小,作相应的处理。

    var imgUrl = "/images/sample1.jpg"; div1 = document.getElementById("div1"); var callback = function(img) { //将图像设为DIV的背景并自动调整DIV的大小。 div1.style.backgroundImage = "url('" + img.src+ "')"; div.style.width = img.width + "px"; div.style.height = img.height + "px"; }; loadImage(imgUrl,callback);
  • Web API 58 0 1 发布

    在过去,想要在网页上构建有声web只能借助Flash等插件,自从web步入HTML5时代后,除插件机制外,我们还可以运用HTML5提供的原生API来实现这一需求。

    本节我们就来探究一下这些原生API。

      概述 简介

    Web Audio API最早是Chrome社区提出并支持的,它是一套全新的相对独立的接口系统,对音频文件拥有很高的处理权限以及内置相关的音频专业效果的处理方法,可以完全独立于<audio>标签存在。简单的说它就是一组JavaScript API,它提供了一系列处理与合成音频的方法。

    Web Audio API本身并不是<audio>标签的替代品,而是对<audio>标签功能上的补充。如果是简单的展现音频则<audio>标签足以应对,如果需要负责的音频操作,则应该是使用Web Audio API。

    特点

    * 更精准的时间控制 * 可独立于<audio>标签,允许多音频文件同时播放 * 模块化的接口设计方式,让音频操作更具灵活特性 * 更多音频专业对口的操作方法

    工作流程

    1. 创建AudioContext实例对象(下文中简称ac) 2. 为ac内置音源,如<audio>标签,震动发声器,音频流等 3. 创建效果节点(effect node)如reverb、biquad filter、compressor等 4. 选择音频的最终输出节点,如电脑扬声器 5. 连接各处理后的效果节点(源-效果-目的地 输入-处理-输出)

    名词简介 AudioContext

    AudioContext是管理和控制音频的核心,作为音频接口上下文对象,它包含了音频信号的路由图,用来连接各AudioNodes。

    AudioNodes

    音频的输入、输出以及中间处理的节点或模块

    AudioDestinationNode

    音频信号处理后的最终目的地

    AudioBuffer

    音频缓冲器,表示驻留在内存中的音频内容

    AudioBufferSourceNode

    由AudioBuffer产生音频的AudioNode

    MediaElementAudioSourceNode

    来源于audio标签、video标签或其他元素的音频资源

    AnalyserNode

    提供实时频率以及时间域分析信息的节点,它是一个AudioNode,将音频流从输入传递到输出,允许获取和处理生成的数据,并创建音频可视化。 * .frequencyBinCount * .getByteFrequencyData

    路由图

    AudioContext中包含了许许多多的几点,大致分为三类:源、目标和中间节点。 一个完整的路由图就是将每个用到的节点以串联的方式一个一个连接起来组成的。这其中源节点和目的节点是必须的而中间节点(提供了各式各样的功能和效果)则是可选的。

    代码示例 基本操作 window.onload = init; var context, bufferLoader; // loading audio file function init () { window.AudioContext = window.AudioContext || window.webkitAudioContext; context = new AudioContext(); bufferLoader = new BufferLoader(context, [ "somPath/someFile.wav", "somePath/anotherFile.wav" ], finishedLoading); bufferLoader.load(); }; // control bufferList function finishedLoading(bufferList) { bufferList.forEach(function(buffer) { playSound(buffer, 0); }); }; // play sound with given buffer and time function playSound(buffer, time) { time = time || 0; var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(time); }; // change volume sound function changeVolume(source, value) { var gainNode = context.createGain(); source.connect(gainNode); gainNode.connect(context.destination); gainNode.gain.value = value; } 静音 var mute = document.querySelector(".mute"); mute.onclick = function() { if(mute.id === "") { gainNode.disconnect(context.destination); mute.id = "activated"; mute.innerHTML = "Unmute"; } else { gainNode.connect(context.destination); mute.id = ""; mute.innerHTML = "Mute"; } } 使用Canvas实现可视化效果 // 获取实时表示频率信息的数组 var analyser = context.createAnalyser(), array = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(array); function createCanvas(width, height) { var canvas = document.createElement("canvas"); canvas.width = width || 300; canvas.height = height || 300; return canvas; } var canvas = createCanvas(), cxt = canvas.getContext("2d"); function draw(size) { cxt.clearRect(0, 0, canvas.width, canvas.height); var w = canvas.width / size; for(i = 1; i < size; i++) { var h1 = array[i] / 256 * canvas.height; h2 = canvas.height - h1; cxt.beginPath(); cxt.fillRect(w * i, h2, w * 0.6, h1); cxt.closePath(); } }
  • Web API 38 0 1 发布

    WebGL(Web Graphics Library)是HTML5规范中的一部分,可以用来渲染三维场景。

    WebGL源自OpenGL ES(OpenGL for Embedded Systems 是OpenGL三维图形API的子集)。

    示例代码// 创建canvas function createCanvas(width, height) { var canvas = document.createElement("canvas"); canvas.width = width || 300; canvas.height = height || 300; return canvas; } // 创建着色器 function createShader(webGL, source, type) { var shader = webGL.createShader(type); webGL.shaderSource(shader, source); webGL.compileShader(shader); return shader; } // 初始化webGL function initWebGL(canvas) { var webGL = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); if (!webGL) { console.log("当前浏览器不支持WebGL,请切换到支持WebGL的浏览器,比如Chrome"); return null; } else { return webGL; } } // 创建矩形 function drawRect(webGL, program) { var buffer = webGL.createBuffer(); webGL.bindBuffer(webGL.ARRAY_BUFFER, buffer); webGL.bufferData( webGL.ARRAY_BUFFER, new Float32Array([-1.0, -1.0,1.0, -1.0, -1.0, 1.0, -1.0, 1.0,1.0, -1.0,1.0, 1.0]), webGL.STATIC_DRAW ); // vertex data var positionLocation = webGL.getAttribLocation(program, "a_position"); webGL.enableVertexAttribArray(positionLocation); webGL.vertexAttribPointer(positionLocation, 2, webGL.FLOAT, false, 0, 0); } // 入口函数 function init() { var canvas = createCanvas(), VER_SHADER_SRC = "attribute vec4 a_position;\n" + "void main() {\n" + "gl_Position = a_position;\n" + "}", FRAG_SHADER_SRC = "precision mediump float;\n" + "void main() {\n" + "gl_FragColor = vec4(1, 0, 0.5, 1);\n" + "}"; document.body.appendChild(canvas); var webGL = initWebGL(canvas); if (webGL) { webGL.clearColor(0.0, 0.0, 0.0, 1.0); webGL.clear(webGL.COLOR_BUFFER_BIT | webGL.DEPTH_BUFFER_BIT); var vertex = createShader(webGL, VER_SHADER_SRC, webGL.VERTEX_SHADER), frag = createShader(webGL, FRAG_SHADER_SRC, webGL.FRAGMENT_SHADER); var program = webGL.createProgram(); webGL.attachShader(program, vertex); webGL.attachShader(program, frag); webGL.linkProgram(program); webGL.useProgram(program); drawRect(webGL, program); webGL.drawArrays(webGL.TRIANGLES, 0, 6); } }代码说明

    WebGLShader(WebGL着色器),WebGL只关心两件事:位置坐标与颜色,所有WebGL程序都是基于这两个元件来构造的,常用的方法是使用两个着色器来实现:

    顶点着色器(vertex shader):返回位置坐标
    像素着色器(fragment shader):返回颜色

    vec4()构造函数用于生成颜色,示例代码中vec4(1, 0, 0.5, 1)的数字的含义:

    第一个1:代表红色

    0:代表绿色

    0.5: 代表蓝色

    第二个1:代表alpha



    在WebGL中颜色的取值范围是0到1.

    具体方法:

    createShader:生成相应类型的WebGLShader

    shaderSource:生成GLSL的回调函数

    compileShader:编译着色器

    WebGLProgram(WebGL环境)着色器编译完后,需要将着色器链接到WebGLProgram:

    createProgram:创建一个WebGL环境

    attachShader:附加着色器

    linkProgram:将着色器连接到WebGL环境中

    提供数据:

    getAttribLocation:从当前环境中寻找定义的属性,即查找示例中初始化顶点着色器时定义的a_position。

    createBuffer:创建buffer(缓存区)

    bindBuffer:声明变量,并指向上一步创建的buffer

    bufferData:赋值数据到指定变量,比如示例中的ARRAY_BUFFER

    清空canvas:

    clearColor:

    clear:

    使用创建的WebGL环境:将当前的WebGL环境告知GPU程序

    useProgram:

    告知WebGL从buffer中获取数据的方式:

    enableVertexArribArray:激活属性

    vertexAtrribPointer:获取数据

    绘制图形:WebGL执行GLSL程序

    drawArrays:这是WebGL提供的一个渲染函数

    效果

  • Web API 55 0 1 发布

    简介

    可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。

    使用场景

    SVG基于VML,这意味着SVG DOM中的每个元素都是可操作的(为元素添加JavaScript事件),在SVG中,被绘制的图形都可以当成一个可操作的对象,如果该对象的属性发生变化,可以通过事件机制,让浏览器实时反映该属性的变化即重绘图形。SVG提供了一系列的图形元素、动画以及事件机制,适用于静态图片的展示,比如google地图。

    目前主要的使用场景有:

    Logo图矢量图UI组件信息化图标图标(字体图标、loading图标等) 实例

    画一个正方形:

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect x="10" y="10" height="100" width="100" style="stroke:#ff0000; fill: #0000ff"/> </svg>

    效果图:

    API 矩形:rect <rect x="10" y="10" fill="#eee" width="100" height="100"/> 圆:circle <circle cx="10" cy="10" r="10" fill="red"/> 椭圆:ellipse <ellipse cx="50" cy="60" fill="#eee" rx="20" ry="30"/> 直线:line <line x1="10" y1="10" x2="20" y2="20" fill="#eee" stroke-width="2" stroke="black"/> 折线:polyline <polyline stroke="black" fill="#eee" points="10, 80 40, 50 30, 60 100, 10"/> 多边形:polygon <polygon fill="#eee" points="60,20 100,40 100,80 60,100 20,80 20,40"/> 路径:path <path fill="#eee" d="M37,17v15H14V17H37z M50,0H0v50h50V0z"/> 动画:animate <animate id="animate" attributeType="XML" attributeName="d" from="-100" to="120" dur="0.3s" repeatCount="indefinite" fill="freeze" values="...."/>
  • Web API 56 0 1 发布

    概述

    配合使用JavaScript中提供的requestAnimationFrame方法,可以很容易的在canvas中实现动画效果

    一般来说,需要按照下面的步骤来创建动画:

    1. 清空canvas:使用clearRect方法,清空区域。 2. 保存canvas状态:如果你要改变一些会改变canvas状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。 3. 绘制动画图形(animated shapes) 4. 恢复canvas状态 代码示例

    GridFunny定义与Canvas概述一节中一致

    window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( /* function */ callback, /* DOMElement */ element) { window.setTimeout(callback, 1000 / 60); }; })(); var grid = new GridFunny({ nextDraw: function() { var time = new Date().getTime() * 0.002, num = this.settings.gridNum, canvasSize = this.settings.canvasSize, cX = canvasSize.width / 2, cY = canvasSize.height / 2, x = Math.sin(time) * this.pixelX + cX, y = Math.cos(time * 0.9) * this.pixelY + cY, gradient = this.context.createRadialGradient(x, y, 20, cX, cY, 110); gradient.addColorStop(0, 'yellow'); gradient.addColorStop(1, 'green'); this.context.fillStyle = gradient; this.context.beginPath(); this.context.arc(cX, cY, 110, 0, 2 * Math.PI, false); this.context.fill(); this.context.closePath(); } }); grid.start(); var animate = function() { requestAnimationFrame(animate); grid._drawBoard(); }; animate();

    代码的执行效果如下:

  • Web API 53 0 1 发布

    概述

    Canvas API中提供的变形方法主要有:

    scale:缩放 CanvasRenderingContext2D.scale(x, y) rotate:旋转 CanvasRenderingContext2D.rotate(angle) translate:重新映射画布上的 (0,0) 位置 CanvasRenderingContext2D.translate(x, y) transform:转换矩阵 CanvasRenderingContext2D.transform(a, b, c, d, e, f) setTrasform:将当前转换重置为单位矩阵。然后运行 transform() CanvasRenderingContext2D.setTransform(a, b, c, d, e, f) 代码示例

    绘制图片一节示例中我们使用GridFunny提供的clone方法实现类似缩放的效果,下面使用scale方法再次实现缩放:

    // 分别为GridFunny添加scale、rotate、translate、transform方法 var grid = new GridFunny({ gridColor: "green", canvasClassName: "transform-canvas", nextDraw: function() { var context = this.context, x = this.pixelX + 50, y = this.pixelY + 10, w = 240, h = 50; context.fillStyle = '#ccc'; context.strokeStyle = 'red'; context.font = '30px Arial'; context.fillRect(x, y, w, h); context.strokeText("transform canvas", x + 5, 85); } }); grid.start(); // scale grid.scale({ width: 300, height: 300 }, function(canvas) { canvas.className = grid.settings.canvasClassName; grid.settings.container.appendChild(canvas); }); // rotate grid.rotate({ angle: 30 * Math.PI / 180 }, function(canvas) { canvas.className = grid.settings.canvasClassName; grid.settings.container.appendChild(canvas); }); // translate grid.translate({ x: 120, y: 50 }, function(canvas) { canvas.className = grid.settings.canvasClassName; grid.settings.container.appendChild(canvas); }); // transform grid.transform({ a: 0.5, b: 0.4, c: -0.2, d: 1.2, e: 200, f: 0 }, function(canvas) { canvas.className = grid.settings.canvasClassName; grid.settings.container.appendChild(canvas); });

    rotate、translate、transform方法会对canvas进行不同程度的选择,如果是原始尺寸操作的话,有部分不能完全显示,这时需要配合scale对原始canvas进行缩放,以便显示全图。

    代码的执行效果如下:

  • Web API 55 0 1 发布

    概述

    Canvas API中提供设置渐变色的方法有:

    createLinearGradient:线性渐变createRadialGradient:径向渐变 代码示例 线性渐变 CanvasRenderingContext2D.createLinearGradient(x0, y0, x1, y1); CanvasGradient.addColorStop(position, color); x0:渐变开始点x坐标y0:渐变开始点y坐标x1:渐变结束点x坐标y1:渐变结束点y坐标position:设定的颜色离渐变结束点的偏移量(0~1)color:绘制时使用的颜色

    GridFunny定义与abstract一节中一致

    // GridFunny定义 var grid = new GridFunny({ onDraw: function() { var num = this.settings.gridNum, gradient = this.context.createLinearGradient(0, 0, 0, this.pixelY * num); gradient.addColorStop(0, 'red'); gradient.addColorStop(0.5, 'green'); gradient.addColorStop(1, 'blue'); this.context.fillStyle = gradient; this.context.fillRect(this.gridOfX[1], this.gridOfY[1], this.pixelX * num, this.pixelY * num); } }); grid.start();

    以下是代码的执行效果:

    径向渐变(发散) CanvasRenderingContext2D.createRadialGradient(x0, y0, r0, x1, y1, r1) CanvasGradient.addColorStop(position, color); x0:发散开始圆心x坐标y0:发散开始圆心y坐标r0:发散开始圆的半径x1:发散结束圆心的x坐标y1:发散结束圆心的y坐标r1:发散结束圆的半径position:设定的颜色离渐变结束点的偏移量(0~1)color:绘制时使用的颜色

    GridFunny定义与abstract一节中一致

    // GridFunny定义 var grid = new GridFunny({ nextDraw: function() { var num = this.settings.gridNum, canvasSize = this.settings.canvasSize, cX = canvasSize.width / 2, cY = canvasSize.height / 2, gradient = this.context.createRadialGradient(cX,cY, 20, cX, cY, 110); gradient.addColorStop(0, 'yellow'); gradient.addColorStop(1, 'green'); this.context.fillStyle = gradient; this.context.beginPath(); this.context.arc(cX, cY, 110, 0, 2 * Math.PI, false); this.context.fill(); this.context.closePath(); } }); grid.start();

    以下是代码的执行效果:

  • Web API 54 0 1 发布

    概述

    Canvas API中提供了一系列与阴影相关的属性来设置阴影。

    shadowOffsetX:设置水平方向的阴影,默认值是0 CanvasRenderingContext2D.shadowOffsetX shadowOffsetY:设置垂直方向的阴影,默认值是0 CanvasRenderingContext2D.shadowOffsetY shadowBlur:设置阴影的模糊度,默认值是0 CanvasRenderingContext2D. shadowBlur shadowColor:设置阴影的颜色,默认为黑色 CanvasRenderingContext2D. shadowColor 代码示例

    GridFunny定义与Canvas概述一节中一致

    var grid = new GridFunny({ nextDraw: function() { var num = this.settings.gridNum, canvasSize = this.settings.canvasSize, cX = canvasSize.width / 2, cY = canvasSize.height / 2, gradient = this.context.createRadialGradient(cX - this.pixelX, cY - this.pixelY, 20, cX, cY, 110); gradient.addColorStop(0, 'yellow'); gradient.addColorStop(1, 'green'); this.context.fillStyle = gradient; this.context.shadowBlur = 6; this.context.shadowOffsetX = 10; this.context.shadowOffsetY = 10; this.context.shadowColor = "#ccc"; this.context.beginPath(); this.context.arc(cX, cY, 110, 0, 2 * Math.PI, false); this.context.fill(); this.context.closePath(); } }); grid.start();

    代码的执行效果如下:

  • Web API 48 0 1 发布

    概述

    Canvas API中提供了两种绘制文本的方法:

    fillText:绘制文本 CanvasRenderingContext2D.fillText(text, x, y); CanvasRenderingContext2D.fillText(text, x, y, maxWidth); strokeText:添加空心字 CanvasRenderingContext2D.strokeText(text, x, y); CanvasRenderingContext2D.strokeText(text, x, y, maxWidth);

    注意:fillText方法不支持文本断行,即所有文本出现在一行内。所以,如果要生成多行文本,只有调用多次fillText方法。 绘制文本的时候还可以为文本添加其他属性:

    font:设置文本的样式textAlign:设置文本水平对齐,'start','end','left','right','center'textBaseline:设置文本垂直对齐,'top','hanging','middle','alphabetic','ideographic','bottom' 示例代码

    abstract一节中,我们绘制了一个9*9的空表格,现在我们来为每个表格填充数字以及x与y轴坐标的乘积:

    // GridFunny定义与[[36:26:canvas:abstract]]一节中一致 var grid = new GridFunny({ gridColor: "green", fillGrid: function(keyX, keyY, pixelX, pixelY) { var paddingX = pixelX / 4, paddingY = pixelY / 4; if (keyX <= keyY) { this.context.fillStyle = "black"; } else { this.context.fillStyle = "blue"; } this.context.font = "20px Arial"; this.context.fillText(keyX * keyY, this.gridOfX[keyX] + paddingX * 1.5, this.gridOfY[keyY] + paddingY * 2.5); } }); grid.start();

    示例代码中使用了GridFunny提供的每个格子的坐标,然后调用fillText方法将坐标的乘积绘制到每个单元表格中。

    这里有一个问题,由于记录单元表格的坐标是左上角的,所以在绘制文本的时候,位置并不是我们想要看到的居中,而是会出现在单元表格左上角的外面,如下图所示: 为了解决这个问题我们在绘制文本的时候做了下位置偏移(临时解决方案,这不是好的实现方法,应该考虑一个更为通用的方法)

    代码的执行效果如下:

  • Web API 67 0 1 发布

    概述

    drawImage方法将所给图片绘制到canvas。

    使用方法 CanvasRenderingContext2D .drawImage(image, dx, dy); CanvasRenderingContext2D .drawImage(image, dx, dy, dw, dh); CanvasRenderingContext2D .drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh); 参数说明 image:图形数据,可以是图像数据也可以是img标签。sx:从图形x轴坐标x处截取sy:从图形y轴坐标y处截取sw: 截取图形的宽sh:截取图形的高dx:从目标canvas的x轴x处绘制dy:从目标canvas的y轴y处绘制dw: 绘制的宽dh:绘制的高 代码示例

    todataurl一节中我们为GridFunny添加了一个toDataURL的方法,将canvas直接转换为图形数据, 本节中的示例,使用这个被转换的数据,并将其重新绘制到另一个canvas中:

    // 为GridFunny添加一个clone方法 GridFunny.prototype.clone = function(options, callback) { if (!this._started) this.start(); var self = this, width = 300, height = 300, destGridW = this._canvasRatio("width", options.width || width) * this.pixelX, destGridH = this._canvasRatio("height", options.height || height) * this.pixelY, _opts = this._extendObject({ type: "image/png", opts: {}, width: width, height: height, sx: this.pixelX, sy: this.pixelY, sw: options.gridNum ? options.gridNum * this.pixelX : this.settings.canvasSize.width - this.pixelX * 2, sh: options.gridNum ? options.gridNum * this.pixelY : this.settings.canvasSize.height - this.pixelY * 2, dx: destGridW, dy: destGridH, dw: (options.width || width) - (destGridW * 2), dh: (options.width || width) - (destGridH * 2) }, options || {}); this.toDataURL(_opts.type, _opts.opts, function(canvas, data) { var image = new Image(); image.src = data; image.onload = function() { var _canvas = self._initCanvas(_opts.width, _opts.height), ctx = _canvas.getContext('2d'); ctx.drawImage(image, _opts.sx, _opts.sy, _opts.sw, _opts.sh, _opts.dx, _opts.dy, _opts.dw, _opts.dh) callback(_canvas); }; }); } // 调用 // 剪切三个格子 grid.clone({ gridNum: 3, width: 300, height: 300 }, function(canvas) { grid.settings.container.appendChild(canvas); }); // 全部复制 grid.clone({ width: 300, height: 300 }, function(canvas) { grid.settings.container.appendChild(canvas); });

    clone参数:

    gridNum:剪切的格子数,没有则为全部width:复制后canvas的宽height:复制和canvas的高(s|d)(x,y,w,h):默认不传,则根据gridNum自动计算,有传值则根据所传值处理图片

    代码的执行效果如下:

  • Web API 62 0 1 发布

    概述

    Canvas API中提供处理形状的简单方法有:

    fillRect:它的四个参数分别为矩形左上角顶点的x坐标、y坐标,以及矩形的宽和高,在绘制矩形前可以使用fillStyle属性设置矩形的填充色 CanvasRenderingContext2D.fillRect(x, y, w, h); strokeRect:以fillRect类似,绘制空心矩形 CanvasRenderingContext2D.strokeRect(x, y, w, h); clearRect:清除给定坐标的矩形区域 CanvasRenderingContext2D.clearRect (x, y, w, h);

    上面的方法只能处理简单的矩形,当需要处理其他复杂形状时可以使用paths,处理流程:

    1. 使用beginPath方法开始一个新的路径绘制

    2. 使用下面的方法绘制图形:

    moveTo:设置线段的起点(x, y) CanvasRenderingContext2D.moveTo(x, y); lineTo:设置线段的终点(x, y) CanvasRenderingContext2D.lineTo(x, y); rect:绘制矩形,与fillRect和strokeRect方法不同的是,使用rect方法必须配合使用stroke或者fill方法着色 CanvasRenderingContext2D.rect(x, y, w, h); quadraticCurveTo:绘制二次贝塞尔曲线 CanvasRenderingContext2D.quadraticCurveTo(cpx, cpy, x, y); bezierCurveTo:绘制三次方贝塞尔曲线 CanvasRenderingContext2D.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); arc:绘制弧或者曲线 CanvasRenderingContext2D.arc(x, y, r, start, end, anticlockwise); arcTo:绘制两切线之间的弧或曲线 CanvasRenderingContext2D.arcTo(x1, y1, x2, y2, radius);

    3. 使用closePath结束路径绘制 4. 使用stroke或者fill方法给绘制好的路径着色,在这之前使用strokeStyle属性设置填充色,还可以赋值lineWidth设置线条的大小

    代码示例

    abstract一节中,我们绘制了一个9*9的空表格,现在我们来为每个表格填充数字以及x与y轴坐标的乘积:

    // GridFunny定义与[[36:26:canvas:abstract]]一节中一致 // 添加一个获取随机颜色的方法 GridFunny.prototype._randColor = function() { var colors = [ "#cfd9df", "#a1c4fd", "#8fd3f4", "#e6dee9", "#c3cfe2", "#a8edea", "#e0c3fc", "#ebbba7", "#fff1eb", "#accbee", "#c1dfc4", "#deecdd", "#fbfcdb", "#6a85b6", "#9face6" ]; return colors[Math.floor(Math.random() * colors.length)]; } var grid = new GridFunny({ gridColor: "green", fillGrid: function(keyX, keyY, pixelX, pixelY) { this.context.fillStyle = this._randColor(); this.context.fillRect(this.gridOfX[keyX], this.gridOfY[keyY], pixelX, pixelY); } }); grid.start();

    abstract一节中,我们其实使用了path的相关方法绘制了一个基本的9*9表格,处理流程是:

    1. 使用clearRect(0, 0, width, height)方法清空矩形区域 2. 调用beginPath,开始路径绘制 3. 按照单元表格的大小分别在x轴与y轴绘制实线,步骤是首先使用moveTo设置线段起点坐标,然后调用lineT设置线段的终点坐标 4. 使用closePath方法结束路径的绘制,赋值strokeStyle设置填充色,最后调用stroke方法着色。

    本节示例代码中,在基础表格之上,通过调用fillRect以及赋值fillStyle属性为单元表格填充随机的颜色。

    代码的执行效果如下:

  • Web API 61 0 1 发布

    用canvas画一个9*9的表格

    (function(global) { 'use strict'; function _extend(obj1, obj2) { for (var i in obj2) { if (obj2.hasOwnProperty(i)) { obj1[i] = obj2[i]; } } } function GridFunny(options) { this.grid = {}; this.gridOfX = {}; this.gridOfY = {}; this.settings = { container: document.body, gridColor: "#ccc", // 格子的颜色 gridNum: 9, // 格子的数量 canvasSize: { width: 500, height: 500 }, // canvas的尺寸 generateGridKey: function(x, y) { return [x, y].join("-"); }, // 创建每个格子在grid对象中的key onDraw: function() { }, // 提供绘画钩子方法,方便定制绘画 fillGrid: function(keyX, keyY, pixelX, pixelY) { }, // 填充每个格子内容的方法 contextType: "2d", // canvas文本类型(2d或者3d) border: 1 // 表格的边框大小 }; _extend(this.settings, options || {}); return this; } GridFunny.prototype.start = function() { this.canvas = this._initCanvas(); this.context = this.canvas.getContext(this.settings.contextType); this._drawBoard(); } GridFunny.prototype._initCanvas = function() { var canvas = document.createElement("canvas"); canvas.width = this.settings.canvasSize.width; canvas.height = this.settings.canvasSize.height; this.settings.container.appendChild(canvas); return canvas; } GridFunny.prototype._drawBoard = function() { var width = this.settings.canvasSize.width, height = this.settings.canvasSize.height, num = this.settings.gridNum, border = this.settings.border, halfBorder = border / 2, context = this.context, color = this.settings.gridColor, pixelX = (width - border) / (num + 2), pixelY = (height - border) / (num + 2), rectXSize = pixelX * (num + 1), rectYSize = pixelY * (num + 1); context.clearRect(0, 0, width, height); context.beginPath(); /* 垂直线 */ for (var i = 0, x = pixelX; x <= rectXSize; x += pixelX) { i++; var beginCoordinate = halfBorder + x; if (i <= num) this.gridOfX[i] = beginCoordinate; context.moveTo(beginCoordinate, pixelX); context.lineTo(beginCoordinate, rectXSize); } /* 水平线 */ for (var j = 0, y = pixelY; y <= rectYSize; y += pixelY) { j++; var endCoordinate = halfBorder + y; if (j <= num) this.gridOfY[j] = endCoordinate; context.moveTo(pixelY, endCoordinate); context.lineTo(rectYSize, endCoordinate); } this._initGridCoordinate(pixelX, pixelY); context.closePath(); this.settings.onDraw.call(this); /* 开始画 */ context.strokeStyle = color; context.stroke(); } GridFunny.prototype._initGridCoordinate = function(pixelX, pixelY) { var context = this.context, grid = this.grid, gridOfX = this.gridOfX, gridOfY = this.gridOfY; for (var keyX in gridOfX) { for (var keyY in gridOfY) { // 记录每个格子的坐标 var key = this.settings.generateGridKey(keyX, keyY); grid[key] = [gridOfX[keyX], gridOfY[keyY]]; this.settings.fillGrid.call(this, keyX, keyY, pixelX, pixelY); } } } // Export Pig into the global scope. if (typeof define === 'function' && define.amd) { define(function() {return GridFunny;}); } else if (typeof module !== 'undefined' && module.exports) { module.exports = GridFunny; } else { global.GridFunny = GridFunny; } }(this)); var grid = new GridFunny({ gridColor: "green" }); grid.start();

    主要用到的方法:

    clearRect(x, y, width, height):清空所选矩形块beginPath:开始绘制路径moveTo(x, y):将画笔移到坐标为(x, y)的地方lineTo(x, y):画一条到坐标(x, y)为止的线closePath:结束绘制路径strokeStyle:给画笔添加颜色(通俗的说法是给画笔加所给颜色的墨水),示例中默认是灰色#cccstroke:根据绘制的路径以及定义的颜色,绘制图画

    以上是代码的执行效果。

  • Web API 73 0 1 发布

    获取和设置HTML属性文本 var disabled = nodelib.attr(node,"disabled"); nodelib.attr(node,"disabled",""); 获取和设置DOM对象属性 var disabled = nodelib.prop(node,"disabled"); nodelib.prop(node,"disabled",false); 工具函数列表

    uDOMlib所提供的工具函数之中,有一部分与元素属性相关,下面列出部分函数的源代码实现以供参考。

    attr

    获取或设置元素的attribute(HTML标签属性)值。

    attr: function(node,name, value) { if (value === undefined){ if (typeof name === "object"){ for (var attr in name){ this.attr(node,attr,name[atrr]); } return this; } else { return node[name]; } } else { node[name] = value; return this; } } data

    获取或设置元素给定名称的数据存储的值。

    data: function(node,name, value) { var attrName = 'data-' + name.replace(capitalRE, "-$1").toLowerCase() if (value === undefined){ var data = this.attr(node,attrName,value); return data !== null ? deserializeValue(data) : undefined; } else { return this.attr(node,attrName,value); } } html

    获取或设置元素的Html内容。 html()内部使用DOM节点的innerHTML属性,适用于任意HTML元素。

    html: function(node,html) { if (html === undefined){ return node.innerHTML; } else { this.empty(node); node.innerHTML = html; //TODO:will be checkd return this; } } prop

    获取或设置元素的property(特性)值。 prop()方法返回的是节点作为一个JavaScript对象所拥有的特性(property)值。 与attr()方法不同,prop()返回的值具有其本来的数据类型,如针对<input type=“checkbox”/>元素调用prop(“checked”),其返回值将是Boolean型的true或false。

    prop: function(node,name, value) { name = propMap[name] || name; if (value === undefined){ return node[name]; } else { node[name] = value; return this; } } removeAttr removeAttr: function(node,name) { name.split(' ').forEach(function(attr) { setAttribute(node, attr); }); return this; } text

    获取或设置元素的文本内容。 .text() 方法不能使用在input元素或scripts元素上。 input 或 textarea 需要使用 .val() 方法获取或设置文本值。得到scripts元素的值,使用.html()方法

    text: function(node,text) { if (text === undefined){ return node.textContent; } else { node.textContent = text == null ? '' : '' + text return this; } } val

    获取或设置元素的当前值。 val()方法主要适用于表单元素,如input, select 和 textarea。 如果select元素设置了multiple属性,.val()返回一个包含每个选择项值的数组

    val: function(node,value) { if (value === undefined){ if (node.multiple) { // select multiple values var selectedOptions = this.find(node,"option").filter(function(){ return this.selected }); return this.pluck(selectedOptions,"value"); } else { return node.value; } } else { node.value = value; return this; } }
  • Web API 61 0 1 发布

    示例代码 获取元素的样式 var backgroundColor = domlib.css(node,"backgroundColor"); 设置元素的样式 domlib.css(node,"backgroundColor","red"); 工具函数列表

    uDOMlib所提供的工具函数之中,有一部分与元素样式相关,下面列出部分函数的源代码实现以供参考。

    addClass

    給元素添加一个或多个类。 该方法不会移除已存在的class属性,仅仅添加一个或多个class属性,添加多个类需使用空格分隔类名。

    addClass: function(el,name){ var re = classRE(name); if (!el.className.match(re)){ el.className += (el.className ? " " : "") + name; } } css

    获取或设置元素的一个或多个样式属性

    css: function(el,property, value){ if (arguments.length < 3) { var computedStyle, computedStyle = getComputedStyle(el, '') if (utils.isString(property)) { return el.style[utils.camelize(property)] || computedStyle.getPropertyValue(property) } else if (utils.isArray(property)) { var props = {}; Array.forEach(property, function(prop){ props[prop] = (el.style[String.camelize(prop)] || computedStyle.getPropertyValue(prop)) }); return props } } var css = '' ; if (type(property) == 'string') { if (!value && value !== 0) el.style.removeProperty(dasherize(property)); else css = dasherize(property) + ":" + maybeAddPx(property, value) } else { for (key in property) if (!property[key] && property[key] !== 0) el.style.removeProperty(dasherize(key)); else css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' } el.style.cssText += ';' + css; return this; } hasClass

    检查元素是否包含指定的类。

    hasClass: function(el,name){ var re = classRE(name); return el.className.match(re); } removeClass

    从元素移除一个或多个类

    removeClass: function(el,name){ var re = classRE(name); if (el.className.match(re)){ el.className = el.className.replace(re, " "); } return this; } toggleClass

    对元素的一个或多个类进行切换。 该方法检查元素是否已设置指定的类。如果不存在则添加类,如果已设置则删除之。

    toggleClass: function(el,name){ var re = classRE(name); if (el.className.match(re)){ el.className = el.className.replace(re, " "); } else { el.className += (el.className ? " " : "") + name; } return this; }
  • Web API 54 0 1 发布

    获取元素的大小

    Element接口提供了众多属性用于获取元素的各种大小值(单位像素),这些属性通常为只读,并且只有元素已经在DOM树中且CSS属性的display不为none时才有效。

    元素的实际大小

    元素的实际大小就是元素在页面中实际所占控件的大小,包括边框,滚动条,但不包括外边距。

    Element.offsetHeight  元素的高度。Element.offsettWidth  元素的宽度。

    另外,通过调用Element.getBoundingClientRect()方法也可以获得元素的实际大小,该方法同时还返回元素其相对于视口的位置。

    元素客户区的大小

    元素的客户区的大小就是指元素内容及其内边距所占空间的大小,包含内边距,但不包括水平滚动条、边框和外边距

    Element.clientHeight  元素的客户区高度。Element.clientWidth  元素的客户区宽度。 元素滚动区域的大小

    如果元素的CSS属性overflow没有被设置成none,元素的内容多至显示不下时将会被滚动显示。 使用scrollWidth和scrollHeight属性可以获取元素的滚动区域即整个内容的大小。

    Element.scrollHeight  元素的滚动区域高度。Element.scrollWidth 元素的滚动区域宽度。

    另外scrollLeft和scrollTop属性可以用来获取和设定的元素的滚动位置。

    页面和视口 页面的大小

    页面的大小指的是整个页面文档的大小,标准方法是利用document.documentElement(HTML元素)的scrollWidth和scrollHeight属性。

    document.documentElement.scrollWidth  整个文档的宽度document.documentElement.scrollHeight  整个文档的高度 视口的大小

    视口指浏览器窗口中看到的那部分网页面积,标准方法是利用document.documentElement(HTML元素)的clientWidth和clientHeight属性。 这两个属性的返回值不包括整个文档的滚动条,也不包括<html>元素的边框和外边距,但包括<html>元素的内边距。

    document.documentElement.clientWidth  视口的宽度document.documentElement.clientHeight  视口的高度

    其他还有以下方法,不过获取的值可能与标准方法获取的值的范围有所差别。

    document.body.clientHeight/document.body.clientWidth  不包括整个文档的滚动条,也不包括<html>元素的边框,也不包括<body>的边框和滚动条。document.body.offsetHeight/document.body.offsetWidth  不包括整个文档的滚动条,也不包括<html>元素的边框,包括<body>的边框和滚动条。window.innerHeight/window.innerWidth 包括整个文档的滚动条及<html>元素的边框。

    工具函数列表

    uDOMlib所提供的工具函数之中,有一部分与元素大小相关,下面列出部分函数的源代码实现以供参考。

    boundingRect boundingRect : function(node,coords) { if (coords === undefined) { return node.getBoundingClientRect() } else { this.boundingPosition(node,coords); this.size(node,coords); return this; } } clientSize clientSize : function(node) { return { width: node.clientWidth, height: node.clientHeight }; } contentRect contentRect : function(node) { var cs = this.clientSize(node), pex = this.paddingExtents(node); return { left: pex.left, top: pex.top, width: cs.width - pex.left - pex.right, height: cs.height - pex.top - pex.bottom }; } height height : function(node,value) { if (value == undefined) { return this.size(node).height; } else { return this.size(node,{ height : value }); } } pageRect pageRect : function(node,coords) { if (coords === undefined) { var obj = node.getBoundingClientRect() return { left: obj.left + window.pageXOffset, top: obj.top + window.pageYOffset, width: Math.round(obj.width), height: Math.round(obj.height) } } else { this.pagePosition(node,coords); this.size(node,coords); return this; } } rect rect : function(node,coords) { if (coords === undefined) { var // Get *real* offsetParent offsetParent = this.offsetParent(node), // Get correct offsets offset = this.boundingRect(node), parentOffset = this.boundingPosition(offsetParent), mex = this.marginExtents(node), pbex = this.borderExtents(offsetParent); // Subtract parent offsets and element margins return { top: offset.top - pbex.top - mex.top, left: offset.left - pbex.left - mex.left, width: offset.width, height: offset.height } } else { this.position(node,coords); this.size(node,coords); return this; } } size size : function(node,dimension) { if (value == undefined) { return { width : node.offsetWidth, height : node.offsetHeight } } else { var isBorderBox = this.css(node, "boxSizing") === "border-box", props = Object.clone(dimension); if (!isBorderBox) { var pex = this.paddingExtents(node), bex = this.borderExtents(node); if (props.width !== undefined) { props.width = props.width-pex.left-pex.right-bex.left-bex.right; } if (props.height !== undefined) { props.height = props.height-pex.top-pex.bottom-bex.top-bex.bottom; } } styler.css(props); return this; } } width width : function(node,value) { if (value == undefined) { return this.size(node).width; } else { return this.size(node,{ width : value }); } }
  • Web API 55 0 1 发布

    元素节点的查找 通过节点属性查找

    通过节点的相关属性可以直接取得对象节点的父子兄弟节点。

    属性说明childNodes获取当前元素节点的所有子节点firstChild获取当前元素节点的第一个子节点lastChild获取当前元素节点的最后一个子节点ownerDocument获取该节点的文档根节点,相当与documentparentNode获取当前节点的父节点previousSibling获取当前节点的前一个同级节点nextSibling获取当前节点的后一个同级节点

    通过以上属性取得的子节点和兄弟节点,不仅有元素节点,也有文本节点等其他类型的节点,根据需要可以通过node.nodeType属性进行判断。

    通过ID查找

    节点的ID在DOM文档中具有唯一性,如果知道查找对象节点的ID,这种方法将是查询性能最高的方法。 domlib的find()方法可以通过ID查询节点,下面的代码将会返回contextNode节点(可以是document)的子孙节点中ID为“id1”的节点。

    var node = domlib.find(contextNode,"#id1");

    find()方法内部调用DOM API的contextNode.getElementById()方法。

    通过类名查找

    domlib的find()方法也可以通过类名查询节点,下面的代码将会返回contextNode节点(可以是document)的子孙节点中类名为”cls1”的节点。

    var node = domlib.find(contextNode,".cls");

    find()方法内部调用DOM API的contextNode.getElementsByClassName()方法。

    通过选择符查找

    domlib的find()方法也可以通过指定更复杂的选择符来查询节点,选择符的语法遵从CSS3规范。 下面的代码将会返回contextNode节点(可以是document)的container节点(类名位container的DIV元素)的<a>子元素。

    var node = domlib.find(contextNode,"div.container > a");

    find()方法内部调用DOM API的contextNode.querySelectorAll()或contextNode.querySelector()方法。

    工具函数列表

    uDOMlib所提供的工具函数之中,有一部分与查找元素相关,下面列出部分函数的源代码实现以供参考。

    children children: function(node,selector) { var childNodes = node.childNodes, result = []; for (var i=0;i<childNodes.length;i++){ if (this.matchs(childNodes[i],selector)) { result.push(childNodes[i]); } } return result; } closest closest: function(node,selector,checkSelf) { node = checkSelf ? node : node.parentNode; while (node && !(this.matches(node, selector))){ node = node.parentNode; } return node; } find

    查找元素列表

    find: function(node,selector,single) { var matched,ret; if (matched = selector.match(simpleIdSelectorRE)) { // ID return node.getElementById(matched[1]); } if (matched = selector.match(simpleClassSelectorRE)) { // Class var ret = node.getElementsByClassName(matched[1]); if (single && ret){ ret = ret[0]; } return ret; } // Selector if (single) { return node.querySelector(selector) } else { return node.querySelectorAll(selector) } } findSingle matches matches: function(node,selector) { if (!selector || !node || node.nodeType !== 1) { return false } var matchesSelector = node.webkitMatchesSelector || node.mozMatchesSelector || node.oMatchesSelector || node.matchesSelector; return matchesSelector.call(node, selector) } parents parents: function(node,selector) { var ancestors = []; while (node = node.parentNode) { if (this.matches(node, selector)){ ancestors.push(node); } } return ancestors; }
  • Web API 63 0 1 发布

    示例代码 创建文本节点 var node = domlib.createTextNode("hello,hudaokeji"); 创建元素节点 var node = domlib.createElemnt("div",{ "style" : "width:100%;height:100%" }); 创建节点块 var node = domlib.createFragment("<div><span>label</span><input type='text'/></div>"); 追加节点 //将node作为兄弟节点追加到refNode后面 domlib.appendAfter(node,refNode); //将node作为兄弟节点追加到refNode前面 domlib.appendBefor(node,refNode); //将node作为第一个子节点追加到parentNode下面 domlib.appendChildFirst(node,parentNode); //将node作为最后一个子节点追加到parentNode下面 domlib.appendChild(node,parentNode); 清空和删除节点 //清空node的内容 domlib.empty(node); //移除node domlib.remove(node); 工具函数列表

    uDOMlib所提供的工具函数之中,有一部分与增删节点相关,下面列出部分函数的源代码实现以供参考。

    clone clone: function(node, deep) { var self = this, clone, doc; // TODO: Add feature detection here in the future if (!isIE || node.nodeType !== 1 || deep) { return node.cloneNode(deep); } doc = self.doc; // Make a HTML5 safe shallow copy if (!deep) { clone = doc.createElement(node.nodeName); // Copy attribs each(self.getAttribs(node), function(attr) { self.setAttrib(clone, attr.nodeName, self.getAttrib(node, attr.nodeName)); }); return clone; } return clone.firstChild;

    }

    createElemnt createElement : function(tag,props){ var node = document.createElement(tag); if (props) { utils.mixin(node,props); } return node; } createFragment createFragment: function(html) { var frag = document.createDocumentFragment(), node; if (html) { fragmentContainer.innerHTML = html; } while ((node = fragmentContainer.firstChild)) { frag.appendChild(node); } return frag; } createTextNode createTextNode : function(text){ return document.createTextNode(text); } empty empty : function(node){ while (node.hasChildNodes()) { var child = node.firstChild; node.removeChild(child); } return this; } isChildOf isChildOf: function(node, parent) { while (node) { if (parent === node) { return true; } node = node.parentNode; } return false; } placeAfter placeAfter: function(node,refNode){ var parent = refNode.parentNode; if(parent){ if(parent.lastChild == refNode){ parent.appendChild(node); }else{ parent.insertBefore(node, refNode.nextSibling); } } return this; } placeBefore placeBefore: function(node,refNode){ var parent = refNode.parentNode; if(parent){ parent.insertBefore(node, refNode); } return this; } placeChildFirst placeChildFirst: function(node,parentNode){ if(parentNode.firstChild){ insertBefore(node, refNode.firstChild); } else { parentNode.appendChild(node); } return this; } placeChild placeChild: function(node,parentNode){ parentNode.appendChild(node); return this; } remove remove: function(node){ if(node && node.parentNode){ node.parentNode.removeChild(node); } return this; } replace replace: function(node, oldNode) { oldNode.parentNode.replaceChild(node, oldNode); return this; }
  • Web API 99 0 1 发布

    DOM简介

    DOM(Document Object Model,文档对象模型)将XML/HTML文档构造成一个层次化的节点树,并提供了一系列的应用程序编程接口,以允许程序或脚本动态的访问和修改文档的内容、结构和样式。

    内容结构

    DOM由W3C进行了标准化,W3C DOM标准中立于平台和语言,分为以下3个部分:

    核心DOM:针对结构化文档的标准模型XML DOM: 针对XML文档的标注模型HTML DOM:针对HTML文档的标准模型 标准化历史

    DOM标准化的历史如下:

    规范化前版本  由各个浏览器自行实现,这个阶段的DOM经常被称为DHTML(Dynamic HTML,动态HTML)DOM级别1规范  发布于1998年10月1日,专注于HTML和XML文档模型DOM级别2规范  发布于2000年11月13日,对DOM级别1添加了样式表对象模型和事件处理模型DOM级别3规范  从2004年开始陆续发布,对DOM级别2作了系列扩展 核心DOM

    核心DOM定义了一个通用性的,以节点为基础的结构化文档模型,DOM文档模型中的所有内容都是节点,整个文档是一个文档根节点。

    基本属性

    节点的基本属性如下:

    nodeType  获取节点的类型。例如 1代表元素节点,2代表属性节点,3代表文本节点,通常这三类节点使用的最为普遍.nodeName  获取节点的名称。如果节点是元素节点,则 nodeName属性返回标签名;如果节点是属性节点,则nodeName属性返回属性的名称;其他节点类型,nodeName属性将返回不同节点类型的不同名称。nodeValue  设置或返回节点的值。如果节点是元素节点或文档节点,nodeValue属性值为null;如果节点是属性节点,nodeValue代表属性的值;如果节点是文本节点,nodeValue代表节点的内容;如果节点是注释节点,nodeValue代表注释的内容 节点类型

    核心DOM规范中定义了以下节点类型:

    类型说明Type值子节点Document(文档节点)表示整个文档(DOM树的根节点)9Element(max.one) ProcessingInstruction Comment DocumentTypeElement(元素节点)表示标签元素1Text ProcessingInstruction Comment CDATASection EntityReferenceAttribute(属性节点)表示元素的属性2Text EntityReferenceText(文本节点)表示元素或属性中的文本内容3无CDATASection(CDATA区段节点)表示文档中的 CDATA 区段4无DocumentFragment(文档片段节点)表示轻量级的Document 对象11Text ProcessingInstruction Comment CDATASection EntityReferenceComment(注释节点)表示注释8无

    其他还有几个,但一般不太用到,在此暂不列出。

    节点层次

    节点树中的节点彼此拥有层级关系:父节点(parent),子节点(child)和同胞节点(sibling)等。父节点拥有子节点,同级的子节点被称为同胞节点。 另外一部分节点如元素节点拥有属性节点. DOM规范为节点提供了以下诸多属性,以用于获取节点的层次关联信息。

    属性说明childNodes获取当前节点的所有子节点(※1)firstChild获取当前节点的第一个子节点(※1)lastChild获取当前节点的最后一个子节点(※1)ownerDocument获取该节点的文档根节点,相当与documentparentNode获取当前节点的父节点previousSibling获取当前节点的前一个同级节点nextSibling获取当前节点的后一个同级节点attributes获取当前元素节点的所有属性节点集合(※2)※1 部分类型的节点如文本节点等没有子节点.※2 仅部分类型的节点如元素节点拥有属性 创建节点 方法说明document.write()这个方法可以把任意字符串插入到文档中document.createElement()创建一个元素节点node.appendChild()将新节点追加到子节点列表的末尾document.createTextNode()创建一个文本节点node.insertBefore()将新节点插入在前面node.replaceChild()将新节点替换旧节点node.cloneNode()复制节点node.removeChild()移除节点 HTML DOM

    HTML DOM定义了一个HTML文档的文档对象模型。

    HTML文档首先是一个XML文档,为简单起见,XML DOM部分也包含在HTML DOM里一并说明。

    HTML文档的主要构成元素是各类HTML标签,HTML文档中的标签对应着元素节点。

    元素属性

    HTML元素的属性有attribute与property两个概念,这两个通常都被翻译成属性,但含义完全不一样。

    attribute是HTML标签属性,设计期在文档中直接记述,运行期可以通过Node的接口方法getAttribute(name)和setAttribute(name,value)进行访问。attribute值只存在文字列类型。而property是JS对象属性,运行期象一般的JS对象访问一样直接元素进行操作。property值拥有各自不同的数据类型。

    通常每个attribute都有一个同名的property,property可以看成是attribute的包装器,同时也对attribute值进行必要的类型转换。

    HTML: <input id="input1" type="checkbox" checked= "checked"/> <input id="input2" type="checkbox" checked= "true"/> JavaScript: console.log(document.getElementById("input1").getAttribute("checked")); // checked console.log(document.getElementById("input1").checked); // true console.log(document.getElementById("input2").getAttribute("checked"); // true 元素事件 事件阶段(Event Phases)

    当一个DOM事件被触发的时候,它并不只是在它的起源对象上触发一次,而是会经历以下三个不同的阶段:

    捕获阶段  事件的第一个阶段是捕获阶段。事件从文档的根节点出发,随着DOM树的结构向事件的目标节点流去。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。目标阶段  捕获阶段结束,即当事件到达目标节点后,事件就进入了目标阶段,事件在目标节点上被触发。冒泡阶段  事件在目标元素上触发后,并不在这个元素上终止。它会随着DOM树一层层向上冒泡,直到到达最外层的根节点。 事件处理

    TODO:待编辑

    事件分类

    TODO:待编辑

    元素样式

    TODO:待编辑

    视口

    TODO:待编辑