JS事件02(鼠标事件、拖拽、focus和input事件、组织默认事件、按键事件、滚轮事件)

鼠标事件

<style>
    body{
        margin: 0;
    }
    .div0
    {
        width:100px;
        height:100px;
        
        position: relative; 
            left:100px; 
            top:800px;
        /* margin: 100px; */
        
    }
    .div1
    {
        width: 50px;
        height: 50px;
        
        position: absolute;
        left:50px;
        top:50px;
        /* margin: 50px; */
    
    }
    .span0
    {
        display: none;
        
        position: absolute;
        padding: 0px 5px;
        border-radius: 50px;
        font-size: 12px;
        z-index: 999;
    }
</style>
<span class="span0">aaaaa</span>
<div class="div0">
    <div class="div1"></div>
</div>
<script>
    /*  clientX: 33  距离可视区域左上角位置
        clientY: 31
​
        layerX: 28   如果目标对象是定位方式,值于offset相似
        layerY: 20   如果目标对象是非定位方式,
        // 取父容器的左上角位置,如果父容器未定位,继续向上取
​
        offsetX: 16  相对事件目标对象的左上角位置
        offsetY: 9
​
        movementX: 0  仅用于mousemove事件  这个值是鼠标移动时相对上次获取坐标的距离
        movementY: 0
​
        pageX: 28 相对页面顶端左上角位置
        pageY: 25
​
        screenX: 38  相对屏幕左上角位置
        screenY: 107
​
        x: 32   和clientX,clientY相同
        y: 33
​
        按下键点击鼠标时变为true
        altKey: false 
        ctrlKey: false
        metaKey: false
        shiftKey: false
​
        针对mousedown事件的属性,判断按下的键
                左键    中键   右键
        button:  0     1       2
        buttons: 0     4       2
        which:   1     2       3
        */
​
    var div=document.querySelector(".div0");
    // div.addEventListener("mousedown",clickHandler);
    // div.addEventListener("mouseup",clickHandler);
    // div.addEventListener("click",clickHandler);
    // div.addEventListener("mouseover",clickHandler);
    // div.addEventListener("mouseout",clickHandler);
    // div.addEventListener("mouseenter",clickHandler);
    // div.addEventListener("mouseleave",clickHandler);
    // mouseover mouseout具有冒泡功能可以收到鼠标滑入滑出子元素的冒泡事件
    // mouseenter mouseleave仅对侦听的对象起到事件接收作用
    // div.addEventListener("mousemove",mouseHandler);
    // div.addEventListener("mouseover",mouseHandler);
    // div.addEventListener("mouseout",mouseHandler);
    div.addEventListener("contextmenu",mouseHandler);
    // var span0=document.querySelector(".span0");
​
    function clickHandler(e){
        console.log(e.type);
        // console.log(e.clientX,e.clientY)
    }
​
    /*  function abc(){
        console.log(e.clientX,e.clientY);
    } */
​
    /* 
        click  点击左键
        dblclick  双击左键
        mousedown  按下键
        mouseup    释放键
        mouseover  滑过
        mouseout   滑出
        mouseenter  进入
        mouseleave  离开
        mousemove  移动
        contextmenu 右键菜单
        */
​
        function mouseHandler(e){
            e.preventDefault();
            console.log(e);
        /*  switch(e.type){
                case "mouseout":
                span0.style.display="none";
                break;
                case "mouseover":
                span0.style.display="inline-block";
                case "mousemove":
                span0.textContent="这是"+getComputedStyle(e.target).backgroundColor+"颜色";
                span0.style.left=e.pageX+"px";
                span0.style.top=e.pageY+"px";
                break;
            } */
        }
    //  tooltip
</script>

拖拽

