JavaScript in Browser
刁星渊
2023-12-01
介绍host概念
与普通的语言不同的是,JavaScript一开始就被设计为一个嵌入式的语言。这意味着,它是寄生在某个环境中而不是自足的。当然,这也意味着其运行环境的边境就是JavaScript的能力边境。JavaScript所寄居的那个运行环境叫做JavaScript的Host。JavaScript跟Host环境之间可以进行非常方便的交流和沟通,并且,以其寄宿的Host作为自己的世界。JavaScript的Host多种多样,包括Browser,Web Server,Flash player,Photoshop,……以及所有支持以JavaScript为其接口脚本语言的各种环境。这儿,我们的重点就是Brower。
window就是Global
我们知道,JavaScript语言规范本身定义了一系列的对象。这些对象被称作built-in对象,它要求JavaScript无论在任何Host中都拥有,或者说Built-in对象就是一个约定。也就是说,JavaScript期望这些built-in对象在任何Host中都是一致的。当然, Host可以增添一些对象,或者修改一些对象的property,毕竟,我们知道修改JavaScript对象是很方便的。在Browser这个 JavaScript最流行的Host里面,增加了很多Host定义的对象,这些对象全是被一个标准体系规定的,这个体系叫做DOM。下面我会详细的介绍 DOM标准的。不过需要明确指出的是:Browser对于DOM标准总是半遮半掩,也就是说:它们实现了部分的DOM标准,同时又扩展了部分DOM没有规定的东西。
无论如何,我们首先需要明确的是:window就是Global。Global是JavaScript的内建对象,window是 Brower提供的Global对象,不过,名字叫window。实现基本上类似于var window = Global; window.newProperty = content; window.oldProperty = updateContent;……。window也像Global一样,可以省略"window."来直接引用其属性。
附加的对象有哪些?
Brower 向JavaScript中附加的对象是非常多的。而且对于不同的Browser,其附加的对象也各不相同。不过大致都会有window(作为Global 存在,提供一些基本的实用功能),document(作为Brower中展现的文档的入口存在),styleSheet(作为样式单操作入口), event(作为事件),xmlHttpRequest(作为异步http通信通道)等等。后面我们自然要一一深究这些对象,不过现在我们可以暂且放过它们。
DOM是什么
DOM是Document Object Model的缩写,它是一个标准族。它规定了Browser相关的对象扩展应该有哪些properties,它们各是什么意义和作用等等。由于DOM是一个独立标准,并不依赖于JavaScript(也就是说,它规定了Browser应该提供的对象以及接口,可是这些对象是用JavaScript引用还是用C++引用它并没有规定),所以它是用了语言独立的IDL来描述这些对象的外貌和功用。关于DOM跟JavaScript的关联,他们把它叫做 binding。
再一次明确一下,DOM是一个标准族,它描述了Browser应该提供的对象的接口。
DOM标准族包括哪些?
DOM 标准族包括XML DOM,HTML DOM,CSS DOM……,其中每一个都有可能是好几个相关的部分组成的。其中最为主要的标准系列就是XMLDOM了。我准备把它们的规范用IDL描述出来,在我认为必要的地方加上简短的说明。关于IDL,其实完全是不言自明的,所以我就不介绍IDL的语法了。
注意:我描述的DOM规范,比较新,有很多特性还没有被Browser支持,而且有些可能还会改动,但改动的幅度不会很大。但是我宁愿描述一个新的合理的规范,也不愿意描述一个老的不完全的规范。
现在开始XML DOM的描述,这是整个DOM标准的核心和基础。DOM标准的基本思想是把一个用标签(tag)标记(mark)的文本文档看作一棵树,文本文档中的任何一段文本都属于这个树的某个节点,每个节点都有一个唯一的父结点,都有若干子节点和属性。
下面是XML DOM的core部分,基础中的基础。
valuetype DOMString sequence<unsigned short>
typedef unsigned long long DOMTimeStamp;
typedef any DOMUserData;
typedef Object DOMObject;
interface DOMImplementation;
interface DocumentType;
interface Document;
interface NodeList;
interface NamedNodeMap;
interface UserDataHandler;
interface Element;
interface TypeInfo;
interface DOMLocator;
exception DOMException
{
unsigned short code;
};
// ExceptionCode
const unsigned short INDEX_SIZE_ERR = 1;
const unsigned short DOMSTRING_SIZE_ERR = 2;
const unsigned short HIERARCHY_REQUEST_ERR = 3;
const unsigned short WRONG_DOCUMENT_ERR = 4;
const unsigned short INVALID_CHARACTER_ERR = 5;
const unsigned short NO_DATA_ALLOWED_ERR = 6;
const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
const unsigned short NOT_FOUND_ERR = 8;
const unsigned short NOT_SUPPORTED_ERR = 9;
const unsigned short INUSE_ATTRIBUTE_ERR = 10;
const unsigned short INVALID_STATE_ERR = 11;
const unsigned short SYNTAX_ERR = 12;
const unsigned short INVALID_MODIFICATION_ERR = 13;
const unsigned short NAMESPACE_ERR = 14;
const unsigned short INVALID_ACCESS_ERR = 15;
const unsigned short VALIDATION_ERR = 16;
const unsigned short TYPE_MISMATCH_ERR = 17;
interface DOMStringList
{
DOMString item(in unsigned long index);
readonly attribute unsigned long length;
boolean contains(in DOMString str);
};
interface NameList
{
DOMString getName(in unsigned long index);
DOMString getNamespaceURI(in unsigned long index);
readonly attribute unsigned long length;
boolean contains(in DOMString str);
boolean containsNS(in DOMString namespaceURI, in DOMString name);
};
interface DOMImplementationList
{
DOMImplementation item(in unsigned long index);
readonly attribute unsigned long length;
};
interface DOMImplementationSource
{
DOMImplementation getDOMImplementation(in DOMString features);
DOMImplementationList getDOMImplementationList(in DOMString features);
};
interface DOMImplementation
{
boolean hasFeature(in DOMString feature, in DOMString version);
DocumentType createDocumentType(in DOMString qualifiedName, in DOMString publicId, in DOMString systemId) raises(DOMException);
Document createDocument(in DOMString namespaceURI, in DOMString qualifiedName, in DocumentType doctype) raises(DOMException);
DOMObject getFeature(in DOMString feature, in DOMString version);
};
interface Node
{
// NodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
readonly attribute DOMString nodeName;
attribute DOMString nodeValue;
// raises(DOMException) on setting
// raises(DOMException) on retrieval
readonly attribute unsigned short nodeType;
readonly attribute Node parentNode;
readonly attribute NodeList childNodes;
readonly attribute Node firstChild;
readonly attribute Node lastChild;
readonly attribute Node previousSibling;
readonly attribute Node nextSibling;
readonly attribute NamedNodeMap attributes;
readonly attribute Document ownerDocument;
Node insertBefore(in Node newChild, in Node refChild) raises(DOMException);
Node replaceChild(in Node newChild, in Node oldChild) raises(DOMException);
Node removeChild(in Node oldChild) raises(DOMException);
Node appendChild(in Node newChild) raises(DOMException);
boolean hasChildNodes();
Node cloneNode(in boolean deep);
void normalize();
boolean isSupported(in DOMString feature, in DOMString version);
readonly attribute DOMString namespaceURI;
attribute DOMString prefix;
// raises(DOMException) on setting
readonly attribute DOMString localName;
boolean hasAttributes();
readonly attribute DOMString baseURI;
// DocumentPosition
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
unsigned short compareDocumentPosition(in Node other) raises(DOMException);
attribute DOMString textContent;
// raises(DOMException) on setting
// raises(DOMException) on retrieval
boolean isSameNode(in Node other);
DOMString lookupPrefix(in DOMString namespaceURI);
boolean isDefaultNamespace(in DOMString namespaceURI);
DOMString lookupNamespaceURI(in DOMString prefix);
boolean isEqualNode(in Node arg);
DOMObject getFeature(in DOMString feature, in DOMString version);
DOMUserData setUserData(in DOMString key, in DOMUserData data, in UserDataHandler handler);
DOMUserData getUserData(in DOMString key);
};
interface NodeList
{
Node item(in unsigned long index);
readonly attribute unsigned long length;
};
interface NamedNodeMap
{
Node getNamedItem(in DOMString name);
Node setNamedItem(in Node arg) raises(DOMException);
Node removeNamedItem(in DOMString name) raises(DOMException);
Node item(in unsigned long index);
readonly attribute unsigned long length;
Node getNamedItemNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
Node setNamedItemNS(in Node arg) raises(DOMException);
Node removeNamedItemNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
};
interface CharacterData : Node
{
attribute DOMString data;
// raises(DOMException) on setting
// raises(DOMException) on retrieval
readonly attribute unsigned long length;
DOMString substringData(in unsigned long offset, in unsigned long count) raises(DOMException);
void appendData(in DOMString arg) raises(DOMException);
void insertData(in unsigned long offset, in DOMString arg) raises(DOMException);
void deleteData(in unsigned long offset, in unsigned long count) raises(DOMException);
void replaceData(in unsigned long offset, in unsigned long count, in DOMString arg) raises(DOMException);
};
interface Attr : Node
{
readonly attribute DOMString name;
readonly attribute boolean specified;
attribute DOMString value;
// raises(DOMException) on setting
readonly attribute Element ownerElement;
readonly attribute TypeInfo schemaTypeInfo;
readonly attribute boolean isId;
};
interface Element : Node
{
readonly attribute DOMString tagName;
DOMString getAttribute(in DOMString name);
void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
void removeAttribute(in DOMString name) raises(DOMException);
Attr getAttributeNode(in DOMString name);
Attr setAttributeNode(in Attr newAttr) raises(DOMException);
Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
NodeList getElementsByTagName(in DOMString name);
DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException);
void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
Attr setAttributeNodeNS(in Attr newAttr) raises(DOMException);
NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
boolean hasAttribute(in DOMString name);
boolean hasAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException);
readonly attribute TypeInfo schemaTypeInfo;
void setIdAttribute(in DOMString name, in boolean isId) raises(DOMException);
void setIdAttributeNS(in DOMString namespaceURI, in DOMString localName, in boolean isId) raises(DOMException);
void setIdAttributeNode(in Attr idAttr, in boolean isId) raises(DOMException);
};
interface Text : CharacterData
{
Text splitText(in unsigned long offset) raises(DOMException);
readonly attribute boolean isElementContentWhitespace;
readonly attribute DOMString wholeText;
Text replaceWholeText(in DOMString content) raises(DOMException);
};
interface Comment : CharacterData
{
};
interface TypeInfo
{
readonly attribute DOMString typeName;
readonly attribute DOMString typeNamespace;
// DerivationMethods
const unsigned long DERIVATION_RESTRICTION = 0x00000001;
const unsigned long DERIVATION_EXTENSION = 0x00000002;
const unsigned long DERIVATION_UNION = 0x00000004;
const unsigned long DERIVATION_LIST = 0x00000008;
boolean isDerivedFrom(in DOMString typeNamespaceArg, in DOMString typeNameArg, in unsigned long derivationMethod);
};
interface UserDataHandler
{
// OperationType
const unsigned short NODE_CLONED = 1;
const unsigned short NODE_IMPORTED = 2;
const unsigned short NODE_DELETED = 3;
const unsigned short NODE_RENAMED = 4;
const unsigned short NODE_ADOPTED = 5;
void handle(in unsigned short operation, in DOMString key, in DOMUserData data, in Node src, in Node dst);
};
interface DOMError
{
// ErrorSeverity
const unsigned short SEVERITY_WARNING = 1;
const unsigned short SEVERITY_ERROR = 2;
const unsigned short SEVERITY_FATAL_ERROR = 3;
readonly attribute unsigned short severity;
readonly attribute DOMString message;
readonly attribute DOMString type;
readonly attribute DOMObject relatedException;
readonly attribute DOMObject relatedData;
readonly attribute DOMLocator location;
};
interface DOMErrorHandler
{
boolean handleError(in DOMError error);
};
interface DOMLocator
{
readonly attribute long lineNumber;
readonly attribute long columnNumber;
readonly attribute long byteOffset;
readonly attribute long utf16Offset;
readonly attribute Node relatedNode;
readonly attribute DOMString uri;
};
interface DOMConfiguration
{
void setParameter(in DOMString name, in DOMUserData value) raises(DOMException);
DOMUserData getParameter(in DOMString name) raises(DOMException);
boolean canSetParameter(in DOMString name, in DOMUserData value);
readonly attribute DOMStringList parameterNames;
};
interface CDATASection : Text
{
};
interface DocumentType : Node
{
readonly attribute DOMString name;
readonly attribute NamedNodeMap entities;
readonly attribute NamedNodeMap notations;
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
readonly attribute DOMString internalSubset;
};
interface Notation : Node
{
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
};
interface Entity : Node
{
readonly attribute DOMString publicId;
readonly attribute DOMString systemId;
readonly attribute DOMString notationName;
readonly attribute DOMString inputEncoding;
readonly attribute DOMString xmlEncoding;
readonly attribute DOMString xmlVersion;
};
interface EntityReference : Node
{
};
interface ProcessingInstruction : Node
{
readonly attribute DOMString target;
attribute DOMString data;
// raises(DOMException) on setting
};
interface DocumentFragment : Node
{
};
interface Document : Node
{
readonly attribute DocumentType doctype;
readonly attribute DOMImplementation implementation;
readonly attribute Element documentElement;
Element createElement(in DOMString tagName) raises(DOMException);
DocumentFragment createDocumentFragment();
Text createTextNode(in DOMString data);
Comment createComment(in DOMString data);
CDATASection createCDATASection(in DOMString data) raises(DOMException);
ProcessingInstruction createProcessingInstruction(in DOMString target, in DOMString data) raises(DOMException);
Attr createAttribute(in DOMString name) raises(DOMException);
EntityReference createEntityReference(in DOMString name) raises(DOMException);
NodeList getElementsByTagName(in DOMString tagname);
Node importNode(in Node importedNode, in boolean deep) raises(DOMException);
Element createElementNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
Attr createAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName);
Element getElementById(in DOMString elementId);
readonly attribute DOMString inputEncoding;
readonly attribute DOMString xmlEncoding;
attribute boolean xmlStandalone;
// raises(DOMException) on setting
attribute DOMString xmlVersion;
// raises(DOMException) on setting
attribute boolean strictErrorChecking;
attribute DOMString documentURI;
Node adoptNode(in Node source) raises(DOMException);
readonly attribute DOMConfiguration domConfig;
void normalizeDocument();
Node renameNode(in Node n, in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException);
};
上面说了,这是标准中的基础部分,而且,也是标准中最重要的部分,实际上,如果你知道了这些接口(再加上这些标准接口跟JavaScript在Browser这个Host中的对象的binging),你就可以进行几乎所有的Browser端编程了。