#DOM-CORE & HTML-DOM

对于什么是DOM而言,之前,已经讨论过了,现在我们重新回过头来,分析和思考一下,有关于DOM的一些分类上的区别。

什么是 DOM?
DOM 是 W3C(万维网联盟)的标准。
DOM 定义了访问 HTML 和 XML 文档的标准:
“W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”
W3C DOM 标准被分为 3 个不同的部分:
核心 DOM - 针对任何结构化文档的标准模型
XML DOM - 针对 XML 文档的标准模型
HTML DOM - 针对 HTML 文档的标准模型

上文是w3c对DOM的分类,基本上就是DOM-CORE 和HTML-DOM,XML-DOM不在讨论范围以内,我们暂且不管。
先说DOM-CORE吧

##DOM-CORE

满足软件开发者和Web脚本编写者,访问和操控产品项目中包含的可解析的HTML和XML内容。这个是COM-CORE的定义,从定义上看,HTML-CORE并不是单独提供给javascript的哦,也就是说,其他的语言也是可以通过HTML-CORE来操作DOM的哦,嗯,为了证实这一点,我们就用全世界最好的语言(php)来写一段。

1
<?php
$Doc = new DOMDocument();
$Doc->load("test.html");

$d = $Doc->documentElement;
foreach ($d->childNodes AS $item)
  {
  print $item->nodeName . " = " . $item->nodeValue . "<br />";
  }
?>

这里用到了一段html

1
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>test</title>
</head>
<body>
    <p>hello world</p>
</body>
</html>

嗯,然后,你就会得到以下的输出:

1
#text = 
head = test 
#text = 
body = hello world 
#text =

虽然不是很强大,但是也是可以的哦,嗯,以上代码的运行环境在php5以上。更多的内容参考这里

回到js的上面,DOM-CORE对应的操作其实更多的是体现在DOM-CORE是基于节点的(NODE-BASE),其所有的操作都是基于该节点的操作,如下:

1
<a href="url" id="id" >this is a a elemt </a>
<script>
//获取 #id 的href属性值
    var node = document.getElementById('id');
    var url = node.attattributes['href'].value;
//监听 #id 的click事件
    node.onclick = function(e){
        //do some thing
    }
//创建一个节点
    document.createElement();
    document.createTextNode();
</script>

Read More

昨天记录了一下DOM的一些简单的操作和一些简单的实现方法,还有一点js的DOM操作,然后提到一个概念,优雅降级,与之对应的是渐进增强,其实他们都是兼容问题。

#兼容

问题的根源

其实吧,我觉得两者是从不同的角度和方向来解决同一个问题。如何对待浏览器大战留下来的坑,以及如何照顾不同受众群体。这个问题的根源其实是http协议本身的无状态。以及计算机网络的不确定性,我们只能将很大一部分代码的基础构建在一个假设上面,而这个假设本身并不能被很好的印证。这样话,其实就有一个很根本的问题了,如果,宿主对象不存在,该如何处理。曾经的想法是优雅降级, 后来我们把想法更新成了渐进增强。
对于不同浏览器的支持可以点这里进行查询。

优雅降级(Graceful degradation)

又叫平稳退化,wiki上有比较详细的解释,英文好的同学可以点击去看看,嗯,说一下自己的理解,其实就是当程序运行在一个非完整环境下,对该不完整环境做的自我阉割,从而使得在该不完整情况下使用的用户能够基本完成所有交互动作。

渐进增强 (Progressive enhancement)

淘宝UED的一篇译文写的极好,这里直接引用。

“渐进增强”观点则认为应关注于内容本身。请注意其中的差别:我甚至连“浏览器”三个字都没提。

内容是我们建立网站的诱因。有的网站展示它,有的则收集它,有的寻求,有的操作,还有的网站甚至会包含以上的种种,但相同点是它们全都涉及到内容。这使得“渐进增强”成为一种更为合理的设计范例。这也是它立即被 Yahoo! 所采纳并用以构建其“分级式浏览器支持 (Graded Browser Support)”策略的原因所在。
原文请点我

##区别

从不同层面和起点去看同一个问题,往往会有不同的答案,就像,我们看到这两个兼容处理。

当我们站在完整浏览器的角度而言,我们所面对的受众都是会自行更新最新浏览器的年轻受众而言,保持网页最酷炫,最丰满的状态往往会得到更大的收益,这时候,建立在最新浏览器支持下的优雅降级,就有其独特的优势。以最好的呈现效果为出发点,当我的呈现效果无法得到宿主环境的支持的时候,我主动阉割,用来实现交互的延续。

当我们站在内容表现的出发点,以最大限度的传递内容信息为依归的去思考问题的时候,我们往往会发现从老旧浏览器出发的向上表现增强,是更好的实现方法。

并没有什么东西是一成不变就能放之四海而皆准的,具体问题具体分析,根据业务环境的选择才是正途。正如这篇博文所说,二者之间,其实并没有什么本质上的区别,更多的是思想观念和具体操作流程上的区别。

Read More

这几天复习审计复习的头昏眼花,间隙间把《javaScript DOM 编程艺术》一书看了一遍。嗯,做一做读书笔记,以后可以看看。

DOM

DOM(document object model)是文档对象模型。当宿主是浏览器,或者是需要解析标记性文本文档的时候,就会有DOM的概念。嗯,根据惯例,先讲理论。

