js常用方法和一些封装(3) -- dom相关

js一个非常重要的作用就是对dom进行操作,所谓的dom,可以理解为html代码里的一个个节点。比如,body标签元素就是一个dom。本文对js的dom操作进行一些总结。

按照惯例,先上一个刚写好的小例子,代码在最后给出:

1.gif

现在,来看看js对dom的一些操作吧。

首先,给出一个html模板,接下来开始用js来做一些有趣的事情吧,css样式的绘制就不细说了,先上代码:

css
*{margin: 0;padding: 0;}
.parent {
    width: 305px;
    height: 302px;
    background: #d7e6ea;
    margin: 100px auto;
    
}
.parent .child {
    width: 80px;
    height: 80px;
    background: deepskyblue;
    float: left;
    margin-top: 10px;
    margin-left: 9px;
    margin-right: 12px;
    margin-bottom: 12px;
    box-shadow: 3px -3px 2px #9898c7;
    text-align: center;
    line-height: 80px;
    font-family: "微软雅黑";
    font-size: 28px;
    text-shadow: 2px 2px 2px yellowgreen;
}
html
<body>
    <div class='parent'>
        <div class='child'>1</div>
        <div class='child'>2</div>
        <div class='child'>3</div>
        <div class='child'>4</div>
        <div class='child'>5</div>
        <div class='child'>6</div>
        <div class='child'>7</div>
        <div class='child'>8</div>
        <div class='child'>9</div>
    </div>
</body>
效果图
Paste_Image.png

从代码中,我们可以看到,body是一个大节点,里面套了一个class属性为parent的div盒子,然后我们又在这个盒子里面放了9个小盒子。

1.最简单的dom方法封装

在本系列中,假设我们不考虑用jQuery。
现在给第三个盒子添加一个id。

<div id='targetBox' class='child'>3</div>

如何拿到这个盒子呢?
很显然,最先想到的肯定是document.getElementById() 方法,于是就有了这样的代码。

var box = document.getElementById('targetBox');
box.style.background = '#FEAF51';

效果:

Paste_Image.png

当然,我们很多时候都不希望每次都把document.getElementById(id)给写一遍,那么,是不是可以将这一个过程封装起来呢?

于是,自然而然的,我们会这么写:

//获取JavaScript的dom对象
function dom(id){
    return document.getElementById(id);
};

var box = dom('targetBox');
box.style.background = '#FEAF51';

完美运行,我们知道,在jQuery中,是这样的:

var box = $('#targetBox');

那么,为了让代码更加山寨,不妨将dom方法稍微改进一下嘞!

//获取JavaScript的dom对象
function dom(id){
    if(id.toString().indexOf('#') != -1) {
        id = id.replace('#','');
    }
    return document.getElementById(id);
};

var box = dom('#targetBox');
box.style.background = '#FEAF51';

2.如何获取dom元素在父盒子中的位置?

刚才,我们已经获得了编号为3的div盒子,要得到它在父盒子的角标位置,首先肯定要拿到它的父盒子对象吧。

像这样:

var box = dom('#targetBox');
var parent = box.parentElement;

parent打印出来是这样的:

Paste_Image.png

看来很顺利呢,接下来因为要知道目标元素在父盒子的位置,则需要拿到父盒子所有的孩子节点。

像这样:

var children = parent.children;

打印结果:

Paste_Image.png

接下来就要遍历这些孩子节点啦,children 的数据类型是object。
然而,在js中我们可以遍历数组,却无法直接遍历object,咋办呢?

原来,这是一个特殊的object,因为它有一个length属性。有length属性的object,可以通过以下方式转换成数组(注:当然,这边也可以直接获取获取object中的length,然后来遍历。):

Array.prototype.slice.call(object);

举个例子:

var obj ={length:2,0:'first',1:'second'};
objArr = Array.prototype.slice.call(obj);
alert(objArr);

结果:


Paste_Image.png

注1: length是几个,就转换几个,如果你length写1,那么只弹出first。
注2: key必须为数字,而且与数组的角标是对应的。

这里不深究call的的意思,我会在以后重新写这方面的内容。

回到正题,现在可以拿到数组形式的children了!

var children = Array.prototype.slice.call(parent.children);

开始遍历:

for(var i = 0,len = children.length;i < len;i++){
    if(children[i] == box){
        alert(i);
    }
}

结果:

Paste_Image.png

弹出来下标是2,因为数组下标的起始值是从0开始的。

上面的循环结构还欠缺了一个东西,就是一旦找到box之后,因为及时退出循环才是。像这样:

for(var i = 0,len = children.length;i < len;i++){
    if(children[i] == box){
        alert(i);
        break;
    }
}

这样便可以一定程度地提高性能。顺便附上forEach的写法:

children.forEach(function(child,index){
    if(child == box){
        alert(index);
        return false;
    }
});

这样也可以,最后,将这些内容封装成方法,就采用forEach的方式吧!

