使用JS控制css样式
(1)修改css样式 语法:元素.style.样式名称= 样式值 (样式值必须是一个字符串)
//修改box1的样式
box1.style.width="300px";
如果css中还有“-”,如background-color,这种名称在js中是不合法的,需要修改为驼峰命名法
box1.style.backgroundColor="grey";
box1.style.borderTopWidth="thick";
通过style属性设置的都是内联样式,内联样式有较高的优先级,通过JS修改的样式往往会立即显示,因为它覆盖了原来选择器的样式,但是样式中加上!important之后优先级最高,JS无法修改。
(2)读取元素的样式 用法:元素.style.样式名称 — 通过style属性设置和读取的都是内联样式,无法读取样式表中的样式。
alert(box1.style.height);
可以使用currentStyle属性获取当前css样式表中正在显示的样式,但是该属性只有IE浏览器支持
用法:元素.currentStyle.样式名称;如果没有设置要获取的样式,则显示样式的默认值,如backgroundColor的默认值就是transparent
alert(box1.currentStyle.width);
在其他浏览器中,可以使用getComputedStyle( 1. 要获取样式的元素 2.传递一个伪元素,一般都是Null) 来获取元素的样式,且该方法是window的方法,可以直接使用;该方法会返回一个对象,对象中封装了当前元素对应的样式。该方法不支持IE8及以下的浏览器。
var obj = getComputedStyle(box1, null); //将box1的样式封装到对象中
alert(obj.width); //显示obj中的width样式
//或者
alert(getComputedStyle(box1, null).width);
为了考虑浏览器的兼容性问题,可以自己定义一个函数来获取指定元素的css样式
//参数:obj是要获取样式的元素,name是要获取的样式名
function getStyle(obj, name){
//正常浏览器查看元素样式的方法
//一定是写window.getComputedStyle,加上window就是window的属性,不写的话就变成寻找变量了
//寻找变量先在函数内部寻找,然后去全局作用域寻找,都没有找到就会报错
if(window.getComputedStyle){
return getComputedStyle(obj, null)[name];
}else{
//IE8的方法
return obj.getCurrentStyle[name];
}
};
//name要加[],不然就写死了是属性name
currentStyle和getComputedStyle( )是只读的,也就是只能读取当前样式,但是不可以修改,如果要修改必须通过style属性。
其他样式相关的属性(只读,不可修改)
(1)clientWidth/clientHeight — 这两个属性可以获取元素的可见高度和可见宽度,并且获取到的只是数字,不带有单位,因此可以直接进行计算;宽度和高度包括内容区和内边距,包括padding但不包括border
//box1是100*100的盒子,padding值为10px,border2px
getComputedStyle(box1, null); //只会返回100px,带单位并且是实际长度
box1.clientWidth; //返回被撑开的盒子的宽度且不带有单位
(2)offsetWidth/offsetHeight — 获取元素的整个宽度和高度,比clientWidth多一个边框
(3)offsetParent — 获取当前元素的定位父元素,也就是离当前元素最近的开了定位的祖先元素;如果所有的祖先元素都没有开启定位,则返回body
(4)offsetLeft/ offsetTop — 获取相对于 offsetParent 元素左侧/上面的位置(以像素为单位)
(5)scrollHeight/scrollWidth — 如果子元素溢出父盒子,子元素可能被设置为hidden或者auto(出现滚动条),如果使用clientHeight则获取到的是可见的高度,scrollHeight则是子元素完整的高度
(6)scrollLeft/scrollTop — 获取水平和垂直滚动条滚动的距离
*如果 scollHeight - scrollTop == clientHeight,则说明垂直滚动条滚到最底下了。
事件对象
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实际参数传入响应函数,在事件对象中封装了当前事件相关的一切信息,包括鼠标的坐标,键盘上的哪个键被按下,鼠标滚轮滚动的方向等。
window.onload = function () {
//鼠标在绿色盒子中动,下面会显示出鼠标的坐标
//获取两个盒子
var areaDiv = document.getElementById("areaDiv");
var showMsg = document.getElementById("showMsg");
//给绿色盒子绑定鼠标移动的事件
areaDiv.onmousemove = function (event) {
//event作为形参
var x = event.clientX;
var y = event.clientY
showMsg.innerHTML = "x=" + x + ",y=" + y;
};
};
事件冒泡(bubble)
事件冒泡就是事件的向上传导,当后代元素的事件被触发时,其祖先元素的相同事件也会被触发。注意一定是相同事件,如div和div里面的span绑定的事件都是onclick,这样才会被触发。
大部分的冒泡在开发中十分有用,如果不希望冒泡,可以通过事件对象cancelBubble来取消冒泡。
window.onload = function () {
//获得box1
var box1 = document.getElementById("box1");
//给盒子绑定响应函数
box1.onclick = function () {
alert("我是大盒子");
};
//获得盒子
var sp2 = document.getElementById("sp2");
sp2.onclick = function (event) {
event = event || window.event;
event.cancelBubble = true;
alert("我是span");
};
};
事件的委派
将事件统一绑定给元素共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。事件委派就是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能。
//事件委派
//给每一个超链接都绑定上单击响应函数,包括通过点击按钮添加的新链接
//获取ul
var u1 = document.getElementById("u1");
//获取按钮
var btn = document.getElementById("btn");
btn.onclick = function () {
var li = document.createElement("li");
//注意不要引号嵌套,可以是双引号套单引号
li.innerHTML = "<a href=''class='link'>新的超链接</a>";
//将nL添加到ul里面
u1.appendChild(li);
};
//给所有的超链接都绑定上响应函数
//注意这里不要给a绑定,而是直接给ul绑定,这样新添加的a也可以获得响应函数
u1.onclick = function (event) {
//但是这样点击的范围就是ul的范围,会变得很大
//所以需要加入判断,判断点击的是否是链接,还是ul的其他部分
//判断点击的是否是超链接
event = event || window.event;
//event中的target是事件触发的对象
if (event.target.className == "link") {
alert("绑定成功啦~");
}
};
事件的绑定
使用元素.事件=函数的绑定方式,只能同时为一个元素的一个事件绑定一个响应函数,比如想要绑定两个onclick事件,后面的将会覆盖掉前面的事件。
通过使用addEventListener( )方法也可以绑定响应函数,参数:1. 事件的字符串,不要on,eg.onclick只写click 2. 回调函数,当事件触发时,该函数会被调用 3. 是否在捕获阶段触发事件,需要一个布尔值,一般都传false 该方法不支持IE8及以下的浏览器
//点击按钮弹出窗口
btn.addEventListener("click", function(){
alert(1);
}, false);
btn.addEventListener("click", function(){
alert(2);
}, false);
//同样的click事件可以绑定两个响应函数
IE8中可以使用attachEvent( )来绑定事件,参数:1. 事件的字符串,要on 2.回调函数 ,该方法也可以绑定多个响应函数,但是和addEventListener( )方法的执行顺序是相反的,是先alert 2 再alert1
btn.attachEvent("onclick",function(){
alert(1);
});
定义一个bind函数来同时兼容IE8和其他浏览器
window.onload = function () {
//定义一个函数
//参数:obj是用来绑定函数的对象;evenStr是事件的字符串;callback回调函数
function bind(obj, evenStr, callback) {
//判断大部分浏览器是否兼容
if (obj.addEventListener) {
obj.addEventListener(evenStr, callback, false);
//这里this指的是obj自己,谁调用就是谁
} else {
//evenStr本身是没有on的,需要加上on
// obj.attachEvent("on" + evenStr, callback);
//但是这里的callback是window调用的,而不是我们调用的,所以为了和上面的指针this指的对象是一样的,需要修改this的指向,window调用时无法修改,先改变调用的方式
obj.attachEvent("on" + evenStr, function () {
//使用匿名函数调用,这时this指的就是匿名函数了
//在匿名函数中修改this的指向
//this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。
callback.call(obj);
});
}
};
//获取按钮
var btn01 = document.getElementById("btn01");
//调用bind函数
bind(btn01, "click", function () {
alert("你好");
});
};
事件的传播
1.捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行捕获,但是默认不会触发事件
2.目标阶段:事件捕获到目标元素,捕获结束,开始触发在目标元素上的事件
3.冒泡阶段:事件从目标元素向它的祖先元素传递,依次触发祖先元素
如果希望在捕获阶段就触发事件,可以将addEventListener( )里面的第三个参数设置为true。
练习:拖拽
//鼠标按下后后盒子跟着鼠标移动,再次点击后盒子落在鼠标移动到的位置
window.onload = function () {
//获取盒子
var box1 = document.getElementById("box1");
//鼠标按下后获得盒子
box1.onmousedown = function (event) {
//盒子跟着鼠标走
//鼠标点击盒子的任意位置都可以实现拖拽,鼠标的位置在按下去鼠标的时候就已经确定了
//需要计算鼠标相对盒子的位置
var ld = event.clientX - box1.offsetLeft;
var td = event.clientY - box1.offsetTop;
//注意这里的范围是document而不是box1 不然只会在box1里面活动的时候才有用
document.onmousemove = function (event) {
//考虑兼容性问题
event = event || window.event;
//获取鼠标的位置
var left = event.clientX - ld;
var top = event.clientY - td;
//盒子的位置等于鼠标的位置
box1.style.left = left + "px";
box1.style.top = top + "px";
};
};
//再次点击后取消onmousemove
//如果是两个div盒子,当box1和box2重合时,函数会失效,因为这个时候鼠标跑到了box2上,所以绑定函数还是要绑定整个document
document.onmouseup = function () {
document.onmousemove = null;
};
滚轮事件
//滚轮向下滚动时盒子变长,向上滚动时盒子变短
window.onload = function () {
var box1 = document.getElementById("box1");
box1.onwheel = function (event) {
//判断鼠标滚动的方向
//deltaX/deltaY可以判断滚动滚动的方向,只看正负值
if (event.deltaY < 0) {
//修改盒子的长度,使其等于滚轮滚动的长度
//向下滚box变长
box1.style.height = (box1.clientHeight + 10) + "px";
} else {
//向下滚box变短
box1.style.height = (box1.clientHeight - 10) + "px";
}
//如果body设置了高度,本身就会出现滚动条,这个时候再滚动,盒子不会变化
//这时浏览器的默认行为,需要取消
return false;
};
};
键盘事件 — 键盘事件一般都会绑定给一些可以获取到焦点的对象或document
onkeydown: 键盘被按下时触发,如果一直按着键盘不松开就会一直被触发;当连续触发时,第一次和第二次之间的间隔会稍微长一点,其他的会非常快,这样是为了防止误操作的发生。
//判断用户是否同时按下shify和y键
document.onkeydown=function(event){
if(event.keyCode == 89 && event.shiftKey){
console.log("shift和y被同时按下了");
}
};
如果是<input>标签,在文本框中输入内容属于onkeydown的默认行为,如果取消了默认行为,输入的内容不会出现在文本框中。
var input = document.getElementsByTagName("input")[0];
document.onkeydown = function () {
console.log("按键被按下了");
};
练习:文本框中不能输入数字
//不让用户输入数字
document.onkeydown = function (event) {
//s数字的keyCode一般是48-57
if (event.keyCode >= 48 && event.keyCode <= 57) {
return false; //取消默认行为
}
};
练习:使用上下左右键移动div盒子
window.onload = function () {
//获得box1
var box1 = document.getElementById("box1");
document.onkeydown = function (event) {
var speed = 10;
//使用变量的话后期方便修改
switch (event.keyCode) {
case 37:
box1.style.left = box1.offsetLeft - speed + "px";
break;
case 39:
box1.style.left = box1.offsetLeft + speed + "px";
break;
case 38:
box1.style.top = box1.offsetTop - speed + "px";
break;
case 40:
box1.style.top = box1.offsetTop + speed + "px";
break;
}
};
};