转码日记——Javascript笔记(13)修改css样式、事件冒泡和委派

2023-11-14

使用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;

            }

        };
    };

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

转码日记——Javascript笔记(13)修改css样式、事件冒泡和委派 的相关文章

随机推荐