WEB前端第三十二课——js事件处理-文档、焦点

1.文档事件

  主要是指添加给整个文档的事件,文档事件中,绝大部分不需要用户触发调用,而是通过文档的不同状态进行自动执行

  主要事件:

    ① load / error,加载成功/失败事件

    ② DOMContentLoaded,当DOM加载完成时触发事件

    ③ beforeunload,页面(文档)发生卸载时触发事件

    ④ readystatechange,文档加载状态判断事件

    ⑤ resize,文档大小发生改变时的回调事件

2.load / error

  load事件在节点加载成功时自动触发

  error时间在节点加载失败时自动触发

  语法:元素/文档(node).onload / onerror = function(){ };

<body>
    <img src="Images/Model.jpg" alt="">
<script>
    var img=document.querySelector('img');
    img.onload=function () {
        console.log('图片加载成功!');
    }
    img.onerror=function () {
        console.log('图片加载Failed!');
    }
</script>

3.DOMContentLoaded

  与 load事件的区别是触发时机不一样,先触发DOMContentLoaded事件,后触发 load事件

  DOM文档加载的步骤:

    ① 解析HTML结构

    ② 加载外部脚本和样式表文件

    ③ 解析并执行脚本代码

    ④ DOM树构建完成  ——☛触发DOMContentLoaded事件执行

    ⑤ 加载图片等外部文件

    ⑥ 页面加载完成  ——☛触发load事件执行

  由此看出,样式文件的加载会阻塞脚本执行

  即,如果把一个内部脚本 <script>元素放在了一个 <link>后面,在页面没有完成解析时脚本不会触发执行,直至样式文件加载完成之后。

  注意,DOMContentLoaded事件只能使用DOM2方式绑定,不存在DOM0绑定方式!

4.beforeunload

  页面发生卸载时触发事件(页面刷新和关闭页面之前),通常情况下配合 event .returnValue使用

  一般情况下都是直接添加到body上面,如果没有在body上添加本事件,则需要在 window上添加

  语法示例:window .onbeforeunload=function(){

        event .returnValue='';

        return'信息已修改是否确认离开?'

       };

  注意,beforeunload事件中弹出的对话框一般情况下不允许用户修改,只能采用默认对话框,且在beforeunload关联的回调函数中也不支持alert弹出框

5.readystatechange

  当 document的 readyState改变时触发这个事件(仅第二阶段)

  document .readyState的三个属性值:

    loading,加载DOM中

    interactive,加载外部资源

    complete,加载完成

  而 readystatechange事件正是这个状态发生改变时调用的事件

  调用方式可以是 DOM0级事件,也可以是DOM2级事件

6.事件测试

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文档事件</title>
<style>
    img{ width: 300px; }
</style>
</head>
<body>
    <img src="Images/Model.jpg" alt="">
<script>
    var img=document.querySelector('img');
    img.onload=function () {
        console.log('图片加载成功!');
    }
    img.onerror=function () {
        console.log('图片加载Failed!');
    }
    console.log('页面加载状态:'+document.readyState);
    document.addEventListener('readystatechange',function () {
        console.log('页面加载状态变化:'+document.readyState);
    });
    document.addEventListener('DOMContentLoaded',function () {
        console.log('文档DOM树构建完成');
    });
    window.onload=function () {
        console.log('浏览器窗口加载完成!')
    }
</script>
</body>
</html>

  

7.resize

  浏览器窗口变化事件

<script>
    window.onresize=function(){
        console.log('width:'+document.documentElement.clientWidth);
        console.log('height:'+document.documentElement.clientHeight);
    }
</script>

  

  js中为了追求变化的敏感度,将 resize事件的响应时间设置为了0,也就是说每一次的文档大小改变都会立即调用本事件

  这就造成了 一次变化 却发生了 不止一次 的resize事件调用

  为了解决这个问题可以采用一种延迟的写法来实现。代码如下:

