js基础知识(2)

一、事件的含义

JavaScript事件是指在文档或者浏览器中发生的一些特定交互瞬间,比如打开某一个网页,浏览器加载完成后会触发load事件,当鼠标悬浮于某一个元素上时会触发hover事件,当鼠标点击某一个元素时会触发click事件等等。

三种事件模型

DOM0 级事件模型,这种模型不会传播,所以没有事件流的概念,但是现在有的浏览器支持以冒泡的方式实现,它可以在网页中直接定义监听函数,也可以通过 js 属性来指定监听函数。所有浏览器都兼容这种方式。

直接在 dom 对象上注册事件名称,就是 DOM0 写法。

IE 事件模型,在该事件模型中,一次事件共有两个过程,事件处理阶段和事件冒泡阶段。

事件处理阶段会首先执行目标元素绑定的监听事件。

然后是事件冒泡阶段,冒泡指的是事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。

attachEvent就是IE事件模型 ,attachEvent用来添加监听函数,可以添加多个监听函数,会按顺序依次执行。

DOM2 级事件模型,在该事件模型中,一次事件共有三个过程,

第一个过程是事件捕获阶段。捕获指的是事件从 document 一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。后面两个阶段和 IE 事件模型的两个阶段相同。

addEventListener 就是DOM2级事件模型。

二、事件组成以及特点

事件由三部分组成

事件源 :给哪个元素/标签/节点来绑定事件

事件类型(某种状态) : eg:点击状态

事件处理程序(事件句柄:handler)

事件函数的特点

全小写、以on开头+事件名,如onclick

三、事件的绑定方式

3.1、行内式

html 复制代码
<div class="box" onclick="console.log(66666)">hello</div>

注意: 行内绑定事件,事件直接执行引号内的代码,这就意味着如下方式绑定事件将不会触发方法

html 复制代码
<div id="container">
  <button id="btn2" onclick="test">test2</button>
</div>
<script>
  function test() { }
</script>

3.2、属性绑定

只能绑定一个处理程序handler,如果绑定多个,只有最后一个生效

html 复制代码
<div class="box">hello</div>
    <script>
        var box = document.querySelector('.box');  
        //对象添加属性 点语法 
        box.onclick = function(){
            console.log('你购买了装备');
        }
        box.onclick = function(){
            console.log('你购买了装备2');
        }
    </script>

3.3、给元素添加一个事件监听器(推荐)

3.3.1、addEventListener介绍

addEventListener() 方法用于向指定元素添加事件处理程序(事件句柄handler)。

参数1:事件名称必须。字符串,指定事件名。

注意: 不要使用 "on" 前缀。 例如,使用 click ,而不是使用 onclick。

参数2:function 必须。指定要事件触发时执行的函数。

注意:事件对象会作为第一个参数传入函数。

参数3:useCapture 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。

true - 事件处理程序(事件句柄)在捕获阶段执行

false默认。事件处理程序(事件句柄)在冒泡阶段执行

事件对象的类型取决于特定的事件。例如, click事件属于 MouseEvent(鼠标事件) 对象。

3.3.2、addEventListener给元素绑定事件

html 复制代码
var box = document.querySelector('.box'); 
//给元素添加一个事件监听器 (绑定事件处理程序)  
box.addEventListener('click',function(){
     console.log(666);
});
console.log(999);

优点一

不阻断代码

分析:还没点击,就打印出999,点击后打印出666,说明 addEventListener()函数并不阻断代码执行。

优点二

可以绑定多个handler,且不影响行内绑定的

html 复制代码
<body>  
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color: #bfa;
        }
    </style>
    <div class="box">hello</div>
    <script>
        var box = document.querySelector('.box'); 
        //给元素添加一个事件监听器 (绑定事件处理程序)  
        box.addEventListener('click',function(){
            console.log(6661);
        });
        box.addEventListener('click',function(){
            console.log(6662);
        });
    </script>
</body>

分析:一点击按钮,就会打印出 6661 和 6662

四、事件的冒泡和捕获

4.1、什么是事件捕获和事件冒泡

事件冒泡

如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发

元素->父元素->body->html->document->window

事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件

事件捕获

从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止

事件捕获,只能通过addEventListener并且参数写true才是事件捕获

其他都是冒泡(不是通过addEventListener添加、addEventListener参数为false)

4.2、事件流

事件流分为三个阶段

1.捕获阶段

2.目标阶段

3.冒泡阶段。

4.3、绑定捕获和冒泡事件