var Utils=(function(){
/* 
    拖拽方法
        拖拽元素
        参数:
            elem:被拖拽的HTML标签DOM元素   HTMLElement
            parentOut:是否不允许拖拽到容器外
                类型 Boolean:true 不允许拖拽到父容器外
                                false 允许拖拽到父容器外
                    Object  示例:{width:Number,height:Number};
                            width和height限制拖拽的范围
                            如果为0,该方向不能拖拽
        返回:无
​
        1、完成拖拽的起始侦听事件,当侦听在元素上按下mousedown事件时
            执行当前对象的函数mousedownHandler
        2、将当前对象存储在这个元素的obj属性中,用于在后面按下时调用
            到当前对象
        3、设置这个元素的定位为绝对定位
        4、设置document对象的属性是当前带入参数是否不允许拖拽到容器外这个值
            用来在后续中判断该元素是否允许拖拽脱离当前容器
    */
    dragElem:function(elem,parentOut){
        elem.obj=this;
        elem.style.position="absolute";
        document.parentOut=parentOut;
        elem.addEventListener("mousedown",this.mousedownHandler);
    },
    /* 
        鼠标按下键和鼠标移动,释放的事件函数
        参数:
            e  MouseEvent 鼠标对象 由鼠标事件自动创建该参数
        1、鼠标按下时
            鼠标按下时 this,e.currentTarget   针对标签元素  this->按下的标签元素
                1、取消默认事件行为,可以解决拖拽时产生禁止拖拽图标
                2、将当前按下鼠标左键相对元素左上角的坐标存储在document的对象属性X和y上
                用于后面调用时使用
                3、将当前this,也就是按下的元素存储在document对象属性div中
                4、将当前Utils这个对象存在document对象属性obj中,用于后面的调用
            5、针对document侦听鼠标移动和释放事件,执行的函数是Utils对象,这个对象存在this.obj
                也就是按下元素的obj属性
        2、鼠标移动时
            this,因为鼠标是侦听document上移动的事件,所以,this是document
            1、获取当前按下元素的父元素,this.div就是document.div,这个在按下时做了存储
                并且求出它的父元素的范围矩形,这个返回矩形包括父元素的相对可视窗口的坐标和父元素宽高
            2、计算出x,y是当前鼠标移动位置相对当前元素父元素的左上角位置 
            3、判断 parentOut传入参数属性是不是允许拖拽到父元素外,如果是true,不允许拖拽到父元素外
                如果是对象就需要设置拖拽的范围
                如果是true,拖拽时禁止x和y小于0,限制右侧和下侧不出容器
                如果时对象,限制不出对象宽高的范围,
            4、设置这个元素的位置是调整过后坐标
        3、鼠标释放时
            删除document上所有的mousemove事件和mouseup事件
    
    */
    mousedownHandler:function(e){
        // 1、事件函数中的this会覆盖普通对象中函数this的指向
        // 2、事件函数中,针对e.type事件类型所有对应的事件侦听对象才是this
​
        if(e.type==="mousedown"){
            e.preventDefault();
            document.x=e.offsetX;
            document.y=e.offsetY;
            document.div=this;
            document.obj=this.obj;
            document.addEventListener("mousemove",this.obj.mousedownHandler)
            document.addEventListener("mouseup",this.obj.mousedownHandler)
        }else if(e.type==="mousemove"){
            var left,top;
            var rect=this.div.parentElement.getBoundingClientRect();
            var x=e.clientX-this.x-rect.x;
            var y=e.clientY-this.y-rect.y;
            if(this.parentOut===true){
                if(x<0) x=0;
                if(x>=rect.width-this.div.offsetWidth)x=rect.width-this.div.offsetWidth;
                if(y<0) y=0;
                if(y>=rect.height-this.div.offsetHeight) y=rect.height-this.div.offsetHeight;
            }else if(typeof this.parentOut==="object"){
                if(x<0) x=0;
                if(x>=this.parentOut.width-this.div.offsetWidth)x=this.parentOut.width-this.div.offsetWidth;
                if(y<0) y=0;
                if(y>=this.parentOut.height-this.div.offsetHeight) y=this.parentOut.height-this.div.offsetHeight;
                if(this.parentOut.width===0) x=0;
                if(this.parentOut.height===0) y=0;
            }
            this.div.style.left=x+"px";
            this.div.style.top=y+"px";
        }else{
            document.removeEventListener("mousemove",this.obj.mousedownHandler)
            document.removeEventListener("mouseup",this.obj.mousedownHandler)
        }
    },
    dragOff:function(elem){
        elem.obj=null;
        document.obj=null;
        elem.removeEventListener("mousedown",this.mousedownHandler);
    }
}
})();

