【javascript】事件

事件处理函数

1、ele.onxxx = function(event) {}

  兼容性很好,但是一个元素的同一个事件上只能绑定一个处理程序

  等同于写在行间上: <div onclick="console.log('a')"></div>

  程序 this 指向 dom 元素本身

2、obj.addEventListener(type, fn, false)

  IE9以下不兼容,可以为一个事件绑定多个处理程序

  div.addEventListener(type, function() {}, false)

  div.addEventListener(type, function() {}, false)

  两个函数不能是同一个函数

  程序 this 指向 dom 元素本身

3、obj.attachEvent('on' + type, fn)

  IE 独有,一个事件绑定多个处理程序

  div.attachEvent(type, function() {})

  div.attachEvent(type, function() {})

  两个函数可以是是同一个函数

  程序 this 指向 window

4、封装兼容的 添加事件函数

            function addEvent(elem, type, handle) {
                if (elem.addEventListener) {
                    elem.addEventListener(type, handle, false);
                } else if (elem.attachEvent) {
                    elem.attachEvent('on' + type, function() {
                        handle.call(elem);    //解决 attachEvent   this指向window的问题
                    })
                } else {
                    elem['on' + type] = handle;
                }
            }

5、练习:用addEventListener 给每一个li添加事件,点击返回li 的顺序

                <ul>
                    <li>a</li>
                    <li>a</li>
                    <li>a</li>
                    <li>a</li>
                </ul>
                <script type="text/javascript">
                    var li = document.getElementsByTagName('li'),
                        len = li.length;
                    for(var i = 0; i < len; i ++) {
                     (function (i) {     //这里形成了闭包,因此需要用立即执行函数
                            li[i].addEventListener('click', function() {
                                console.log(i + 1);
                            }, false);
                        }(i));
                    }
                </script>    

解除事件处理程序

1、ele.onclick = false // null

      div.onclick = function () {

    console.log('1');

            this.onclick = null;

      }

2、ele.removeEventListener(type, fn, false);

       div.addEventListener('click', handle, false);

       function handle() {console.log('a');}

       div.removeEventListener('click', handle, false);

3、ele.detachEvent('on' + type, fn);

注意:如果绑定 匿名函数, 则无法解除

事件处理模型

1、事件冒泡

  结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,

  即同一事件,自子元素冒泡向父元素。 自底向上)

例:                    <div class="wrapper">
                            <div class="content">
                                <div class="box">
                                </div>
                            </div>
                        </div>
                        <script type="text/javascript">
                            var wrapper = document.getElementsByClassName('wrapper')[0],
                                content = document.getElementsByClassName('content')[0],
                                box = document.getElementsByClassName('box')[0];
                            wrapper.addEventListener('click', function() {
                                console.log('wrapper');
                            }, false);
                            content.addEventListener('click', function() {
                                console.log('content');
                            }, false);
                            box.addEventListener('click', function() {
                                console.log('box');
                            }, false);
                        </script>

点击wrapper 时, 打印 wrapper

点击content时, 打印 content wrapper

点击box时, 打印 box content wrapper

2、事件捕获

  结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,

  即同一事件,自父元素冒泡向子元素(事件源元素)。 自顶向下)

  IE没有捕获事件

例:                 <div class="wrapper">
                            <div class="content">
                                <div class="box">
                                </div>
                            </div>
                        </div>
                        <script type="text/javascript">
                            var wrapper = document.getElementsByClassName('wrapper')[0],
                                content = document.getElementsByClassName('content')[0],
                                box = document.getElementsByClassName('box')[0];
                            wrapper.addEventListener('click', function() {
                                console.log('wrapper');
                            }, true);                     //改为true,就变成了捕获
                            content.addEventListener('click', function() {
                                console.log('content');
                            }, true);
                            box.addEventListener('click', function() {
                                console.log('box');
                            }, true);
                        </script>
点击wrapper 时, 打印 wrapper 点击content时, 打印 wrapper content 点击box时, 打印 wrapper content box

3、触发顺序,先捕获,后冒泡,被点击区域,按照事件执行顺序执行

4、focus, blur, change, submit, reset, select 等事件不冒泡

 

5、取消冒泡

  1、W3C标准 event.stopPropagation(); 但不支持ie9以下版本

  2、IE独有 event.cancelBubble = true;

  3、封装取消冒泡函数:

function stopBubble(event) {
    if(event.stopPropagation) {
        event.stopPropagation();
    }else {
    event.stopBubble = true;
    }
}        