<script>
    var flag=true
    window.onresize=function(){
        var w=document.documentElement.clientWidth;
        var h=document.documentElement.clientHeight;
        if (flag==true){
            console.log('(w,h):('+w+','+h+')');

            flag=false;
            setTimeout(function () {
                flag=true;
            },1000);
        }
    }
</script>

  

8.焦点事件

  在js中当前正在和用户发生交互的节点称为焦点,包括获取焦点(focus)和失去焦点(blur)两种情况

  获取焦点和失去焦点都既可以使用DOM0绑定也可以使用DOM2绑定,自动触发事件执行

  语法:元素节点 .onfocus / onblur = function(){ };

  注意,这两种事件均不支持事件冒泡,只有当前节点触发调用

     如果需要传递触发,则需要使用DOM2绑定事件中的捕获方式

  事件本身的书写格式:元素节点 .focus()  / blur(); ,(方法)代表获取焦点 / 失去焦点

<body>
    Name:<input type="text" class="name">
    Code:<input type="text" class="code">
<script>
    var code=document.querySelector('.code');
    code.onfocus=function(){
        code.setAttribute('placeholder','请设置6位数密码!');
    };
    code.onblur=function(){
        if (code.length!==6){
            code.setAttribute('style','border:1px solid red');
            alert('密码格式不符合要求,请重新设置。');  //先于setAttrbute执行
        };
    };
</script>
</body>

9.用户注册界面

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册界面</title>
    <style>
        input{
            display: inline-block;
            outline: none;
            height: 20px;
            line-height: 30px;
        }
        .boxName{
            display: inline-block;
            padding: 0;
            width: 80px;
        }
        .submit{
            display: inline-block;
            margin-left: 60px;
        }
        .borderGreen{
            border: 2px solid darkgreen;
        }
        .fontGreen{
            color: darkgreen;
            font-weight: bold;
        }
        .borderRed{
            border: 2px solid red;
        }
        .fontRed{
            color: red;
        }
        .idtCodePic{
            width: 177px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            /*word-spacing: 20px;          对字符无效*/
            letter-spacing: 10px;
            background-image: url("Images/idtCodePic.jpg");
            margin-left: 85px;
            font-size: 30px;
        }
        .idtCodePic:hover{
            cursor: pointer;
        }
    </style>
</head>
<body>
    <p>
        <span class="boxName">用户名:</span>
        <input type="text" class="userName">
        <span class="nameTips"></span>
    </p>
    <p>
        <span class="boxName">手机号码:</span>
        <input type="text" class="phoneNumber"/>
        <span class="phoneTips"></span>
    </p>
    <p>
        <span class="boxName">登录密码:</span>
        <input type="text" class="loginCode">
        <span class="loginTips"></span>
    </p>
    <p>
        <span class="boxName">确认密码:</span>
        <input type="text" class="confirmCode"/>
        <span class="confirmTips"></span>
    </p>
    <span style="font-size: 12px;color: #b3d4fc;float: left;
    width: 25px;height: 50px;margin-left: 50px">点击图片切换</span>
    <div class="idtCodePic"></div>
    <p>
        <span class="boxName">验证码:</span>
        <input type="text" class="idtCode"/>
        <span class="idtTips"></span>
    </p>

    <button class="submit" disabled>提交注册</button>
<script>
    var userName=document.querySelector('.userName');  //name不能作为变量声明!
    var nameTips=document.querySelector('.nameTips');
    var phoneNumber=document.querySelector('.phoneNumber');
    var phoneTips=document.querySelector('.phoneTips');
    var loginCode=document.querySelector('.loginCode');
    var loginTips=document.querySelector('.loginTips');
    var confirmCode=document.querySelector('.confirmCode');
    var confirmTips=document.querySelector('.confirmTips');
    var idtCodePic=document.querySelector('.idtCodePic');
    var idtCode=document.querySelector('.idtCode');
    var idtTips=document.querySelector('.idtTips');
    var submit=document.querySelector('.submit');