焦距和Input事件

<input type="text" id="input0" placeholder="用户名">
<input type="text" id="input1">
<script>
    /* 
        FocusEvent  焦距事件
            focus  汇聚焦距
            blur   失去焦距
            所有的表单元素,例如文本框
            超链接
            focus汇聚焦距的方式有点击,tab切换
    
    */
​
    var input0=document.querySelector("#input0");
    var input1=document.querySelector("#input1");
    input0.addEventListener("focus",focusHandler);
    input1.addEventListener("focus",focusHandler);
    input1.addEventListener("blur",focusHandler);
​
    function focusHandler(e){
        console.log(e);
        // e.relatedTarget  上次汇聚焦距的元素
    }
​
    // inputEvent  input事件
    var input0=document.querySelector("#input0");
    input0.addEventListener("input",inputHandler);
​
    function inputHandler(e){
        console.log(e);
        
            /*   e.data: "o"  输入的内容
            e.inputType: "insertText" 输入的类型  insertCompositionText
                            包括插入文本,删除文本,插入输入法文本,剪切粘贴文本等等
            e.isComposing: true   是否是输入法文本   
        */
        if(!isNaN(e.data)) input0.value=input0.value.replace(e.data,"");
    }
​
    // 节流
​
    var input0=document.querySelector("#input0");//拿到input0这个标签
    var ids;//定义一个ids计数器
    input0.addEventListener("input",inputHandler);//给input标签加一个事件监听
​
    function inputHandler(e){//当input事件发生时,执行这个函数
        if(ids!==undefined) return;//当ids有值时,即setTimeout创建后ids计数器有值,此时直接return 
        ids=setTimeout(function(){//如果未赋值,创建一个setTimeout
            clearTimeout(ids);//首先清除ids计数器
            ids=undefined;
            console.log(input0.value);//打印此次节流500ms后的input的值
        },500);
    }
</script>

阻止默认事件

<style>
    div
    {
        width: 100px;
        height: 100px;
        
    }
</style>
<form action="#">
    <input type="text" name="user">
    <input type="password" name="pass">
    <input type="submit">
    <input type="reset">
</form>
<div>askjdjksad</div>
<img src="./img/1.png">
<script>
    // 1、表单事件中的submit reset 使用阻止默认事件可以取消提交和重置
    /* var form=document.querySelector("form");
    form.addEventListener("submit",formHandler);
    form.addEventListener("reset",formHandler);
​
    function formHandler(e){
        e.preventDefault();        
    } */
​
    // 2、当使用contextmenu事件,取消鼠标右键菜单
    /* document.addEventListener("contextmenu",mouseHandler);
    function mouseHandler(e){
        e.preventDefault();      
    } */
​
    // 3、当针对元素拖拽时,元素内有文本,文本会被选中
    /* var div=document.querySelector("div");
    document.addEventListener("mousedown",mouseHandler);
​
    function mouseHandler(e){
        e.preventDefault();       
    } */
​
    // 4、图片拖拽时产生禁止拖拽图标
    /* var img=document.querySelector("img");
    img.addEventListener("mousedown",mouseHandler);
​
    function mouseHandler(e){
        e.preventDefault();
    } */
</script>

按键事件

<style>
    textarea
    {
        width: 800px;
        height: 400px;
    }
    input
    {
        width: 600px;
    }
    div
    {
        width: 500px;
        height: 400px;
        border:1px solid #000000;
        word-wrap: break-word;
    }