JavaScript中,我们可以使用addEventListener方法来绑定捕获和冒泡事件。

element.addEventListener(event, function, useCapture);
其中,event表示要绑定的事件类型,function表示事件触发时要执行的函数,useCapture是一个可选的参数,用于指定事件是使用捕获还是冒泡阶段进行处理。

当useCapture为false或未提供时,事件将在冒泡阶段进行处理;当useCapture为true时,事件将在捕获阶段进行处理此时事件不在冒泡,只捕获不冒泡。

html 复制代码
<div id="blueBox">
   <div id="yellowBox">
     <div id="greenBox"></div>
   </div>
</div>

<script> 
 let blueBox = document.getElementById('blueBox');
 let yellowBox = document.getElementById('yellowBox');
 let greenBox = document.getElementById('greenBox');
 blueBox.addEventListener('click', () => {
     console.log('blueBox')
 })
 yellowBox.addEventListener('click', () => {
     console.log('yellowBox')
 })
 greenBox.addEventListener('click', () => {
     console.log('greenBox');
 })
</script>

当点击绿色方块时,输出greenBox、yellowBox、blueBox,因为绿色包含在黄色里,黄色和绿色被包含蓝色中。addEventListener不写第三个参数时,事件将在冒泡阶段进行处理,从目标元素开始,逐级向外层元素传播,直到达到最外层的元素,也就是绿色、黄色、蓝色。

同理,点击黄色时,输出yellowBox、blueBox。点击蓝色时,输出blueBox。

如果将第三个参数全部设成true,点击绿色(greenBox),将输出blueBox、yellowBox、greenBox,因为事件将在捕获阶段进行处理,事件捕获的顺序是从最外层的元素开始,逐级向内部元素传播,直到达到目标元素,也就是蓝色、黄色、绿色。

5.4、阻止事件冒泡

event.stopPropagation()

调用该方法会阻止事件继续传播,但不会阻止其他事件处理程序被触发。也就是说,如果一个元素上绑定了多个事件处理程序,调用该方法只会阻止事件传播到更高层级的元素,而不会阻止同一元素上的其他事件处理程序被触发。

html 复制代码
 blueBox.addEventListener('click', () => {
     console.log('blueBox')
 }, true);
 yellowBox.addEventListener('click', () => {
     console.log('yellowBox')
 })
 greenBox.addEventListener('click', (event) => {
     console.log('greenBox');
     event.stopPropagation();
 }, true);

在上面的示例中,当点击绿色方块时,调用event.stopPropagation()会阻止事件继续传播到外层元素,所以只会输出"greenBox",而不会输出"yellowBox"和"blueBox"。

5.5、事件委托

事件委托也称为事件代理(Event Delegation),事件委托是一种将事件处理程序绑定到一个父元素上,而不是将事件处理程序绑定到每个子元素上的技术。通过事件委托,可以减少事件处理程序的数量,提高性能和代码的可维护性。

html 复制代码
<ul id="ul">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

<script>
  let li = document.getElementsByTagName("li");
  for (let i = 0; i < li.length; i++) {
    li[i].addEventListener("click", () => {
      console.log(li[i].innerHTML);
    });
  }
</script>

如上述代码所示,点击某一数字,就会输出对应内容。节点少的时候还好,如果节点多达上千上万个,就需要声明相当多的事件函数,比较消耗内存。而且如果列表经常发生动态变更,也会导致大量监听事件的移除和绑定。

在这种情况下,事件委托就可以体现它的优势了。事件委托正是利用事件流的冒泡特性,将本来要绑定到多个元素的事件函数,委托到了其祖先元素上。

优点:节约内存 提升性能(不需要注销子节点)

//事件代理 节约内存 提升性能(不需要注销子节点)

html 复制代码
let ul = document.getElementById("ul");
ul.addEventListener("click", (event) => {
    console.log(event.target.innerHTML);
})

我们通过将事件处理程序绑定到父元素ul上,当点击列表项时,通过 event 对象拿到必要的信息,会打印出被点击的列表项的内容。如此这般,不管li有多少,更新多频繁,我们只需要维护一个函数就够了。

五、事件对象

5.1、什么是事件对象

当事件被触发时(如onclick事件),浏览器会自动创建一个名为event的JavaScript对象,这个对象存在于window对象中。window.event(window可以省略)表示当前正在处理的事件的详细信息(如事件类型(click、mousemove等)、目标元素、鼠标位置、按键状态等)。

5.2、事件对象的作用

事件对象可以用于访问事件的类型、目标元素、鼠标位置、按键状态等信息,以及阻止事件的默认行为或停止事件的传播。