//    用户名内容设置
    userName.onfocus=function(){
        userName.setAttribute('placeholder','不少于两位字符!');
    };
    userName.onblur=function(){
        if (userName.value.length>=3){
            nameTips.innerHTML='通过';
            nameTips.setAttribute('class','fontGreen');
            userName.setAttribute('class','borderGreen');
        }else{
            nameTips.innerHTML='格式不符合要求,请重新填写';
            nameTips.setAttribute('class','fontRed');
            userName.setAttribute('class','borderRed');
        }
        checkAllInfo();
    };
//    手机号码内容设置
    phoneNumber.onfocus=function(){
        phoneNumber.setAttribute('placeholder','请填写11位手机号码!');
    };
    phoneNumber.onblur=function(){
        if (phoneNumber.value.length==11&&phoneNumber.value[0]==1){
            phoneTips.innerHTML='通过';
            phoneTips.setAttribute('class','fontGreen');
            phoneNumber.setAttribute('class','borderGreen');
        }else{
            phoneTips.innerHTML='格式不符合要求,请重新填写';
            phoneTips.setAttribute('class','fontRed');
            phoneNumber.setAttribute('class','borderRed');
        }
        checkAllInfo();
    };
//    登录密码内容设置
    loginCode.onfocus=function(){
        loginCode.setAttribute('placeholder','请设置6~12位数字或字母!');
    };
    loginCode.onblur=function(){
        if (loginCode.value.length>=6&&loginCode.value.length<=12){
            loginCode.setAttribute('class','borderGreen');
            loginTips.innerHTML='通过';
            loginTips.setAttribute('class','fontGreen');
        }else{
            loginCode.setAttribute('class','borderRed');
            loginTips.innerHTML='密码格式不符合要求,请重新设置';
            loginTips.setAttribute('class','fontRed');
        }
        checkAllInfo();
    };
//    确认密码内容设置
    confirmCode.onfocus=function(){
        confirmCode.setAttribute('placeholder','请确认上述密码!');
    };
    confirmCode.onblur=function(){
        if (confirmCode.value==loginCode.value&&confirmCode.value!=''){
            confirmCode.setAttribute('class','borderGreen');
            confirmTips.innerHTML='通过';
            confirmTips.setAttribute('class','fontGreen');
        }else{
            confirmCode.setAttribute('class','borderRed');
            confirmTips.innerHTML='密码不符合要求,请重新确认';
            confirmTips.setAttribute('class','fontRed');
        }
        checkAllInfo();
    };
//    验证码图片内容设置
    function creatIdtCode() {
        var idtCodeSet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        var maxNum=idtCodeSet.length;
        var idtCodeVal='';
        for (var i=0;i<5;i++){
            var index=Math.floor(Math.random()*maxNum);
            var idtCodeTemp=idtCodeSet[index];
            idtCodeVal+=idtCodeTemp;
        }
        return idtCodeVal;
    }
    idtCodePic.innerHTML=creatIdtCode();
    idtCodePic.onclick=function(){
        var newIdtCode=creatIdtCode();
        console.log(newIdtCode);
        idtCodePic.innerHTML=newIdtCode;
    };
    idtCodePic.setAttribute('letter-spacing','20px');   //此处设置无效!!
//    验证码内容设置
    idtCode.onfocus=function(){
        idtCode.setAttribute('placeholder','请输入上述图片内验证码!');
    };
    idtCode.onblur=function(){
        if (idtCode.value==idtCodePic.innerHTML){
            idtCode.setAttribute('class','borderGreen');
            idtTips.innerHTML='通过';
            idtTips.setAttribute('class','fontGreen');
        }else{
            idtCode.setAttribute('class','borderRed');
            idtTips.innerHTML='验证码错误,请重新填写';
            idtTips.setAttribute('class','fontRed');
        }
        checkAllInfo();
    };
