一. DOM
1.DOM核心
2.html-DOM
3.CSS-DOM
二. jQuery的DOM操作
1.查找节点
(1)元素节点
1
2
|
alert($( 'ul li:eq(1)' ).text);
//获取ul中第2个li内文档内容 |
(2)属性节点:使用attr()方法
1
2
|
alert($( 'p' ).attr( 'title' ));
//获取p元素的title值(如果有的话) |
2.创建节点
(1)元素节点
创建节点可以直接使用jQuery的工厂函数
$('HTML代码');
添加节点使用
jq父亲对象.append(jq子对象)
【例3.1】创建两个li元素并添加到节点上
1
2
3
4
5
6
|
< ul id = "list" >
< h4 >你喜欢的水果是</ h4 >
< li >苹果</ li >
< li >橘子</ li >
< li >菠萝</ li >
</ ul >
|
jq
1
2
3
4
5
6
7
8
|
$(document).ready( function (){
var $oLi1=$( '<li>雪梨</li>' );
var $oLi2=$( '<li>柿子</li>' );
//以上就直接创建了两个对象
$( '#list' ).append($oLi1);
$( '#list' ).append($oLi2);
//添加到节点,也可以使用链式写法
}) |
(2)创建文本节点
直接写进去就行
$('HTML代码');
(3)创建属性节点
也是直接把属性(比如title写入到html中)
1
|
$(" <li tilte=' apple '>苹果</li>" )
|
3. 插入节点
方法 | 释义 | 示例 | 备注 |
append() | 在匹配元素的内部追加内容,在父元素内部最后面 | jq父对象.append(jq子对象) | 类似js里的appendChild()方法 |
appendTo() | 颠倒了常规的append方法,在父元素内部最后面 | jq子对象.appendTo(jq父对象) | |
preppend() | 向每个匹配元素内部前置内容,在父元素内部最前 | jq父对象.preppend(jq子对象) | |
preppendTo() | 颠倒的preppend方法 | jq子对象.preppendTo(jq父对象) | |
after() | 在每个匹配目标元素之后加入内容 | jq目标元素.after(jq操作对象) | |
insertAfter() | 颠倒了after方法 | jq操作对象.insertAfter(jq目标对象) | |
before | 在每个匹配目标元素之前加入内容 | jq目标元素.before(jq操作对象) | |
insertBefore() | 颠倒的before方法 | jq操作对象insertBefore(jq目标对象) |
DOM的节点是可以用上述方法来移动的,如果操作的是一个已有所属的dom元素,那么它将从一个所属元素的父级移出。按照方法的规则重新排位。
4.删除节点
(1)remove()
$xxx.remove()——删除xxx节点remove里面可以跟选择器
【例3.2】筛选搜索结果
1
2
3
4
5
6
7
|
< input id = "btn1" type = "button" value = "搜索" />
< ul id = "list" >
< li >苹果</ li >
< li >橘子</ li >
< li title = "菠萝" >菠萝</ li >
</ ul >
|
js
1
2
3
4
5
6
|
$(document).ready( function (){
$( '#btn1' ).click( function (){
$( 'ul li' ).remove( "li[title!=菠萝]" )
})
}) |
(2)detach()方法
和remove类似,但万一以后重新创建,相应绑定的方法和操作都会保留
(3)empty
清空元素里的内容,但不删除节点
5.复制节点——clone()方法
被复制的节点无任何行为,如果要具有同样的功能可以调用clone方法的参数true
1
|
$( this ).clone( true ).appendTo( 'body' );
|
6. 替换节点
通过重新给节点赋值的方法,似乎不能生效
(1)replaceWith()
1
|
|
以上案例把div下,p内的后代换成了新定义的html语句
(2)replaceAll()
1
|
$( '<h1>你不喜欢的水果是?</h1>' ).replaceAll( 'p' )
|
所有的p都会被换成新的html语句。
注意:替换后所有绑定的事件全部消失!
7. 包裹节点
把某个节点用一个标记包裹起来——wrap()
1
|
$( '被标记对象的标签' ).wrap( '完整标记元素(包括闭合)' )
|
所有被标记对象的标签是单独被一个标记元素所包裹——局限性还是有点大。
(1)wrapAll()方法
所有被标记对象的标签是全部被一个标记元素所包裹。
(2)wrapInner
将每个匹配元素的子内容包括文本节点用设定的标记包裹
以上两个方法格式和wrap方法相同
8.属性操作
用attr获取和设置属性,removeAttr()来删除属性
(1)attr()方法
给所有p元素设置标题
1
|
$( 'p' ).attr( 'title', '标题' );
|
一次设置多个属性:在每个属性对中用逗号隔开,属性对内改用冒号分隔。
1
|
$( '选择器' ).attr( '属性1' : '值1' , '属性2' : '值2' ....)
|
(2)removeAttr()方法
1
|
$( '选择器' ).removeAttr( '属性1' )
|
9. 样式操作
(1)获取设置样式
比如,我要把所有p元素的class设置为“para”
1
|
$( 'p' ).attr( 'class' , 'para' )
|
这里沿用的是attr方法。注意,这里的设置是覆盖全部class的,修改后只有唯一的clas——para。这对于布局来说是很不友好的。所以不常用。
(2)追加class样式——addClass()
1
|
$( 'p' ).addClass( 'para' )
|
p 标记原有的class会被保留。当两个class样式冲突时,后面覆盖前面
(3)移除样式——removClass()
1
|
$( 'p' ).removeClass( 'para class1' )
|
上面例子中,p元素的两个className(para class1)都被删掉了。不带参数时,删除所有className。
(4)切换样式——toggle()方法——1.8+版本已废弃
貌似挺好用的方法——但是toggleClass能运行在1.11+版本中
1
2
|
< input id = "btn1" type = "button" value = "切换" />
< div id = "div1" class = "class1" ></ div >
|
存在两个class样式
1
2
3
4
5
6
7
8
9
10
11
12
|
#div1{ width: 200px;height: 200px;
} .class1{ background: yellow;
} .class2{ background: green;
} |
点击按钮来回切换颜色
1
2
3
4
5
|
$(document).ready( function (){
$( '#btn1' ).click( function (){
$( '#div1' ).toggleClass( 'class2' )
})
}) |
(5)判断是否含有某种样式——返回的是一个布尔值
hasClass方法
1
|
$( 'p' ).hasClass( 'para' )
|
作为判断,jquery实际是调用了is函数
1
|
$( 'p' ).is( '.para' );
|
10. 设置获取HTML、文本的值
(1)html()方法
类似innerHTML方法
1
2
|
alert($( 'p' ).html());
//打印p标记内的html内容 |
在html()参数内设置html文本,可以改变p的内容
(2)text()方法
前面章节已经用过——类似innerText,不包含html结构内容。可以设置文本参数改变里面的文本内容
(3)val()方法
相当于value。
【例3.3】登录界面,鼠标焦点移入时,value值消失,移除焦点时,value回复。
提示:jq选择器有$(':focus')方法——还有focus()事件——失去焦点:blur()
1
2
3
|
< input type = "text" id = "address" value = "请输入邮箱地址" /> < br />< br />
< input type = "text" id = "password" value = "请输入邮箱密码" /> < br />< br />
< input type = "button" value = "登录" />
|
js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
$(document).ready( function (){
$( '#address' ).focus( function (){
if ($( this ).val()== '请输入邮箱地址' ){
$( this ).val( '' );
}
})
$( '#address' ).blur( function (){
if ($( this ).val()== '' ){
$( this ).val( '请输入邮箱地址' );
}
})
$( '#password' ).focus( function (){
if ($( this ).val()== '请输入邮箱密码' ){
$( this ).val( '' );
}
})
$( '#password' ).blur( function (){
if ($( this ).val()== '' ){
$( this ).val( '请输入邮箱密码' );
}
})
}) |
11. 遍历节点
每个遍历节点都可以加参数进行筛选。
(1)获取匹配元素的子元素集合——children()方法
取得一个包含匹配的元素集合中每一个元素的所有子元素的元素集合。
可以通过可选的表达式来过滤所匹配的子元素。注意:parents()将查找所有祖辈元素,而children()只考虑子元素而不考虑所有后代元素。
可以用于遍历
$aObj[i]
(2)next()方法
1
2
|
$( 'p' ).next()
//获取紧邻p元素的下一个同辈元素 |
(3)prev()方法
获取匹配元素紧邻的前一个同辈元素
(4)sibling()方法
获取匹配元素后紧邻的所有同辈元素
(5)closest
获取最近的匹配元素
1
|
$( '.para' ).closest( 'li' )
|
如上,class为para的标记靠的最近的那个li元素——按辈分算。
【注意区别parent,parents和closest】
12. CSS-DOM操作
利用jq提取外部样式的属性,这是最大的优势。因此隆重推出css()方法
无论外部样式是怎样关联的,css()都可以获取!
css()可以直接给元素设置样式!
和attr方法一样,css()可以直接一次性改变多个属性!
1
|
$( 'p' ).css( 'background' : 'white' , 'color' :red,
|
注意
a. font-size之类的属性可以不加引号——但是必须写成fontSize。
b. opacity可以直接用,jq已经处理好了兼容性。
c. css()也可以获取高度,但是那只是样式所说的静态高度。获取计算后的高度是用xxx.height(),相对应的是width()方法。
布局常用方法:
(1)offset()
返回的是top和left两个属性值。
1
2
|
$( 'p' ).offset().left
//获取p元素的offsetLeft。 |
left,top仅仅是获取。不带参数
(2)position方法
返回的是相对于做了定位的先代元素的偏移——假如操作对象的定位为绝对。
1
2
|
$( 'p' ).position().left
//获取p元素的left值 |
(3)scrollTop()和scrollLeft()方法
滚动条距离顶端和距离左侧的长度
1
2
|
$( 'p' ).scrollTop(300).scrollLeft(300);
//p元素始终在滚动条滚动到指定位置时出现。 |
【久违的大案例】某网站超链接和图片显示效果
【1】超链接提示效果
现代浏览器中,可以通过title实现超链接悬停提示的效果。如
1
|
< a href = "javascript:;" title = "我是提示" >提示demo</ a >
|
这种提示效果相当慢。试着写出一个js模拟这种效果
(1)鼠标滑入超链接:创建一个div,内容为title值,追加到文档中,设置位置跟随鼠标
(2)移出超链接,移除div。
难点
(1)完全跟随鼠标指针被遮挡可能触发onmouseout,要设置一定的偏离
(2)消除浏览器自带的显示效果(已证明return false不行)。
布局
1
2
3
4
|
< p >< a href = "#" class = "tooltip" title = "这是我的超链接提示1." >提示1.</ a ></ p >
< p >< a href = "#" class = "tooltip" title = "这是我的超链接提示2." >提示2.</ a ></ p >
< p >< a href = "#" title = "这是自带提示1." >自带提示1.</ a ></ p >
< p >< a href = "#" title = "这是自带提示2." >自带提示2.</ a ></ p >
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
body{ margin : 0 ;
padding : 40px ;
background : #fff ;
font : 80% Arial , Helvetica , sans-serif ;
color : #555 ;
line-height : 180% ;
position : relative ;
} p{ clear : both ;
margin : 0 ;
padding :. 5em 0 ;
} .tips{ position : absolute ;
border : 1px solid #333 ;
background : #f5f5f5 ;
padding : 1px ;
color : #333 ;
width : 100px ;
} |
我们把要产生div的样式写到一个tips里。
懂js是基础,所以先考虑原生js的实现方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
window.onload= function (){
var aTool=document.getElementsByClassName( 'tooltip' );
var TipsTxt= null ;
var tips= null ;
var i=0;
for (i=0;i<aTool.length;i++){
aTool[i].onmouseover= function (ev){
var oEvent=ev||event;
tips=document.createElement( 'div' );
TipsTxt=document.createTextNode( this .title);
tips.appendChild(TipsTxt);
tips.className= 'tips' ;
tips.style.left=oEvent.clientX+ 'px' ;
tips.style.top=oEvent.clientY+20+ 'px' ;
this .parentNode.appendChild(tips); //加到兄弟节点上去,防止样式混乱及冒泡!
this .onmousemove= function (ev){
var oEvent=ev||event;
tips.style.left=oEvent.clientX+ 'px' ;
tips.style.top=oEvent.clientY+20+ 'px' ;
} //设置跟随
this .title= '' ; //阻止悬停时产生title自带效果,return false无效
}
aTool[i].onmouseout= function (){
this .title=tips.innerText; //恢复title,下次再调用
this .parentNode.removeChild(tips);
}
}
} |
这里面用了多个事件。jq中鼠标位置为e.pageX和e.pageY(需要参数e)。js的移入移出移动去掉on就是jq里的同类事件。也可以使用hover:
hover(function()({移入},function{移出})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
$(document).ready( function (e){
var $aTool=$( '.tooltip' );
$aTool.mouseover( function (){
//生成+插入元素
var $tips=$( '<div>' +$( this ).attr( 'title' )+ '</div>' );
$tips.addClass( 'tips' )
.appendTo($( this ).parent());
//鼠标指针焦点是用参数e来表示
$tips.position().left=e.pageX+ 'px' ;
$tips.position().top=e.pageY+20+ 'px' ;
$( this ).mousemove( function (e){
$tips.css(
{ 'left' :e.pageX+ 'px' ,
'top' :e.pageY+20+ 'px' }
)
}) //跟随。不写里面也可以。
$( this ).attr( 'title' , '' ); //阻止弹出信息
})
$aTool.mouseout( function (){
var $tips=$( '.tips' ); //因为tips函数不公开,所以还要再声明一遍。
$( this ).attr( 'title' ,$tips.text());
$tips.remove();
})
}) |
让jq发挥更强大的优势:
这段代码算是完善了,但是显示消失太唐突了。jq可以让它看起来很美。想要使用这种效果,需要在css把.tips设置为display:none。同时鼠标移出时为了显示动画,不能删除节点——可以在鼠标移入时声明,不管有没有都删除掉$('.tips')。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
$(document).ready( function (e){
var $aTool=$( '.tooltip' );
$aTool.mouseover( function (){
$( '.tips' ).remove();
//生成+插入元素
var $tips=$( '<div>' +$( this ).attr( 'title' )+ '</div>' );
$tips.addClass( 'tips' )
.appendTo($( this ).parent())
.fadeIn();
//鼠标指针焦点是用参数e来表示
$tips.position().left=e.pageX+ 'px' ;
$tips.position().top=e.pageY+20+ 'px' ;
$( this ).mousemove( function (e){
$tips.css(
{ 'left' :e.pageX+ 'px' ,
'top' :e.pageY+20+ 'px' }
)
}) //跟随。不写里面也可以。
$( this ).attr( 'title' , '' ); //阻止弹出信息
})
$aTool.mouseout( function (){
var $tips=$( '.tips' ); //因为tips函数不公开,所以还要再声明一遍。
$( this ).attr( 'title' ,$tips.text());
$tips.fadeOut();
})
}) |
同样的,输了fadeIn和fadeOut,还有slideUp,slideDown等方法,也可以从设计角度出发,干脆不要移出时的动画,直接删除节点——选最合适的。
【2】图片提示效果
根据上一个案例的思想,可以很快做出一个鼠标悬停显示放大效果,进一步就可以做细节显示。比如介绍文字等等。
先布局
根据框架来写:
li的title做说明文字用
1
2
3
4
5
6
|
< ul >
< li title = "123" >< img class = "tooltip" src = "images/apple_1_bigger.jpg" /></ li >
< li title = "1234" >< img class = "tooltip" src = "images/apple_2_bigger.jpg" /></ li >
< li title = "12345" >< img class = "tooltip" src = "images/apple_3_bigger.jpg" /></ li >
< li title = "123456" >< img class = "tooltip" src = "images/apple_4_bigger.jpg" /></ li >
</ ul >
|
在样式方面,将创建两个嵌套的div
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
ul{ margin: 100px auto;
width: 500px;
} ul li{ list-style: none;
float: left;margin-left: 20px;
border:1px solid #ccc;
} img{ width: 100px;height: 75px;
} /*大pic样式*/ .bigpic{ position: absolute;
width: 400px;height: 300px;
border: 1px solid #ccc;
display: none;
background-size: 400px 300px;
background-repeat: no-repeat;
} /*附加说明文字的样式,嵌套在.bigpic里面*/ .tips{ background:rgba(0,0,0,0.7);
color: #f5f5f5;
height: 20px;width: 100%;
position: absolute;
bottom: 0;
padding: 10px;
} |
jq分析,根据之前的框架一个个写。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
$(document).ready( function (e){
var $aImg=$( '.tooltip' );
$aImg.mouseover( function (e){
var $bigpic=$( '<div class="bigpic"><div class="tips">' +$( this ).parent().attr( 'title' )+ '</div></div>' );
//直接用$(html)方法创建两个定义好的嵌套div,
//其中小div嵌套文本为图片节点的父元素li的对应title值。
$bigpic.css(
{ 'left' :e.pageX+ 'px' ,
'top' :e.pageY+20+ 'px' ,
'background-image' : 'url(' +$( this ).attr( 'src' )+ ')' }
);
//设置样式,通过背景图来显示大图片,背景图来源为该图片节点的src值
$bigpic.appendTo($( this ).parent()).fadeIn();
//准备完毕后加到里面去!展现方式为fadein
$( this ).mousemove( function (e){
$( '.bigpic' ).css(
{ 'left' :e.pageX+ 'px' ,
'top' :e.pageY+20+ 'px' }
);
}); //鼠标运动跟随
$( this ).parent().attr( 'title' , '' );
//清空li的title值,防止显示。
})
.mouseout( function (){
$( this ).parent().attr( 'title' ,$( '.tips' ).text());
//把小div里的值添加到图片节点的父级也就是li的title里面
//支持下一次调用。
$( '.bigpic' ).remove(); //移除。
}) //鼠标移出事件
}) |
显示效果如下