【JS交互篇】事件和元素操作

这篇具有很好参考价值的文章主要介绍了【JS交互篇】事件和元素操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、事件 和 元素相关属性

事件是用户或者浏览器自身执行的某种动作,如:click、load和mouseover等,都是事件的名字;

原生JavaScipt案例合集
JavaScript +DOM基础
JavaScript 基础到高级
Canvas游戏开发

1.1 窗口或元素相关事件:

事件 描述
onload 页面或图像加载完成后触发的事件
onresize 窗口发生改变时触发的事件
onscroll 窗口滚动条滚动时触发的事件

1.2 元素相关属性

属性 描述
element.clientHeight 在页面上返回内容的可视高度(不包括边框,边距或滚动条)
element.clientWidth 在页面上返回内容的可视宽度(不包括边框,边距或滚动条)
element.offsetHeight 返回任何一个元素的高度包括边框和填充,但不是边距
element.offsetWidth 返回元素的宽度,包括边框和填充,但不是边距
element.scrollTop 页面或元素顶部被卷去的距离
element.scrollLeft 页面或元素左边被卷去的距离
element.offsetLeft 返回当前元素的相对水平偏移位置的偏移容器
element.offsetTop 返回当前元素的相对垂直偏移位置的偏移容器
element.offsetParent 返回元素的偏移容器

1.4 鼠标事件

事件 描述
onclick 鼠标单击触发的事件
ondblclick 鼠标双击触发的事件
oncontextmenu 鼠标右键触发的事件
onmouseover 鼠标滑过触发的事件
onmoseout 鼠标离开触发的事件
onmouseenter 鼠标指针移动到当前元素上触发的事件
onmouseleave 鼠标指针移出当前元素触发的事件
onmousedown 鼠标被按下触发的事件
onmouseup 鼠标被松开触发的事件
onmousemove 鼠标移动事件

  1. onmouseenter 和 onmouseleave 不支持事件冒泡;而onmouseout 和 onmouseover支持事件冒泡
  2. mouseenter 事件只有在鼠标指针进入被选元素时被触发,mouseover事件在鼠标指针进入任意子元素时也会被触发;
  3. mouseleave 事件只有在鼠标指针离开被选元素时被触发,mouseout事件在鼠标指针离开任意子元素时也会被触发
  4. onclick、onmousedown、onmouseup执行的顺序 onmousedown --> onmouseup --> onclick

1.6 键盘事件

事件 描述
onkeydown 键盘按键被按下触发的事件
onkeyup 键盘按键被松开触发的事件
onkeypress 键盘按键(数字和字母)被按下并松开时触发的事件

  1. 三个键盘事件触发的顺序 onkeydown --> onkeypress --> onkeyup
  2. keypress 主要用来接收字母、数字等ANSI字符,箭头键和功能键不能被触发,如:Alt、Ctrl、Shift、Esc 等功能键
  3. keydown和keyup事件可以处理任何不被keypress识别的击键。诸如:功能键(F1-F12),编辑键、定位键以及任何这些键和键盘换档键的组合键

1.8 表单事件

事件 描述
onfocus 获取表单控件的焦点
onblur 失去表单控件的焦点
oninput 获取用户在控件中正在输入的事件
onchange 获取表单发生改变的事件
onselect 表单中内容被选中的事件
onsubmit 表单提交事件
onreset 表单信息重置事件

注:onsubmit、onreset 事件由 form 元素驱动

二、事件对象

事件对象是用来记录事件发生时相关信息的对象。如: 鼠标事件发生后,获取鼠标的横坐标 event.clientX ( clientX用来获取鼠标距离浏览器左边的距离 ) 。

事件对象只有在事件被触发时才会产生,并且只能在事件处理函数内部访问;当事件处理函数运行结束后,事件对象就被销毁。

对于不同的浏览器,事件对象获取的方式不同:

  • IE8及以下浏览器版本中,只能直接从全局中获取事件对象 window.event

  • 火狐(Firefox,简称FF)低版本浏览器中,只能通过事件传递的方式,在事件函数中传递事件对象

  • 所有高版本浏览器两者都兼容