//    提交注册按钮设置
    function checkAllInfo(){
        if (nameTips.innerHTML=='通过'&&phoneTips.innerHTML=='通过'&&loginTips.innerHTML=='通过'
            &&confirmTips.innerHTML=='通过'&&idtTips.innerHTML=='通过'){
            submit.removeAttribute('disabled');
        }else {
            submit.setAttribute('disabled','disabled');
        }
    }
</script>
</body>
</html>

      

10.滚动事件

  scroll事件会在文档或元素发生滚动操作时触发

  ① 文档滚动事件

    scrollTop,表示滚动条上下滚动的距离

    scrollLeft,表示滚动条左右滚动的距离

    注意,scrollTop和 ScrollLeft 距离没有计量单位,实际上是文档滚动的距离

       两个属性不但可以读取,还可以赋值!书写格式:body节点 .scrollTop/.scrollLeft=value;

    语法:IE环境,document .documentElement .scrollTop/.scrollLeft;

       非IE环境,document .body .scrollTop/.scrollLeft;

    为解决兼容性问题,在使用时可以采用“||”(或)的方式:

      document .body .scrollTop/.scrollLeft || document .documentElement .scrollTop/.scrollLeft;

  ② 元素滚动事件

    元素发生滚动时,不存在兼容性问题,但前提是,必须存在滚动条

    元素的滚动条可以通过 overflow相关属性实现

      overflow属性值:

        visible,默认值,溢出内容不会被修剪,会呈现在元素框之外

        hidden,溢出内容会被修剪,且不可见

        auto,如果溢出内容被修剪,浏览器会显示滚动条以便查看

        scroll,浏览器会显示滚动条,以便查看溢出内容

      overflow-x和 overflow-y属性使用方法与overflow基本相同

    语法:元素节点 .scrollTop / scrollLeft;

    注意,可以获取元素位移距离,也可以写入,书写格式:元素节点 .scrollTop/.scrollLeft=value;

11.滚动事件代码  

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>滚动事件</title>
<style>
    body{
        width: 3000px;
        height: 5000px;
        background: linear-gradient(to bottom,lightblue,darkorange);
    }
    div{
        width: 300px;
        height: 200px;
        margin-left: 100px;
        background-color: lightpink;
        overflow-y: auto;
    }
    .divBtn{
        margin-left: 100px;
    }
    .bodyBtn{
        position: fixed;
        bottom: 10px;
        right: 10px;
    }
</style>
</head>
<body>
    <div>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
        <p>下周就开学了。</p>
    </div>
    <button class="divBtn">滚回首行</button>
    <button class="bodyBtn">返回顶部</button>
<script>
    var divBox=document.querySelector('div');
    var divBtn=document.querySelector('.divBtn');
    var bodyBtn=document.querySelector('.bodyBtn');

    window.onscroll=function () {
        var top=document.body.scrollTop || document.documentElement.scrollTop;
        var left=document.body.scrollLeft || document.documentElement.scrollLeft;
        console.log('Top:'+top+','+'Left:'+left);
    }
//  文档页面滚动事件设置
    bodyBtn.onclick=function(){
        var bodyScrollBack=null;
        console.log(bodyBtn.firstChild.nodeValue);
        // 添加返回顶部速度效果
        bodyScrollBack=setInterval(function () {
            var top=document.body.scrollTop || document.documentElement.scrollTop;
            top = top-100;
            if (top<=0){
                top = 0;
                clearInterval(bodyScrollBack);
            }
            document.body.scrollTop=top;
            document.documentElement.scrollTop=top;   //Chrome环境下也要设置这一句!
        },50);
    };
//  元素内容滚动事件设置
    divBtn.onclick=function(){
        var divScrollBack=null;
        divScrollBack=setInterval(function () {
            var top=divBox.scrollTop;
            top = top-10;
            if (top<=0){
                top = 0;
                clearInterval(divScrollBack);
            }
            divBox.scrollTop=top;
        },50);
    }
</script>
</body>
</html>

  

(0)

相关推荐