JavaScript基础练习源码(一)DOM相关
sshong 发表于2013年4月24日 21:08:06 更新于2013年5月3日 19:15:10
最近从头学习javascript,自己写的一些练习源码用于加深理解,记录备查。

1、DOM相关

1.1 基础概念
htmltree
在一个html文档(树)中,所有的东西都是Node节点。Node是最基础的基类,有子类Document、Element、CharacterData(text、comment)。

其中Document代表一个html文档,是最顶层节点,js中可以用window.document(document)引用到。

html标签代表的是最顶层的元素element(HTMLHtmlElement),js中可以用document.documentElement引用到。

Node类定义了一些基本的属性和方法,如childNodes、nodeType、nodeName、nodeValue。
一个document节点,他的childNodes通常至少包括一个顶层htmlelement(html标签),还可以有Doctype节点、comment注释节点。
一个顶层html element(<html>),通常至少包括一个head element(<head> HTMLHeadElement)、body(<body> HTMLBodyElement),这两个element可以用document.head合document.body引用到
考虑如下代码:

<!DOCTYPE html>
<!-- this is a comment -->
<html>
<head>
    <title>test DOM 2(www.asarea.me)</title>
    <script type="text/javascript">
        window.onload = function() {
            //一个html页面所有都是Node,Node是最上层的基类
            console.log(document, document.nodeType, document.nodeName, document.nodeValue);
            var nodes = document.childNodes;
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                console.log(node, node.nodeType, node.nodeName, node.nodeValue);
            };
        }
    </script>
</head>
</html>

输出:
dom1

1.2 操作

1.2.1 获取element
Node对我们来说通常用处不大,我们通常需要直接操作的是Element。
一个Element是由一个tag加上一些属性组成。因此Element新增加了一些属性和方法,如tagName,children(只返回子elements),getAttribute等。
获取Element的方法,通常用到document的几个方法,
A、根据id:getElementById
B、根据name:getElementsByName
C、根据tag类型:getElementsByTagName
D、根据classname:getElementsByClassName
E、采用css选择器:querySelectorAll、querySelector(不同浏览器有兼容性问题,可以采用jquery封装的sizzle,支持强大的css选择器语法同时解决兼容性问题)。

考虑如下代码:
<html>
<head>
    <title>test query(www.asarea.me)</title>
    <script type="text/javascript">
        window.onload = function() {
            //为element分配id属性会自动定义一个id值的属性在window上,不是在document上
            //尽量采用document.getElementById为不要采用window.**方式获取element
            console.log(window.divA, document.divA);
            console.log(window.divA === document.getElementById('divA'));

            console.log('------------------');

            console.log(document.getElementsByName('formA'));
            console.log(document.getElementsByName('txtA'));

            console.log('------------------');

            console.log(document.getElementsByTagName('div'));
            console.log(document.getElementsByTagName('span'));

            console.log('------------------');

            console.log(document.getElementsByClassName('left'));
            console.log(document.getElementsByClassName('left right'));

            console.log('------------------');

            console.log(document.querySelectorAll('.left'));
            console.log(document.querySelector('.left'));
            console.log(document.querySelectorAll('*[id="divA"]'));
        }
    </script>
</head>
<body>
    <div id='divA'>divA</div>
    <div id='divB' class='left right'>divB</div>
    <span id='spanA' class='left'>spanA</span>
    <form name='formA' onsubmit='return false;'>
        <input type='text' name='txtA'>
    </form>
</body>
</html>
输出:
element query

1.2.2 获取element属性
获取element属性的途径都是定义在Element中:
A、HtmlElement定义了一些标准的html属性,可以直接获取,如ele.id,ele.onclick等。属性值可以是字符串、布尔值、cssstyleDeclaration、function。
B、Element的getAttribute方法可以用来获取标准、非标准属性,但是属性值永远当做 字符串!!
C、非标准属性除了用getAttribute获取外,还可以用dataset属性来获取设置(前提是属性名必须是data-),这是html5中新增的
D、还有可以用attributes来获取,属性值也是当做字符串

考虑如下代码:
<html>
<head>
    <title>test attribute(www.asarea.me)</title>
    <script type="text/javascript">
        window.onload = function() {
            var ele = document.getElementById('textA');
            //取不到返回null,而非undefined
            console.log(ele === null, ele === undefined);
            //HtmlElement定义了一些标准的html属性,可以直接获取,属性值可以是字符串、布尔值、cssstyleDeclaration、function
            console.log(ele.id, ele.required, ele.style, ele.onclick);
           
            //getAttribute可以用来获取标准、非标准属性,属性值永远当做 字符串!!
            console.log(ele.getAttribute('id'), ele.getAttribute('required'), ele.getAttribute('style'), ele.getAttribute('onclick'));
            //非标准属性除了用getAttribute获取外,还可以用dataset属性来获取设置(前提是属性名必须是data-)
            console.log(ele.getAttribute('data-test'), ele.dataset.test);

            //还有可以用attributes来获取,属性值也是当做字符串
            console.log(ele.attributes.id.value, ele.attributes.style.value, ele.attributes['data-test'].value);
        }
    </script>