获取事件对象的兼容性写法:

element["on" + 事件类型] = function(e){
	var ev = e || window.event;
}

事件对象通用属性:

属性 描述
type 返回事件的类型

鼠标事件对象相关属性:

属性 描述
clientX 返回当事件被触发时,鼠标指针的水平坐标。
clientY 返回当事件被触发时,鼠标指针的垂直坐标
screenX 返回当某个事件被触发时,鼠标指针的水平坐标。
screenY 返回当某个事件被触发时,鼠标指针的垂直坐标。
pageX 鼠标相对于浏览器(这里说的是浏览器的有效区域)左上角x轴的坐标; 随滚动条滚动而改变
pageY 鼠标相对于浏览器(这里说的是浏览器的有效区域)左上角y轴的坐标; 随滚动条滚动而改变
offsetX 鼠标相对于事件源左上角X轴的坐标
offsetY 鼠标相对于事件源左上角Y轴的坐标

键盘事件对象相关属性:

属性 描述
key 在按下按键时返回按键的标识符
keyCode 返回onkeypress事件触发的键的值的字符代码,或者 onkeydown 或 onkeyup 事件的键的代码
which 返回onkeypress事件触发的键的值的字符代码,或者 onkeydown 或 onkeyup 事件的键的代码

注:onkeypress 事件触发的键的值的字符代码(表示ASCII字符的数字),或者 onkeydownonkeyup 事件的键的代码(表示键盘上真实键的数字)。

三、事件处理程序

事件处理程序指的是当HTML中发生某些事件时所调用的方法。

事件处理程序分为以下几种:

  1. HTML事件处理程序

    直接在html元素中使用"on"+事件类型实现,如:onclick ,使得html元素具有能够执行js 代码的特性

    这种事件处理程序有两个缺点:

    • 存在一个时差的问题,如果将 script 程序写在页面的最底部,而用户又在 html 元素一出现就触发相应的事件,这个时候事件处理程序有可能尚不具备执行条件(即:script 程序未加载,dom 从上往下依次解析html 文件)
    • html 代码与 JS 代码紧密耦合,这样在维护或修改时需要修改两个地方。所以建议摒弃 html 事件处理程序,进而使用 JS 指定事件处理程序
  2. DOM0级事件处理程序

    通过 JS 指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。这种操作简单且具有跨浏览器的优势。

    • 使用DOM0级方法指定的事件处理程序被认为是元素的方法;因此这时候的事件处理程序是在元素的作用域中运行;即:程序中的this引用的是当前元素
    • 这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

    添加方式:element[‘on’ + 事件类型] = function(){}

    移除方式:element[‘on’ + 事件类型] = null

  3. DOM2级事件处理程序

    添加方式:element.addEventListener(type,handler,boolean)

    移除方式: element.removeEventListener(type,handler,boolean)

    注意:移除时三个对应参数事件类型、事件函数、事件冒泡或捕获阶段要一一对应,匿名函数没有办法被移除。

    IE8及以下浏览器报错: 对象不支持 “addEventListener” 属性或方法;

    可以给同一个元素定义多个同种类型的事件函数;

    第三个参数默认是false,事件冒泡流阶段。多个同种类型的事件,按照渲染顺序,依次执行。

  4. IE事件处理程序

    添加方式:element.attachEvent(‘on’+事件类型,事件函数)

    移除方式:element.detachEvent(‘on’+事件类型,事件函数)

    只能在IE10及以下浏览器版本中使用,其它浏览器报错:btn.attachEvent is not a function

    也可以添加多个同种类型的事件,执行顺序按照渲染顺序逆向执行。

    与DOM0级方法的区别在于事件处理程序的作用域不同:DOM0级是在其所属元素的作用域内运行,而IE事件处理程序是在全局作用域运行,因此this等于window。

    与DOM2级方法一样,可以为同一个按钮添加两个不同事件处理程序,但是IE事件处理程序的执行顺序是以相反的顺序触发,即先触发的是后面添加的事件。

    使用detachEvent()来移除通过attachEvent()方法添加的事件,与DOM2级方法一样,匿名函数无法被移除