5.3、如何获取事件对象

5.3.1、行内式绑定事件获取事件对象

//事件被触发后,event对象被创建在window上,window可以省略

html 复制代码
<div id="box" onclick="doClick()"></div>
<script>
      function doClick() {
        console.log(window.event);
      }
</script>

注意!!!!

doClick()这里的括号不可省略,这是因为内联模式下,事件直接执行引号内的代码。

以下方式方法不能调用doClick

html 复制代码
<div id="box" onclick="doClick"></div>
<script>
      function doClick() {
        console.log(window.event);
      }
</script>

5.3.2、属性绑定事件获取事件对象

在属性绑定事件的方式中,浏览器会将事件对象event传递给事件处理函数(handler)

html 复制代码
      // 获取页面中id为box的元素
      var box = document.getElementById("box");
      box.onclick = function (event) {
        //event就是事件触发的时候浏览器传递给事件处理函数
        console.log(event);
      };

5.3.3、addEventListener绑定事件获取事件对象

html 复制代码
// 给一个按钮添加点击事件处理程序
const myButton = document.querySelector("#my-button");

myButton.addEventListener("click", function (event) {
  console.log(event.type); // 获取事件类型(click)
  console.log(event.target); // 获取目标元素(myButton)
});

在上面的代码中,当按钮被单击时,浏览器将自动创建一个事件对象event,并将其传递给事件监听器函数的第二个参数。我们可以通过访问event对象的属性来获取有关事件的信息。

例如,使用event.type可以获取事件类型,而使用event.target可以获取事件的目标元素。

5.4、事件对象阻止默认行为

有些事件具有默认行为,例如单击链接将导航到链接的URL,按下回车键将提交表单等。在某些情况下,我们可能需要取消事件的默认行为。可以使用事件对象的preventDefault()方法来阻止事件的默认行为。

html 复制代码
const myLink = document.querySelector('#my-link');
myLink.addEventListener('click', function(event) {
  event.preventDefault();  // 阻止单击链接的默认行为
});

5.5、事件对象停止事件传播

在JavaScript中,事件通常会在DOM树中沿着从子元素到祖先元素的路径进行传播(冒泡)。这意味着,当您单击一个<button>元素时,该按钮的父级元素也会收到单击事件。

在某些情况下,您可能需要仅响应事件的特定元素,而取消事件对其祖先元素的进一步传播。可以使用事件对象的stopPropagation()方法来停止事件传播。

html 复制代码
const container = document.querySelector('#my-container');
container.addEventListener('click', function(event) {
  console.log('Clicked the container!');
});
 
const myButton = document.querySelector('#my-button');
myButton.addEventListener('click', function(event) {
  event.stopPropagation(); // 阻止事件传播到父元素
  console.log('Clicked the button!');
});

在上述代码中,我们用stopPropagation()方法阻止了事件传播到容器元素,因此单击按钮时,只会显示Clicked the button!而不会显示Clicked the container!。

5.6、事件对象的属性和方法总结

JavaScript中的事件对象是一个非常有用的工具,可以在事件处理程序中访问和操作许多方面的事件信息。下面是常用的事件对象属性和方法的总结:

event.type - 获取事件类型(例如,"click"、"mousedown"等)。

event.target - 获取目标元素(即发出事件的元素)。

event.preventDefault() - 取消事件的默认行为。

event.stopPropagation() - 停止事件在DOM树中的传播。

event.clientX和event.clientY - 获取鼠标光标的坐标。

event.keyCode - 获取按下的键的键码。

总之,了解事件对象的相关属性和方法可以帮助我们更好地理解和操作JavaScript中的事件。我们可以根据需要使用它们来执行特定的操作,并确保一个可交互的和响应式的用户体验。

六、JavaScrip脚本可以处理的事件