文档 Document

文档简单的说,是字符串的集合,是标记符号的集合。对于一般的字符串而言,浏览器并不会对他们进行过多的解析,只有当这些字符串被能被浏览器识别的标记符号包裹的时候,浏览器才会对该文档进行对象化操作,生成DOM tree。

对象 Object

对象的话,DOM的本身之意其实就是把标记文档进行对象化,是他们能够成为可操作的对象节点。JavaSript的对象分成三类:

  • 用户定义的对象

    1
    var a = {}; 
    var o = new Object();
  • 内建对象 js语言自带的对象,其实吧,我觉得每一个引用类型都是一个自建对象啊arrayfunctionRegExp,Date等除了那五个初始类型(Null,Undefined,BooleanNumber,String

1
var date = new Date();
var a = [];
var a = new Audio();
var a = new String();
//tips:new String 得到是一个Object而不是string。
“asdfe” === new String("asdfe");//false
  • 宿主对象:
    • window Object 窗口对象模型(BOM)是最基础的宿主对象
      • document Obcject
      • location
      • history

模型 Model

模型的话,这个我的理解是解释的对象解析的本身关系的样子。嗯,DOM的话其实就是树啦,正所谓DOM tree嘛。用来表示各个对象节点之间的关系是什么。
一个简单的DOM tree如下图:DOM tree

Read More

在上一篇文章里,我们已经解释了如何脚本化一个音频文件,并对它做一个傅里叶变换,然后进行音频分析。我们可以把上次的代码做个模块化处理。这样比较方便调用。

1
define('wavemodule',['zepto','loadAudio'],function(require,exports,module){
    var loadAudio = require("loadAudio"),
        $ = require('zepto'),
        context = new AudioContext(),
        analyser = context.createAnalyser(),
        displayWave = function(waveByteDate){
            var canvas = $('#display')[0];
            var canvasContext = canvas.getContext('2d');
            canvasContext.fillStyle = "#428bca";
            canvasContext.clearRect(0,0,1024,100);
            for(var i = 0; i<waveByteDate.length; i++){
                canvasContext.fillRect(i,100,1,(0- (waveByteDate[i]/255 * 100)));
            }
            canvasContext.stroke();
        },
        playSoud = function(buffer) {
            console.log("work here");
            var source = context.createBufferSource();
            source.buffer = buffer;
            source.connect(analyser);
            analyser.smoothingTimeConstant = 0.8;
            analyser.connect(context.destination);
            var handler = setInterval(function(){
                var waveByteDate = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(waveByteDate);
                displayWave(waveByteDate);//绘制波形
            },10)
            source.start(0);
            source.ended = function(){
                $("#wave").getContext("2d").clearRect(0,0,1024,100);
                clearInterval(handler);
            }
            source.stop = function(){
                if(!source.stop){
                    source.stop = source.noteOff;
                }
            };
        };

    exports.start = function(url){
        console.log("work here");
        loadAudio.setconfig(context,url,playSoud);
        loadAudio.start();
    };
})

processor

好了,这次,我们讲的东西比较简单,实现一个将键盘输入的1,2,3,4,5,6,7播放成dou ri mi fa so la xi dou。

定义

这里涉及到一个可编辑音乐节点的问题。我们需要用到一个叫做ScriptProcessorNode(脚本处理节点)这个节点用于生成,处理,或使用JavaScript分析的音频节点。它有两个缓冲区,一个是包含所输入的音频数据,另一个则包含处理后的输出音频数据的audioNode节点。通过Processing来实现以下几个事件

  • 每次输入缓冲器有新数据时发送给对象,
  • 事件处理程序终止时,将已有的数据填充到数据输出缓冲器

    Read More

由上,我们已经可以很简单的在页面中播放声音了,就像这样:

1
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Audio</title>
        <body>
            <button id="play">play</button>
            <button id="stop">stop</button>
            <button id=""pause>pause</button>
            <script type="application/javascript">
            (function(){
                var $ = function(selector){
                    return document.getElementById(selector);
                },
                play = $("play"),
                stop = $("stop"),
                pause = $("pause"),
                Audio.prototype.stop = function(){
                    this.pause();
                    this.currentTime = 0;
                },
                player = neew Audio("path\to\audio");
                
                play.addEventListener("click",function(){
                    player.play();
                },false);
                
                stop.addEventListener("click",function(){
                    player.stop();
                },false);
                
                pause.addEventListener("click",function(){
                    player.pause();
                },false);
                
                })();
            </script>
        </body>
    </head>
</html>

嗯,但是,这样好像并没有什么很酷炫的东西,样式什么的,去我的github上看成品,虽然也还是很难看。。。
好了,我们来点更酷炫一点的东西。我们这里要用到一个高级接口,叫做audiocontext。具体的接口说明可以参考MDN,和W3C上的解释。

audioContext 接口

嗯,这个接口其实蛮有意思的,它并不能直接播放音源,但是它可以解析音源,并对音源进行一些处理,然后将音源传回给Audio接口进行播放。嗯,我们来看一张图。


|——————————————————-|
| audioContext |
| |—————-| |—————-| |
| |auidoNode | => | duration | |
| |—————-| |—————-| |
|——————————————————-|

Read More