添加事件的事件处理程序兼容性代码:

function addEvent(elem, type, fn) {
    if (elem.addEventListener) { //支持DOM2
        elem.addEventListener(type, fn);
    } else if (elem.attachEvent) { //IE8及以下
        elem.attachEvent('on' + type, fn)
    } else {
        elem['on' + type] = fn
    }
}

移除事件的事件处理程序兼容性代码

function removeEvent(elem, type, fn) {
    if (elem.removeEventListener) {
        elem.removeEventListener(type, fn)
    } else if (elem.detachEvent) {
        elem.detachEvent("on" + type, fn)
    } else {
        elem["on" + type] = null
    }
}

添加和移除事件处理程序的兼容性代码:

var oEvent = {
        /**
         * 添加事件的函数
         * @elem 添加事件的元素
         * @type 事件类型
         * @fn  事件执行函数
         * */
        addEvent: function (elem, type, fn) {
            if (elem.addEventListener) {
                elem.addEventListener(type, fn);
            } else if (elem.attachEvent) {
                elem.attachEvent('on' + type, fn)
            } else {
                elem["on" + type] = fn;
            }
        },
        /**
         * 添加事件的函数
         * @elem 添加事件的元素
         * @type 事件类型
         * @fn  事件执行函数
         * */
        removeEvent: function (elem, type, fn) {
            if (elem.removeEventListener) {
                elem.removeEventListener(type, fn)
            } else if (elem.detachEvent) {
                elem.detachEvent("on" + type, fn)
            } else {
                elem["on" + type] = null
            }
        },
        /**
         * 定义一个函数,元素只能执行一次事件;如:点击事件,第一次点击有效,第二次点击无效
         * */
        once: function () {

        }
}

四、事件流

事件流用来描述从页面中接收事件的顺序。

事件流分为两种:事件冒泡流和事件捕获流。这两种事件流的概念几乎完全相反。

事件流出现的前提:嵌套元素中定义了同种类型的事件。

事件捕获流只能通过 DOM2 级事件处理程序实现

4.1 事件冒泡流

IE事件流叫做事件冒泡,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档);也就是说一个标签元素处理完事件之后,它的父元素、父元素的父元素也都会处理事件(从内到外)。

4.2 事件捕获流

Netscape(网景)的事件流叫做事件捕获,不太具体的节点(最外层标签)应该更早接收到事件,而最具体的节点(最内层标签)最后接收到事件(事件执行的顺序是从外到内);由于老版本浏览器不支持,因此很少有人使用事件捕获。建议大家放心地使用事件冒泡,在有特殊需要时再使用事件捕获。

DOM2级事件处理程序添加事件 element.addEventListener(type, callbackfn, boolean),第三个参数boolean是一个布尔值,默认是false,表示绑定到冒泡阶段,如果是true则表示绑定到捕获阶段。

4.3 阻止事件冒泡或事件捕获的兼容代码

if(ev.stopPropagation){//DOM推荐标准
    ev.stopPropagation()
}else{//兼容IE678
    ev.cancelBubble = true;
}

IE8及以下浏览器:对象不支持“stopPropagation”属性或方法

4.4 阻止元素默认行为的兼容性代码:

只有有默认行为的对象,才有阻止的必要性。如:页面鼠标右键事件、a标签href链接、img标签中的src请求等等…

// 兼容性写法
if (event.preventDefault) {//dom标准写法
    event.preventDefault()
} else {//兼容IE678
    event.returnValue = false;
}

// 利用return false也能阻止默认行为,没有兼容问题(只限传统注册方式DOM0级事件处理程序)

对象不支持 “preventDefault” 属性或方法

4.5 事件代理