//查找当前dom元素在父盒子中的位置
function getIndex(dom){
    var index = -1;
    var domArr = Array.prototype.slice.call(dom.parentElement.children);
    domArr.forEach(function(obj,i){
        if(obj==dom){
            index = i;
            return false;
        }
    });
    return index;
};

我学习js的路线就是如此,先想尽办法把功能实现了,然后才开始封装成方法。封装的好处不言而喻,没有人喜欢每次用到这个功能的时候,就去把实现代码拷贝一份吧。

3.如何获取parent下面指定class的元素列表?

parent盒子下面有9个孩子节点,我们能否通过一个什么办法获取到这9个孩子节点呢?显然,这些孩子节点都有一个共同的className,那么我们可以通过这个className来获取。

IE9 + 已经可以通过下面的方式来实现了:

var children = parent.getElementsByClassName('child');

效果:

1.gif

IE678还是不支持的,那么,如果让我们自己来封装一个方法,又该如何呢?

这里提供一种思路:
1.用getElementsByTagName获取parent元素下所有的节点。
2.遍历这些节点,比较className,如果相同,就用一个数组装起来。
3.返回这个数组。

上代码:

/*通过className获取dom元素进行过滤*/
function getClass(pid,sClass){
    var aEle = dom(pid).getElementsByTagName('*');
    var arrs = [];
    for(var i=0;i<aEle.length;i++){
        if(aEle[i].className.indexOf(sClass)!=-1){
            arrs.push(aEle[i]);
        }
    }
    return arrs;
}

最后,附上最开始小例子的源码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
               *{margin: 0;padding: 0;}
            body {
                background: url(https://ss1.bdstatic.com/lvoZeXSm1A5BphGlnYG/skin/12.jpg?2) no-repeat;
                background-size: 100% 128%;
                overflow: hidden;
            }
            .content {
                height: 600px;
                width: 305px;
                margin: 100px auto;
                position: relative;
                border-top:8px solid #ccc;
                border-right:10px solid #ccc;
            }
            
            .content .screen {
                height: 298px;
                width: 305px;
                background: #333;
                position: absolute;
            }
            .content .screen .icon {
                width: 78px;
                height: 78px;
                display: inline-block;
                background: url(android.png) no-repeat;
                background-size: 100% 100%;
                position: absolute;
                top: 50%;
                left: 50%;
                margin-top: -39px;
                margin-left: -39px;
            }
            
            .parent {
                width: 305px;
                height: 302px;
                background: #d7e6ea;
                position: absolute;
                bottom: 0px;
                
            }
            .parent .child {
                width: 80px;
                height: 80px;
                background: #eee;
                float: left;
                margin-top: 10px;
                margin-left: 9px;
                margin-right: 12px;
                margin-bottom: 12px;
                box-shadow: 3px -3px 2px #9898c7;
                text-align: center;
                line-height: 80px;
                font-family: "微软雅黑";
                font-size: 28px;
                text-shadow: 2px 2px 2px yellowgreen;
            }
            .parent .child:hover {
                cursor: pointer;
                background: linear-gradient(#ccc,#666);
            }
            
            .putIn {
                position: absolute;
                width:100%;
                height:60px;
                line-height: 60px;
                color: #fff;
                bottom:0;
                right: 0;/*为了让padding起作用*/
                text-align:right;
                font-size: 40px;
                overflow: hidden;
                padding-right: 8px;
                padding-bottom: 8px;
            }


        </style>
    </head>
        <body>
            <div class="content">
                <div class="screen">
                    <i class="icon"></i>
                    <span id="putIn" class="putIn"></span>
                </div>
                <div class='parent'>
                    <div class='child'>1</div>
                    <div class='child'>2</div>
                    <div id='targetBox' class='child'>3</div>
                    <div class='child'>4</div>
                    <div class='child'>5</div>
                    <div class='child'>6</div>
                    <div class='child'>7</div>
                    <div class='child'>8</div>
                    <div class='child'>9</div>
                </div>
            </div>
            
        </body>

    
    <script>

        //获取JavaScript的dom对象
        function dom(id){
            if(id.toString().indexOf('#') != -1) {
                id = id.replace('#','');
            }
            return document.getElementById(id);
        };
        
        var buttons = document.getElementsByClassName('child');
        var putIn = dom('#putIn');
        for(var i = 0,len = buttons.length;i < len;i++){
            buttons[i].onclick = function(){
                var num = this.innerHTML;
                if(putIn.innerText.length < 13 )
                    putIn.innerText = putIn.innerText + num;
                
            }
        }

    </script>
</html>

本章结束 ...

剽悍一小兔,电气自动化毕业。
参加工作后对计算机感兴趣,深知初学编程之艰辛。
希望将自己所学记录下来,给初学者一点帮助。

免责声明: 博客中所有的图片素材均来自百度搜索,仅供学习交流,如有问题请联系我,侵立删,谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容