05.使用Dom操作css

首先我们先不讨论css 先看下如何获取dom节点

  • 获取子节点
    Element.childElementCount获取子元素的个数。child儿子,Element元素,Count数量
<div class="box">
    1
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p class="four">5</p>
</div>
<script>
    var oP = document.querySelector('.box')
    console.log( oP )/*
        <div class="box">
            1
            <p>2</p>
            <p>3</p>
            <p>4</p>
            <p class="four">5</p>
        </div>
    */
    
    //元素是一个对象,对象上有一个属性叫做childElementCount,保存了当前元素有几个子元素
    console.log( oP.childElementCount )//4
    
    console.log( oP.childNodes )//NodeList(9) [text, p, text, p, text, p, text, p.four, text]
</script>

打印的结果是4,这里我们发现,没有被包裹在任何标签里的1并没有被算在里边,因为他是childElementCount(获取子元素数量),而孤零零的这个1并不是子元素。

那怎么能获取到这个 1 呢 接下来我们个方法 叫做Element.childNodes获取子节点

那么有小伙伴会问啦何为节点?
元素里的标签,文本包括换行的空格都是节点

//代码承接上一部分
console.log( oP.childNodes )/*
    NodeList(9) [text, p, text, p, text, p, text, p.four, text] 
    length: 9
    0: text  点开这个会发现是1
    1: p
    2: text 空
    3: p
    4: text 空
    5: p
    6: text 空
    7: p.four
    8: text 空
*/

上边的例子中,第一个text是1,然后我们发现每个p标签之间都多了一个text(文本节点),把text(文本节点)点开发现是空的什么都没有,这个空text来源于p标签之间的换行。

<div class="box">1<p>2</p><p>3</p><p>4</p><p class="four">5</p></div>

如果我们这样写的话 那些空就会消失

接下来我们看 如何精确的获取子元素
Element.children 某个元素的所有子元素列表

console.log( oP.children )//HTMLCollection(4) [p, p, p, p.four]

这样就可以精确的获取子元素啦

  • Element.firstChild元素的第一个子节点(注意哈,这里是节点):
console.log( oP.firstChild )//"1"
  • Element.firstElementChild元素的第一个子元素(注意哈,这里是元素):
console.log( oP.firstElementChild )//<p>2</p>
  • Element.lastChild元素的第一个子节点(注意哈,这里是节点):
console.log( oP.lastChild )//text 点开是个空的,因为最后一个p标签和div的结束标签之间有换行
  • Element.lastElementChild元素的第一个子元素:
console.log(oP.lastElementChild)//<p class="four">5</p>
  • Element.removeChild(node)删除子节点(注意是子节点,不是元素),会把被删除的节点返回出来,因此我们可以用变量接受也可以直接打印:
//除了上边这种方法以外,我们还可以:
console.log( oP.removeChild(oP.childNodes[0]) )//"1",页面中的1也被删除了

​ 假如我想删除一个元素怎么办:

//依旧是先获取再删除,加入说我们现在想删除<p class="four">5</p>
var node = document.querySelector('.box > .four')
console.log( oP.removeChild(node) )//<p class="four">5</p>,删除了这个p标签,同时把他返回给了我们

​ 上边讲的方法对我们的6个选择器都有效。

​ 那么上边主要是对子元素进行的一些操作,除此之外我们还可以获取到父元素。

  • Element.parentNode:获取父节点:
var four = document.querySelector('four')
console.log( four.parentNode )//可以获取到four的父元素及父元素里的所有内容提供,因为父节点只有一个所以返回给我们的不是列表,而直接是这个元素
  • Element.previousSibling元素的上一个节点(节点!!),previous上一个,sibling兄弟:
<body>
    <div>1</div>
    <div class="box">2</div>
    <div>3</div>
    <div>4</div>
</body>
<script>
    var box = document.querySelector('.box')
    console.log( box.previousSibling )//text 点开以后是一个空字符串,这个空字符串来源于元素间的换行
</script>
  • Element.previousElementSibling元素的上一个兄弟元素,previous上一个,sibling兄弟:
console.log( box.previousElementSibling )//<div>1</div>

​ 假设这个元素已经是第一个了,那么:

var first = document.querySelector('div')
console.log( first )//<div>1</div>
console.log( first.previousElementSibling )//null
  • Element.nextSibling获取元素的下一个节点(节点!!),next下一个,sibling兄弟:
console.log( box.nextSibling )//#text 点开以后是一个空字符串,这个空字符串来源于元素间的换行
  • Element.nextElementSibling获取元素的下一个兄弟元素:
console.log( box.nextElementSibling )//<div>3</div>
  • Element.hasChildNodes()父元素是否有子节点,有返回true,没有返回false,传参无效:
<body>
    <div class="one"></div>
    <div class="two">
    </div>
    <div class="three">1</div>
    <div class="four">
        <p></p>
    </div>
</body>
<script>
    var one = document.querySelector('.one')
    console.log( one.hasChildNodes() )//false
    var two = document.querySelector('.two')
    console.log( two.hasChildNodes() )//true,换行是空白节点
    var three = document.querySelector('.three')
    console.log( three.hasChildNodes() )//true ,1是three下的节点
    var four = document.querySelector('.three')
    console.log( four.hasChildNodes() )//true
</script>
  • Element.append()添加子节点(可以是文本节也可以是元素),append追加:
<body>
    <div class="one">hello</div>
    <div class="two"></div>
</body>
<script>
    var one = document.querySelector('.one'),
        two = document.querySelector('.two')
    console.log( one )//<div class="one">hello</div>
    console.log( two )//<div class="tow"></div>
    two.append(one)//把class为one的div添加到class为two的div中,也就是说给.two添加一个子元素,这个子元素添加在最后
    console.log( one )//<div class="one">hello</div> one并没有消失,好好的存在页面中
    console.log( two )/*
        <div class="two">
            <div class="one">hello</div>
        </div>
        two中多了一个子元素,这个子元素是one
    */
    //既然是节点,那么我添加一个字符串试试
    two.append('someone')//报错,因为'someone'是一个字符串,不是一个文本节点,那么如何添加一个文本节点呢?请继续往下看
</script>
  • document.createElement()创建一个元素,create创造:
<body>
    <div class="box"></div>
</body>
<script>
    var box = document.querySelector('.box')//<div class="box"></div>
    var oP = document.createElement('p')//创建了一个p标签
    oP.innerText = 'helloworld'//设置p标签里的文本
    box.append(oP)//追加一个子元素
    console.log(box)//<div class="box"><p>helloworld</p></div>,div中多了一个子元素p标签,在页面中也能看到
    //想生成什么标签就生成什么标签
</script>
  • document.createTextNode()创造文本节点:
<body>
    <div class="hello">hello</div>
</body>
<script>
   var hello = document.querySelector('.hello')
   hello.append('world')//报错
   var world = document.createTextNode('world')
   hello.append(world)//不报错,div标签里多了一个文本节点world,现在div里的内容是helloworld
</script>

​ 上边的操作中我们可以创造一个元素,或者创造一个文本节点,然后添加到某个元素里,但是我们的网页第一次在加载时是这样的:js不算,把页面中要显示的内容都读完以后,文档就关闭了,然后我们用js去改变html的时候,文档就会重新打开,所以我们要尽可能一次性的把js创造的元素一起添加进某个地方。因此我们需要:

  • document.createDocumentFragment()创建文档碎片Fragment(碎片):
<body>
    <div class="hello">hello</div>
</body>
<script>
    //现在我们要动态生成一个img标签,一个p标签,append(追加)到hello里
    var hello = document.querySelector('hello'),
        fragment = document.createDocumentFragment()
    var img = document.createElement('img')//创建一个img标签
    img.setAttribute = ('src', 'https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4254164563,3923686114&fm=26&gp=0.jpg')//设置src属性
    var p = document.createElement('p')//创建一个img标签
    p.innerText = '吴彦祖'
    fragment.append( img, p )
    hello.append( fragment )//此时,hello这个元素多了两个子元素p和img,而且在页面中也显示了出来
</script>

​ 在文档中写入:

document.write(''),传一个字符串作为参数,如果不是字符串则会被转化为字符串。如果字符串里包含了标签,会被转化。会在body标签的最后写入。

<body>
    <p>1</p>
    <p>2</p>
</body>
<script>
    //性能贼垃圾,最好不要用
    document.write('<p>')
    document.write('123')
    document.write('456')
    document.write('</p>')
    document.write('<span>789</span>')
</script>

​ 最后的显示结果为:

<body>
    <p>1</p>
    <p>2</p>
    <script>
        //性能贼垃圾,最好不要用
        document.write('<p>')
        document.write('123')
        document.write('456')
        document.write('</p>')
        document.write('<span>789</span>')
    </script>
    <p>123456</p>
    <span>789</span>
</body>

​ 上边的都是和html有关的知识,接下来我们看看css:

我们无法修改在style标签或者css文件里写入的css,我们添加的css属性最后都会以行内样式显示出来,这是一个巧妙的设计,因为行内样式不存在优先级问题。

  • window.getCompotedStyle(Element)返回元素计算后的样式(也就是最终在页面中显示的样式),这是一个只读属性,也就意味着我们无法去改变里边的值,只能拿到。
<style>
    .hello{
        width: 100px;
        height: 100px;
        background-color: orange;
        margin: 50px auto;
    }
</style>
<body>
    <div class="hello"></div>
</body>
<script>
    var hello = document.querySelector('.hello')
    console.log(hello)//<div class="hello"></div>
    console.log(window.getComputedStyle(hello))//看到一个很大很大的对象
    //如果我想获取元素的宽度属性,直接加.width获得
    console.log( window.getComputedStyle(hello).width )//'100px'
    //或者我可以直接声明一个变量,保存下来
    var width = window.getComputedStyle(hello).width
    console.log( width )//'100px'
</script>
  • 我们可以通过Element.style.property,Element某个具体的元素,style样式,property属性名来给元素设置css样式,不过最后css样式会显示在标签的style属性里。
hello.style.width = '300px'//此时我们看到元素的宽度变为300px,并且可以在控制台里看到样式被写在了元素的style标签里。

​ 如果是已横岗链接的属性,则要改成驼峰写法:

background-color css写法

backgroundColor js写法

hello.style.backgroundColor = 'purple'//颜色变成了紫色
hello.style.backgroungImage = 'url()'//设置背景图片,注意!()不用添加引号

​ 所有的属性都可以通过这种形式设定,但是有一个属性比较特别,不能直接设置:

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