事件代理也叫事件委托。利用事件冒泡机制,给父元素指定一个事件处理程序,就可以管理父元素及其后代元素某一类型的所有事件;如:子元素要触发的事件交由父元素代为触发执行。

  1. 为什么要用事件委托?

    一般来说,dom需要有事件处理程序,我们都会直接给它设事件处理程序就好了,那如果是很多的dom需要添加事件处理呢?比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,那这么做会存在什么影响呢?

    • 操作DOM次数过多,造成浏览器的重排和重绘就越多;
      在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

    • 每个事件都是一个对象,事件处理程序越多,占用的内存越多,影响前端性能;每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了(内存不够用,是硬伤,哈哈)比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢,那只能说呵呵了,如果用事件委托,那么我们就可以只对它的父级(如果只有一个父级)这一个对象进行操作,这样我们就需要一个内存空间就够了,是不是省了很多,自然性能就会更好。

  2. 事件委托(事件代理)原理

    对“事件处理程序过多”问题的解决方案就是事件委托,事件委托利用事件冒泡(从最深的节点开始,然后逐步向上传播事件)只在他们的父素上指定一个事件处理程序,就可以管理某一类型的的所有事件。这就是事件委托,委托它们父级代为执行事件。

  3. 事件委托的实现:查找事件源,IE和DOM事件处理程序获取方式如下:

    • DOM中的事件对象:事件对象.target 获取事件目标(事件源)

    • IE中的事件对象: 事件对象.srcElement 获取事件目标(事件源)

    • 获取事件目标兼容性写法:

      element["on"+事件类型] = function(e){
          var ev = e || event;
          //获取目标对象
          //支持DOM事件的浏览器使用target来获取事件目标
          //IE8及以前版本浏览器通过srcElement来获取事件目标
          var target = ev.target || ev.srcElement; 
      }
      
  4. 事件委托的使用场景

    • 为DOM中的很多元素绑定相同事件;

    • 为DOM中尚不存在的元素绑定事件。

  5. 事件委托的优点

    • 适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress
    • 减少DOM操作:减少浏览器的重绘(repaint)和重排(reflow),从而提高性能;
    • 减少内存空间的占用率,因为每一个函数都是一个对象,对象越多,内存占有率就越大,自然性能就越差,使用事件委托,只需要在其父元素中定义一个事件就可以。

五、鼠标滚轮事件

代码:

// 鼠标滚轮事件   
// onmousewheel  谷歌和IE8以上支持的鼠标滚轮事件;火狐浏览器不支持onmousewheel形式,无响应
// window.onmousewheel = function(e){
//     var ev = e || event;
//     console.log(ev);//WheelEvent {isTrusted: true, deltaX: -0, deltaY: 100, deltaZ: 0, deltaMode: 0, …}
//     console.log(ev.type);//mousewheel
// }

// DOMMouseScroll  只能使用DOM2级事件处理程序;火狐浏览器可以正常使用;谷歌和IE8以上不支持,无响应
// window.addEventListener("DOMMouseScroll",function(e){
//     console.log(e)
// })

// 鼠标滚轮事件的兼容性代码
window.onmousewheel = wheelHandler;
window.addEventListener('DOMMouseScroll', wheelHandler);
function wheelHandler(e) { //事件对象传参是DOM标准推荐的方式
    console.log(e)
}

注:鼠标滚轮事件的属性文章来源地址https://www.toymoban.com/news/detail-637906.html

  1. 谷歌浏览器:属性 deltaY 垂直方向滚动的距离,滚轮向下滚动,每次滚动的距离是 100px,向上滚动,每次滚动的距离是 -100px。它是固定的值。
  2. 谷歌浏览器、IE8以上浏览器,属性 wheelDelta 固定值 120,向下是负值 -120,向上是正值 +120
  3. 火狐浏览器:属性 detail 固定值 3,向上是负值 -3 ,向下是正值 +3