</head>
<body>
    <input type='text' id='textA' required data-test='test' style='width:100' onclick='alert("click");'></div>
</body>
</html>
输出:
element attr

1.2.3 获取、设置element内容
element内容可以有html源码格式,也可以是纯文本格式。
获取、设置element内容的方法有:
1、html源码格式,可以通过Element的innerHTML、outerHTML(带自身标签)获取&设置。
2、纯文本格式,可以通过Node的属性textContent,而IE只支持HTMLElement的innerText(innerText尝试保留一些格式)

考虑如下代码:
<html>
<head>
    <title>test content(www.asarea.me)</title>
    <script type="text/javascript">
        window.onload = function() {
            var ele = document.getElementById('divA');
            //element的属性:innerHTML outerHTML
            console.log(ele.innerHTML, ele.outerHTML);

            console.log('------------------');

            //node的属性textContent, IE的innerText(innerText尝试保留一些格式)
            console.log(ele.textContent, ele.innerText);

            console.log('------------------');

            console.log(getTextContent(ele));
        }

        function getTextContent(ele) {
            //如果是text类型
            if(ele.nodeType === 3) {
                return ele.nodeValue;
            }
            //否则递归找所有子node
            else {
                var s = '';
                for (var i = 0; i < ele.childNodes.length; i++) {
                    s += getTextContent(ele.childNodes[i]);
                }
                return s;
            }
        }
    </script>
</head>
<body>
    <div id='divA'>
        this is <p> paragraph. </p> this is <b>bold text</b>.
    </div>
</body>
</html>

输出如下:
element content

1.2.4 创建、复制、插入、替换、删除element
创建节点可以用document.createElement方法,传入标签名。也可以用document.createTextNode方法创建text纯文本节点。
复制节点可以用node.cloneNode方法,传入true代表深度复制。
插入节点用node.insertBefore或者node.appendChild方法。
替换节点用node.replaceChild方法。
删除节点用node.removeChild方法。

另外有一个叫片段的特殊node,可以作为一系列节点的暂时容器,然后将这个片段统一插入到某element下。
片段的创建方法:document.createDocumentFragment();

参考如下代码:
<html>
<head>
    <title>test modify elements(www.asarea.me)</title>
    <script type="text/javascript">
        var createIndex = 0;

        window.onload = function () {
            addListener(document.getElementById('btnCreate'), 'click', onCreate);
            addListener(document.getElementById('btnSort'), 'click', onSort);
        }

        function onCreate() {
            createIndex++;
            var newEle = document.createElement('div');
            newEle.innerHTML = 'This is the ' + createIndex + ' created item. <button onclick="onDelete(this)">删除</button><button onclick="onReplace(this)">替换</button>';

            var parent = document.getElementById('dynamicDiv');
            parent.appendChild(newEle);
        }

        function onReplace(btn) {
            var ele = btn.parentNode;
            var newEle = document.createTextNode('This is replaced');
            ele.parentNode.replaceChild(newEle, ele);
        }

        function onDelete(btn) {
            var ele = btn.parentNode;
            ele.parentNode.removeChild(ele);
        }

        function onSort() {
            //片段器,是一个节点临时容器
            var frag = document.createDocumentFragment();
            var parent = document.getElementById('dynamicDiv');
            //将子节点倒序加入片段器
            while(parent.lastChild) {
                frag.appendChild(parent.lastChild);
            }
            //再总体加入父容器
            parent.appendChild(frag);
        }

        function addListener(obj, evt, handler) {
            if(obj.addEventListener) {
                obj.addEventListener(evt, handler);
            }
            else if(obj.attachEvent) {
                obj.attachEvent('on' + evt, handler);
            }
        }
    </script>
</head>
<body>
    <div id='dynamicDiv'>
    </div>
    <button id='btnCreate'>创建</button>
    <button id='btnSort'>倒序</button>
</body>
</html>

效果如下:
modify dom
标签:无分类:JS&Html5阅读:2566
评论
暂无评论
添加评论
您的大名,限长10汉字,20英文(*)
电子信箱(*)
您的网站
正文,限长500汉字,1000英文(*)
验证码(*) 单击刷新验证码
联系我
博客订阅