</style>
<!-- <textarea id="texts"></textarea><br>
<input type="text" id="msg">
<button>提交</button> -->
<div></div>
<script>
        /* 
            e.code: "KeyA"
            e.key: "a"
            e.keyCode: 65
            e.which: 65   */
            
    document.addEventListener("keydown",keyHandler);
    function keyHandler(e){
        console.log(e);
        
    }
​
    var texts,msg,bn
    init();
    function init(){
        texts=document.querySelector("#texts");
        msg=document.querySelector("#msg");
        bn=document.querySelector("button");
        bn.addEventListener("click",clickHandler);
        document.addEventListener("keydown",clickHandler);
    }
​
    function clickHandler(e){
        if(e.type!=="click" && e.type!=="keydown") return;
        if(e.keyCode && e.keyCode!==13) return
        if(msg.value.trim().length<1) return;
        texts.value+=msg.value+"\n";
        msg.value="";
    } 
​
    // 富文本编辑器
    var div=document.querySelector("div");
    document.addEventListener("keydown",keyHandler);
    // document.addEventListener("keyup",keyHandler);
​
    function keyHandler(e){
        if(e.keyCode<48 || e.keyCode>57 && e.keyCode<65 || e.keyCode>90) return;
​
        div.innerHTML+=e.key;
    }
</script>

人物走路案例

var actor,code;
var bool=false,
    dic="",
    time=0,
    speed=1,
    num=0,
    x=0,
    y=0;
​
init();
function init(){
    actor=createActor();
    document.addEventListener("keydown",keyHandler);
    document.addEventListener("keyup",keyHandler);
    setInterval(animation,16);
}
​
function createActor(){
    var  actor=document.createElement("div");
    Object.assign(actor.style,{
        width:"32px",
        height:"32px",
        position:"absolute",
        left:0,
        top:0,
        backgroundImage:'url(./img/Actor01-Braver03.png)',
    });
    document.body.appendChild(actor);
    return actor;
}
​
// 37,38,39,40
function keyHandler(e){
    bool=e.type==="keydown";
    code=e.keyCode;
    if(e.type==="keyup"){
        actor.style.backgroundPositionX="0px";
        time=0;
    }
}
​
function animation(){
    if(!bool) return;
​
    actorMove();
    actorAction();
}
​
function actorAction(){
    if(code<37 || code>40) return;
    time--;
    if(time>0)return;
    time=15;
    actor.style.backgroundPositionX=num++%4*-32+"px"
}
​
function actorMove(){
    switch(code){
        case 37:
        if(dic!=="left"){
            actor.style.backgroundPositionY="-33px";
            dic="left"
        }
            x-=speed;
        break;
        case 38:
        if(dic!=="top"){
            actor.style.backgroundPositionY="-99px";
            dic="top"
        }
            y-=speed;
        break;
        case 39:
        if(dic!=="right"){
            actor.style.backgroundPositionY="-66px";
            dic="right"
        }
            x+=speed;
        break;
        case 40:
        if(dic!=="bottom"){
            actor.style.backgroundPositionY="0px";
            dic="bottom"
        }
            y+=speed;
        break;
    }
    actor.style.left=x+"px";
    actor.style.top=y+"px";
}

滚轮事件

/* 向上
google和IE
deltaX: -0
deltaY: -100
deltaZ: 0
detail: 0
wheelDelta: 120
wheelDeltaX: 0
wheelDeltaY: 120
火狐
e.detail: -3
*/
var speed=0;
window.addEventListener("mousewheel",wheelHandler);
window.addEventListener("DOMMouseScroll",wheelHandler)
​
function wheelHandler(e){
    if(e.type==="mousewheel"){
        speed=e.deltaY<0 ? -10 : 10; 
    }else if(e.type==="DOMMouseScroll"){
        speed=e.detail<0 ? -10 : 10;
    }
    console.log(speed);
} 

 

posted @ 2020-07-25 23:45  菠蘿的旅行  阅读(1037)  评论(0编辑  收藏  举报