阻止默认事件

  默认事件有 表单提交 a 标签跳转 右键菜单 

  1、return false  : 以对象属性的方式注册的事件才生效,

    如:(1)a 标签

              a 标签跳转会重新加载页面和跳到页面顶端

                        a 标签href 里可以写javascript 代码,如

        <a href = "javascript:alert(‘a’)">demo</a>

        a标签取消默认事件:<a href = "javascript:void(false)">demo</a>

      (2)右键菜单 document.oncontextmenu = function () {

                    console.log('a');

                   return false;

                   }

  2、event.preventDefault() : IE9以下不兼容,

    例: 右键菜单: document.oncontextmenu = function (e) {

              console.log('a');

              e.preventDefault();

      ·      }

  3、event.returnValue = false;  兼容IE

        例: 右键菜单: document.oncontextmenu = function (e) {

              console.log('a');

              e.returnValue = false;

            }

  4、封装阻止默认事件的函数

function cancelHandler(event) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
}        

事件对象

  event || window.event(用于IE)

  1、事件源对象 target

    event.target  火狐只有这个

    event.srcElement   ie只有这个

    chrome 两个都有

  兼容性写法:

    div.onclick = function (e) {

      var event = e || window.event;

      var target = event.target || event.srcElement;

    }

  例子3000个li,点击相应的li ,输出相应li 的文本

var ul = document.getElementsByTagName(‘ul’)[0];  
  // 先获取ul ,因为每个li 事件都会冒泡到ul
  ul.onclick = function (e) {
    var event = e || window.event;
    var target = event.target || event.srcElement;
    console.log(target.innerHTML);
}

 

事件委托

  利用事件冒泡,和事件源对象进行处理

  优点:

    1、性能不需要循环所有的元素一个个绑定事件

    2、灵活 当有新的子元素时不需要重新绑定事件

 

鼠标事件

  1、鼠标事件有:click  mousedown  mousemove  mouseup  contextmenu  

    mouseover-mouseout   ==  mouseenter -mouseleave

    click == mousedown + mouseup

  2、button 来区分鼠标的按键  0 / 1 /2

    左键:0  中键:1  右键: 2

  3、DOM3 标准规定:click事件只能监听左键,只能通过mousedown和 mouseup 来判断鼠标键

  4、如何解决mousedown 和 click 的冲突

                    var firstTime = 0,
                        lastTime = 0,
                        key = false;
                    document.onmousedown = function() {
                        firstTime = new Date().getTime();
                    }
                    document.onmouseup = function() {
                        lastTime = new Date().getTime();
                        if(lastTime - firstTime < 300) {
                            key = true;
                        }
                    }
                    document.onclick = function() {
                        if(key) {
                            console.log('click');
                            key = false;
                        }
                    }

  5、例子:拖拽

                    <div style="width: 80px;height: 80px;background-color: red;"></div>
                    <script type="text/javascript">
                        var div = document.getElementsByTagName('div')[0];
                        div.onmousedown = function() {
                            div.onmousemove = function() {
                                var event = e || window.event;
                                div.style.left = e.pageX + 'px';
                            }
                            
                        }
                    </script>

  6、div.setCapture(); 事件捕获,仅在IE里好使,div会捕获页面上发生的所有事件到自己身上

             div.releaseCapture();

键盘事件

  1、keydown  keyup   keypress

  2、keydown > keypress > keyup:顺序是先keydown ,keypress 到 keyup

  3、keydown 和 keypress 的区别

             keydown 可以响应任意键盘按键, charCode:0

             keypress只可以响应字符类键盘按键  charCode 10

             keypress返回ASCII码, 可以转换成相应字符

  4、打印键盘对应的字符

    document.onkeypress = function(e) {

      console.log(String.fromCharCode(e.charCode))

    }

文本操作事件:

1、input

  var input = document.getElementsByTagName('input')[0];
  input.oninput = function (e) {
    console.log(this.value);
  }
  //但凡input 里的内容有变化,都会打印input里的内容

2、change

var input = document.getElementsByTagName('input')[0];
input.onchange = function (e) {
  console.log(this.value);
}
//当input 里失去焦点,就会打印input里的内容

3、focus,blur

  input默认值的设置

<input type="text" value="请输入用户名"
       onfocus="if(this.value == '请输入用户名')this.value=''"
       onblur="if(this.value=='')this.value='请输入用户名'"/>

窗体操作类 --> window上的事件

  1、scroll :scoll滚动条一滚动,事件触发:

  2、load : window.onload = function(){}

  浏览器执行顺序:

    先生成一个domTree , cssTree,两个合成一个渲染树 renderTree

    onload 会等整个文档解析完后,renderTree 构建完后,dom所有的信息全部下载完后,

    整个页面全部就绪的时候,才会触发load事件,这个效率是最低的

  4、例子:fixed 定位 js兼容版

function positionFixed(elem) {
  var elemTop = elem.offsetTop;
  window.onscroll = function() {
    div.style.top = window.pageYOffset + elemTop + 'px';
  }
}

 

猜你喜欢

转载自www.cnblogs.com/hjysunshine/p/12285199.html
今日推荐