|--------|-------------|--------------------------------|
| 事件类型 | 事件 | 说明 |
| 表单相关 | onfocus | 当某个元素获得焦点时触发此事件. |
| 表单相关 | onblur | 当某个元素失去焦点时触发此事件。 |
| 表单相关 | onchange | 当某个元素失去焦点并且元素的内容发生改变时触发此事件。 |
| 表单相关 | onsubmit | 提交表单时触发此事件。 |
| 表单相关 | onreset | 表单被重置时触发此事件 |
| 鼠标相关 | onclick | 单击鼠标时触发此事件 |
| 鼠标相关 | ondblclick | 双击鼠标时触发此事件。 |
| 鼠标相关 | onmousedown | 按下鼠标时触发此事件。 |
| 鼠标相关 | onmouseup | 按下鼠标后松开鼠标时触发此事件。 |
| 鼠标相关 | onmouseover | 当鼠标移动到某元素的区域时触发此事件。 |
| 鼠标相关 | onmousemove | 当鼠标在某元素的区域内移动时触发此事件。 |
| 鼠标相关 | onmouseout | 当鼠标离开某元素的区域时触发此事件。 |
| 键盘相关 | onkeypress | 键盘上的键被按下并释放时触发此事件。可处理单键的操作。 |
| 键盘相关 | onkeydown | 键盘上的键被按下时触发此事件。可处理单键或组合键的操作。 |
| 键盘相关 | onkeyup | 键盘上的键被按下后松开时触发此事件。可处理单键或组合键的操作 |
| 页面相关事件 | onload | 当页面完成加载时触发此事件。 |
| 页面相关事件 | onunload | 当离开页面时触发此事件。 |
| 页面相关事件 | onresize | 当窗口大小改变时触发此事件。 |

6.1、onfocus获得焦点和onblur失去焦点事件

当焦点进入网页上的username文本输入框,该输入框的背景色变为绿色,当焦点离开,背景色改为白色。

html 复制代码
<form name="myform">
  username:<input
    type="text"
    name="username"
    onfocus="dofocus()"
    onblur="doblur()"
  />
</form>

<script>
  function dofocus() {
    // 获得当前的事件
    var event = window.event;
    // 获得触发当前事件的元素
    var element = event.srcElement;
    // 把元素的背景色改为绿色
    element.style.background = "#00FF00";
  }

  function doblur() {
    // 获得当前的事件
    var event = window.event;
    // 获得触发当前事件的元素
    var element = event.srcElement;
    // 把元素的背景色改为白色
    element.style.background = "#FFFFFF";
  }
</script>

6.2. onsubmit表单提交和onreset表单重置事件

当用户按下表单中的提交按钮,会触发onsubmit事件,按下重置按钮,会触发onreset事件。 以下输入框的type属性的值分别为submit和reset,分别表示提交按钮和重置按钮:

html 复制代码
<input type="submit" value="submit" />  
<input type="reset" value="reset" />  

以下代码指定dosubmit()函数处理onsubmit事件,doreset()函数处理onreset事件,action属性指定把表单提交给后端的hello.jsp处理:

html 复制代码
<form
  name="myform"
  onsubmit="return dosubmit()"
  onreset="doreset()"
  action="hello.jsp"
></form>

完整代码

html 复制代码
<form name="myform" action="hello.jsp" onsubmit="return dosubmit()">
  username:<input type="text" name="username" />
  <input type="submit" value="submit" />
  <input type="reset" value="reset" />
</form>

<script>
  function dosubmit() {
    var isSubmit = true;

    if (myform.username.value == "") {
      alert("Please input username.");
      isSubmit = false;
    }

    return isSubmit;
  }
</script>

6.3、onclick鼠标单击事件

当用户单击网页上的按钮、图片等元素,会触发onclick事件。 例程4的bgcolor.html会在网页上显示一个change按钮,点击该按钮,网页的背景色会在红色与白色之间切换。document.bgColor表示网页的背景色。

html 复制代码
<form name="myform" >
 <input type="button" value="change" onclick="doclick()"  />
</form>

<script>
var isRed=true;

function doclick(){  // 切换网页的背景色
  if(isRed)
    document.bgColor="red";
  else
    document.bgColor="white";

  isRed=!isRed;       // isRed变量的值取反
}
</script>

6.4、onmouseover鼠标移入和onmouseout鼠标移出事件

当用户在网页上把鼠标移入某个元素的区域,会触发onmouseover事件,把鼠标移出某个元素的区域,会触发onmouseout事件。鼠标移入该图片区域,图片的透明度设为1,当鼠标移出该图片区域,透明度设为0.3

html 复制代码
<img
  src="logo.gif"
  onmouseover="visible(this,1)"
  onmouseout="visible(this,0.3)"
/>

<script>
  function visible(element, n) {
    // 设置图片的透明度
    element.style.opacity = n;
  }
</script>

6.5. onkeydown、onkeypress、onkeyup按键事件

onkeypress

这个事件在用户按下并放开任何字母数字键时发生,并不是每个按键都会触发这个事件。系统按钮(例如:箭头键和功能键)无法得到识别。

onkeyup

这个事件在用户放开任何先前按下的键盘键时发生。

