首先我们先不讨论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!生效