到了这里,关于【JS交互篇】事件和元素操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端 JavaScript 与 HTML 怎么实现交互?

    前端的交互性是通过JavaScript与HTML结合实现的。JavaScript作为一种脚本语言,可以嵌入HTML中,通过对DOM(文档对象模型)的操作,实现与用户的交互。以下将详细介绍前端JavaScript与HTML如何实现交互,包括事件处理、DOM操作、表单交互等方面的内容。 事件是指用户在页面上的动

    2024年01月22日
    浏览(38)
  • js的鼠标事件(JavaScript的鼠标事件,vue的鼠标事件)

    js鼠标事件,相关属性: vue鼠标事件,相关属性 (js鼠标事件和vue中的鼠标事件区别是省略了on字符):

    2024年02月12日
    浏览(40)
  • web前端javascript笔记——(13)事件(1)

    鼠标/键盘属性 altKey               返回当事件被触发时,“ALT”是否被按下。 button               返回当事件被触发时,哪个鼠标按钮被点击 clientX               返回当事件被触发时,鼠标指针的水平坐标。 clientY               返回当事件被触

    2024年01月25日
    浏览(42)
  • 【前端|Javascript第4篇】详解Javascript的事件模型:小白也能轻松搞懂!

    前言 在当今数字时代,前端技术正日益成为塑造用户体验的关键。而其中一个不可或缺的核心概念就是 JavaScript的事件模型 。或许你是刚踏入前端领域的小白,或者是希望深入了解事件模型的开发者,不论你的经验如何,本篇博客都将带你揭开事件模型的神秘面纱。 🚀 作者

    2024年02月13日
    浏览(36)
  • 前端基础自学整理|HTML + JavaScript + DOM事件

    目录 一、HTML 1、Html标签 2、Html元素 3、基本的HTML标签 二、CSS 样式 层叠样式表 三、JavaScript 使用示例 四、HTML DOM  通过可编程的对象模型,javaScript可以: window document 1、查找HTML元素 2、操作HTML元素 获取元素的属性 四、HTML DOM事件 ⚠️是DOM提供的API Html是用来描述网页的一

    2024年02月22日
    浏览(39)
  • 前后端交互系统:在Node.js中运行JavaScript

    在Node.js中运行JavaScript,您需要编写适用于服务器端的代码,而不是浏览器端的代码。以下是一些示例代码,用于在Node.js中创建一个简单的HTTP服务器并在浏览器中访问它: 将上述代码保存到一个名为main.js的文件中,然后在命令行中运行 node .main.js。这将创建一个简单的HTT

    2024年02月08日
    浏览(33)
  • JavaScript离别之作——HTML元素操作

    📜个人简介 ⭐️ 个人主页: 微风洋洋 🙋‍♂️ 🍑 博客领域:编程基础,后端 🍅 写作风格: 干货,干货,还是tmd的干货 🌸 精选专栏 : 【JavaScript】 🚀 支持洋锅: 点赞👍、收藏⭐、留言💬 好久不见,甚是想念! 大家好! 我是微风洋洋 今天这篇文章就是JavaScript的最后

    2024年02月02日
    浏览(24)
  • 【JavaScript】1.4 事件和DOM操作

    在这一节中,我们将讨论JavaScript的两个重要概念:事件和DOM操作。我们将通过实例和代码示例来详细解释这些概念。 JavaScript中的事件和DOM操作是前端开发中不可或缺的重要组成部分,它们为网页提供了丰富的交互性和动态性。事件驱动是JavaScript编程的核心思想之一,通过事

    2024年02月04日
    浏览(30)
  • 19个Web前端交互式3D JavaScript框架和库

    JavaScript (JS) 是一种轻量级的解释(或即时编译)编程语言,是世界上最流行的编程语言。JavaScript 是一种基于原型的多范式、单线程的动态语言,支持面向对象、命令式和声明式(例如函数式编程)风格。JavaScript 几乎可以做任何事情,更可以在包括物联网在内的多个平台

    2024年02月22日
    浏览(33)
  • JS中常用的的选择器,JavaScript获取HTML标签元素

    getElementById是JavaScript中的一个DOM方法,用于根据元素的id属性获取HTML文档中的元素。该方法接受一个字符串参数,即元素的id属性值,并返回具有该id属性值的元素。如果没有找到匹配的元素,则返回null。 以下是一个示例,演示如何使用getElementById获取页面中的元素: 在这个

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包