onkeydown

这个事件在用户按下任何键盘键(包括系统按钮,如箭头键和功能键)时发生。

最难理解的是 onkeyup 和 onkeypress 事件,onkeypress按下并放开,onkeyup 按下并放开所有键,其中略有不同,对于输入快的人,按键都是连续的,所以 onkeypress每个按键都会调用,可理解为正在输入的状态中调用,但是 onkeyup是所有按键都弹起时被调用,调用的次数是按键的个数。

onkeydown 事件最先执行,其次是 onkeypress,最后是才是 onkeyup

三个事件同时在的话,onkeyup不会在中途执行,也就是要等所有按键都弹起以后才会执行。

onkeydown案例

一个红色的色块,当按下键盘的LEFT、RIGHT、UP、DOWN键,色块就会向相应的方向移动

html 复制代码
<div id="box"></div>

<script>
// 获取页面中id为box的元素
var box = document.getElementById("box");  
box.style.position = "absolute";    // 色块绝对定位
box.style.width = "20px";            // 色块宽度
box.style.height = "20px";           // 色块高度
box.style.backgroundColor = "red";  // 色块背景色

// 指定处理onkeydown事件的函数
document.onkeydown = dokeydown;

// 方向键控制色块移动
function dokeydown(){  
  var event = window.event;  
  switch(event.keyCode){  // 获取当前按下键盘键的编码
    case 37 :  // 按下LEFT箭头键,向左移动5个像素
                box.style.left = box.offsetLeft - 5  + "px";
                break;
    case 39 :  // 按下RIGHT箭头键,向右移动5个像素
                box.style.left = box.offsetLeft + 5 + "px";
                break;
    case 38 :  // 按下UP箭头键,向上移动5个像素
                box.style.top = box.offsetTop  - 5 + "px";
                break;
    case 40 :  // 按下DOWN箭头键,向下移动5个像素
                box.style.top = box.offsetTop  + 5 + "px";
                break;
  }
}
</script>

6.6. onload页面加载和onunload页面卸载事件

当用户访问某个网页,浏览器就会先加载该网页,此时会触发onload事件。当用户离开网页、刷新网页或关闭浏览器时,会触发onunload事件。

有时候我们需要在dom渲染完成的时候,才能获取dom,这个时候就可以使用onload事件

html 复制代码
<script>
  const boxDom = document.getElementById("box"); // 报错--此时dom并未渲染完成
  // 正确写法
  window.onload = function () {
    const boxDom = document.getElementById("box");
  };
</script>
<body>
  <div id="box"></div>
</body>

6.7、onscroll事件

onscroll 事件在元素的滚动条被滚动时发生。

在滚动 <div> 元素时执行 JavaScript:

<div οnscrοll="myFunction()">

在不同滚动位置的类名之间切换 - 当用户从页面顶部向下滚动 50 像素时,类名 "test" 将被添加到元素中(再次向上滚动时将被删除)。

html 复制代码
window.onscroll = function() {myFunction()};

function myFunction() {
  if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
    document.getElementById("myP").className = "test";
  } else {
    document.getElementById("myP").className = "";
  }
}

使用 addEventListener() 方法:

object.addEventListener("scroll", myScript);

6.8、onscroll事件

onresize 事件在浏览器窗口被调整大小时发生。

调整浏览器窗口大小时执行 JavaScript:

<body οnresize="myFunction()">

属性绑定

object.onresize = function(){myScript};

使用 addEventListener() 方法在 window 对象上附加 "resize" 事件:

window.addEventListener("resize", myFunction);

相关推荐
小纯洁w8 分钟前
Python numpy 应用之 topn
开发语言·python·numpy
得不到的更加爱11 分钟前
Java多线程不会?一文解决——
java·开发语言
五敷有你13 分钟前
Go:hello world
开发语言·后端·golang
V言微语15 分钟前
2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片
开发语言·数码相机·c#
forwardMyLife22 分钟前
element-plus 的form表单组件之el-radio(单选按钮组件)
前端·javascript·vue.js
拔剑纵狂歌32 分钟前
Golang异常处理机制
开发语言·后端·golang·go
fs哆哆34 分钟前
ExcelVBA运用Excel的【条件格式】(二)
linux·运维·服务器·前端·excel
L小李要学习1 小时前
十一、作业
c语言·开发语言·c++
安冬的码畜日常1 小时前
【CSS in Depth 2精译】2.5 无单位的数值与行高
前端·css
ilisi_1 小时前
导航栏样式,盒子模型
前端·javascript·css