Dom多个事件绑定addEventListener、鼠标事件、拖拽元素

1 Dom多个事件绑定addEventListener():

addEventListener()

- 也可以通过addEventListener()来为元素绑定事件

addEventListener(type, listener [, useCapture])

- 参数:

type 要监听的事件的字符串,注意这里不需要写on

listener 回调函数,当事件发生后调用的函数

useCapture 布尔值,是否在捕获阶段触发事件,一般都是false

通过addEventListener()可以为一个元素的一个事件绑定多个响应函数,

这样当事件被触发时,响应函数会按照事件的绑定顺序依次执行

该方法不支持IE8及以下的浏览器

通过addachEvent()可以为一个元素的相同事件绑定多个响应函数 该方法支持IE8以下的浏览器—两个参数addachEvent (on事件,回调函数)

不同的是—先绑定的后执行,后绑定的先执行!

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>事件的绑定</title>

<script>

window.onload = function () {

var btn01 = document.getElementById('btn01');

// 通过 对象.属性 的形式绑定响应函数时,同时只能为一个事件绑定一个响应函数

// btn01.onclick = function () {

// alert(1);

// };

//

btn01.onclick = function () {

alert(2);

};

btn01.onclick = null;

/*

addEventListener()

- 也可以通过addEventListener()来为元素绑定事件

addEventListener(type, listener [, useCapture])

- 参数:

type 要监听的事件的字符串,注意这里不需要写on

listener 回调函数,当事件发生后调用的函数

useCapture 布尔值,是否在捕获阶段触发事件,一般都是false

通过addEventListener()可以为一个元素的一个事件绑定多个响应函数,

这样当事件被触发时,响应函数会按照事件的绑定顺序依次执行

该方法不支持IE8及以下的浏览器

通过addachEvent()可以为一个元素的相同事件绑定多个响应函数 该方法支持IE8以下的浏览器—两个参数addachEvent (on事件,回调函数)

不同的是—先绑定的后执行,后绑定的先执行!

*/

// btn01.addEventListener("click",function () {

// alert(1);

// }, false)

//

// btn01.addEventListener("click",function () {

// alert(2);

// }, false)

//

// btn01.addEventListener("click",function () {

// alert(3);

// }, false)

// btn01.removeEventListener()

/*

removeEventListener(type, listener[, useCapture]);

- 用来移除元素上的事件监听器

*/

function fn() {

alert(123);

}

btn01.addEventListener('click',fn, false);

btn01.removeEventListener('click', fn, false);

};

</script>

</head>

<body>

<button id="btn01">点我一下</button>

</body>

</html>

2DOM事件的捕获:

关于事件的传播方向当时两大巨头网景和微软有着不同的理解:

网景公司认为事件应该由外向内传递,

事件发生时,应该先从外层元素上的事件,然后向内一层一层传递

这一事件的传播机制,称为 事件的捕获

微软公司认为事件应该由内向外传递

事件发生时,应该先从内层元素(触发事件的元素)开始,然后一层一层传递

这一事件的传播机制,称为 事件的冒泡

于是W3C将事件整个分为了三个阶段:

1.捕获阶段

- 事件发生后首先从外层元素向内层元素进行事件的捕获

- 默认情况下此阶段并不会触发事件

通常在捕获阶段不想触发事件--可以将addEventListener()的第三个参数设置为false

- 如果希望在捕获阶段触发事件,可以将addEventListener()的第三个参数设置为true

2.目标阶段

- 捕获到达触发事件的元素,捕获终止

3.冒泡阶段

- 从触发事件的元素开始,向外层进行事件的冒泡,并触发事件

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

#box1{

width: 300px;

height: 300px;

background-color: #bfa;

}

#box2{

width: 150px;

height: 150px;

background-color: #ff0;

}

#box3{

width: 50px;

height: 50px;

background-color: orange;

}

</style>

<script>

window.onload = function () {

/*

关于事件的传播方向当时两大巨头网景和微软有着不同的理解:

网景公司认为事件应该由外向内传递,

事件发生时,应该先从外层元素上的事件,然后向内一层一层传递

这一事件的传播机制,称为 事件的捕获

微软公司认为事件应该由内向外传递

事件发生时,应该先从内层元素(触发事件的元素)开始,然后一层一层传递

这一事件的传播机制,称为 事件的冒泡

于是W3C将事件整个分为了三个阶段:

1.捕获阶段

- 事件发生后首先从外层元素向内层元素进行事件的捕获

- 默认情况下此阶段并不会触发事件

通常在捕获阶段不想触发事件--可以将addEventListener()的第三个参数设置为false

- 如果希望在捕获阶段触发事件,可以将addEventListener()的第三个参数设置为true

2.目标阶段

- 捕获到达触发事件的元素,捕获终止

3.冒泡阶段

- 从触发事件的元素开始,向外层进行事件的冒泡,并触发事件

*/

//分别为三个元素绑定单击响应函数

var box1 = document.getElementById('box1');

var box2 = document.getElementById('box2');

var box3 = document.getElementById('box3');

box1.addEventListener('click',function () {

alert(1);

}, true); //传false 就不会在捕获阶段触发

box2.addEventListener('click',function () {

alert(2);

}, true);

box3.addEventListener('click',function () {

alert(3);

}, true);

};

</script>

</head>

<body>

<div id="box1">

<div id="box2">

<div id="box3"></div>

</div>

</div>

</body>

</html>

3鼠标拖拽div案例:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

#box1{

width: 100px;

height: 100px;

background-color: #f00;

position: absolute;

}

#box2{

width: 100px;

height: 100px;

background-color: orange;

}

#box3{

width: 100px;

height: 100px;

background-color: yellow;

}

#box4{

width: 100px;

height: 100px;

background-color: tomato;

}

.drag{

position: absolute;

}

</style>

<script>

window.onload = function () {

//获取box1对象

var box1 = document.getElementById('box1');

// 创建一个变量,记录拖拽的状态

//var isDrag = false; // 默认拖拽没有开始

var left, top;

// 创建一个变量,记录被拖拽的对象

var dragEle = null;

//为box1绑定鼠标按下的事件

document.addEventListener('mousedown',function (ev) {

// alert(ev.button);

// button用来表示鼠标的按钮 0表示左键 1表示滚轮按下 2表示右键

// 判断元素是否是拖拽元素

if(ev.target.classLisr.contains('drag') === 'drag' && ev.button === 0){

// 开始拖拽 将isDrag设置为true

// isDrag = true;

// 将ev.target 赋值给dragEle

dragEle = ev.target;

// 取消默认行为

ev.preventDefault();

// 获取鼠标和元素的距离

left = ev.offsetX;

top = ev.offsetY;

}

}, false);

// 开始拖拽 , 为document绑定一个鼠标移动的事件

document.addEventListener('mousemove',function (ev) {

if(dragEle){

dragEle.style.left = ev.clientX - left +'px';

dragEle.style.top = ev.clientY - top + 'px';

}

}, false);

//设置onmouseup来停止拖拽

document.addEventListener('mouseup', function (ev) {

// 将 isDrag 设置为false,停止拖拽

// isDrag = false;

dragEle = null;

});

};

</script>

</head>

<body>

<div id="box1" class=""></div>

<div id="box2" class="drag"></div>

<div id="box3" class="drag"></div>

<div id="box4" class="drag"></div>

<img src="an.jpg" class="drag">

</body>

</html>

4.js读取元素的class属性:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

.box1{

width: 100px;

height: 100px;

background-color: #bfa;

}

.hello{

width: 200px;

height: 200px;

background-color: #ff0;

}

</style>

<script>

window.onload = function () {

var box1 = document.querySelector('.box1');

// 使用className获取的元素的class值,就是原本的class值

// 例如:box1.className 是这样的 box1 box2 box3 box4

// classList 是一个类数组对象,在它里边将元素的每一个class属性都设置为了数组中的一个元素

/*

自己实现一组类相关的方法,要求兼容IE8以上的浏览器

classList只支持IE10以上的浏览器

contains() 用来检查classList是否含有某个类,如果有返回true,没有返回false

add() 用来向元素中添加一个或多个class

remove() 移除元素中的一个或多个class

replace() 使用一个新的class替换元素中的class

toggle() 切换元素中的指定class,如果有则删除,如果没有则添加

*/

var btn01 = document.getElementById('btn01');

btn01.addEventListener('click',function () {

// alert(box1.classList.contains('hello'));

// box1.classList.add('hello');

// box1.classList.remove('box1');

// box1.classList.replace('box1', 'hello');

box1.classList.toggle('hello');

},false)

};

</script>

</head>

<body>

<button id="btn01">点我一下</button>

<div class="box1 box2 box3 box4"></div>

</body>

</html>

5鼠标右键的事件contextmenu:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>鼠标事件</title>

<style>

*{

margin: 0;

padding: 0;

}

.menu{

width: 200px;

position: absolute;

background-color: #bfa;

list-style: none;

display: none;

}

.menu li:hover{

background-color: #ff0;

}

</style>

<script>

//contextmenu 表示右键菜单的事件

document.addEventListener("contextmenu",function (ev) {

// 如果取消了contextmenu的默认行为,将会导致右键菜单不会出现

ev.preventDefault();

// 将菜单显示出来

var menu = document.querySelector('.menu');

menu.style.display = 'block';

menu.style.left = ev.clientX + 'px';

menu.style.top = ev.clientY + 'px';

},false);

document.addEventListener('click',function () {

var menu = document.querySelector('.menu');

menu.style.display = 'none';

},false)

</script>

</head>

<body>

<ul class="menu">

<li>菜单一</li>

<li>菜单二</li>

<li>菜单三</li>

<li>菜单四</li>

<li>菜单五</li>

<li>菜单六</li>

<li>菜单七</li>

</ul>

</body>

</html>

6鼠标滚轮的事件wheel:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

#box1{

width: 100px;

height: 100px;

background-color: #f00;

}

</style>

<script>

window.onload = function () {

/*

box1可以根据鼠标滚轮滚动的方向变长或变短

*/

// 获取box1

var box1 = document.getElementById('box1');

box1.addEventListener('wheel',function (ev) {

// alert(ev);

//wheel 事件会在鼠标滚轮滚动的时候触发

// deltaX 获取鼠标滚轮横向滚动方向

// 向左拨-3 向右拨3

// 左-100 右100(Chrome)

// deltaY 获取鼠标滚轮纵向滚动方向

// 上-3 下3

// 上-100 下100

// 如果滚轮向下滚,box1变长

if(ev.deltaY > 0){

box1.style.height = box1.clientHeight + 10 + 'px';

}else{

// 如果滚轮向上滚,box1变短

box1.style.height = box1.clientHeight - 10 + 'px';

}

},false)

};

</script>

</head>

<body>

<div id="box1"></div>

</body>

</html>

7 class属性更改替换(兼容IE8):

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

.box1{

width: 100px;

height: 100px;

background-color: #bfa;

margin-top: 50px;

}

.yellow{

width: 200px;

height: 200px;

background-color: #ff0;

}

</style>

<script>

window.onload = function () {

var btn = document.getElementById('btn');

var box1 = document.querySelector('.box1');

btn.addEventListener('click',function () {

replaceClass(box1, 'yellowgreen', 'yellow');

// alert(hasClass(box1,'box1'));

// toggleClass(box1, 'yellow');

// addClass(box1, 'yellow');

// 修改box1的样式

// box1.style.width = '300px';

// box1.style.height = '300px';

// box1.style.backgroundColor = 'yellowgreen';

// 检查className中是否含有yellow,然后在添加

// var re = new RegExp("\\byellow\\b")

// if(!re.test(box1.className)){

// // 将box1的class属性修改为yellow

// box1.className += ' '+'yellow';

// }

// /\byellow\b/

// var reg = /\byellow\b/;

// 使用构造函数创建一个正则

// reg = new RegExp("\\byellow\\b"); // /\byellow\b/

// alert(reg);

},false)

};

//定义一个函数,用来为任意的元素添加class

// ele 表示要添加样式的元素

// className 表示要添加的class

function addClass(ele, className) {

if(!hasClass(ele,className)){

// 将box1的class属性修改为yellow

ele.className += ' '+className;

}

}

// 定义一个函数用来检查类中是否含有某个class

function hasClass(ele, className) {

var re = new RegExp("\\b"+className+"\\b");

return re.test(ele.className);

}

// 删除元素的指定类

function removeClass(ele, className) {

// 根据className创建一个正则表达式

var re = new RegExp('\\s*\\b'+className+'\\b');

// 将ele.className中符合正则表达式的内容,替换为空串

ele.className = ele.className.replace(re, '');

}

// 切换class,如果元素中具有该class则删除,如果没有则添加

function toggleClass(ele, className) {

// 检查元素中是否含有该class

if(hasClass(ele, className)){

removeClass(ele, className);

}else{

addClass(ele, className);

}

}

// 替换元素class属性

function replaceClass(ele, oldCls, newCls) {

// 根据oldCls创建一个正则表达式

var re = new RegExp('\\b'+oldCls+'\\b');

// 将ele.className中符合re的内容替换为newCls

ele.className = ele.className.replace(re, newCls);

}

</script>

</head>

<body>

<button id="btn">点我一下</button>

<div class="box1 yellowgreen"></div>

</body>

</html>

欢迎关注我的原创文章:小伙伴们!我是一名热衷于前端开发的作者,致力于分享我的知识和经验,帮助其他学习前端的小伙伴们。在我的文章中,你将会找到大量关于前端开发的精彩内容。

学习前端技术是现代互联网时代中非常重要的一项技能。无论你是想成为一名专业的前端工程师,还是仅仅对前端开发感兴趣,我的文章将能为你提供宝贵的指导和知识。

在我的文章中,你将会学到如何使用HTML、CSS和JavaScript创建精美的网页。我将深入讲解每个语言的基础知识,并提供一些实用技巧和最佳实践。无论你是初学者还是有一定经验的开发者,我的文章都能够满足你的学习需求。

此外,我还会分享一些关于前端开发的最新动态和行业趋势。互联网技术在不断发展,新的框架和工具层出不穷。通过我的文章,你将会了解到最新的前端技术趋势,并了解如何应对这些变化。

我深知学习前端不易,因此我将尽力以简洁明了的方式解释复杂的概念,并提供一些易于理解的实例和案例。我希望我的文章能够帮助你更快地理解前端开发,并提升你的技能。

如果你想了解更多关于前端开发的内容,不妨关注我的原创文章。我会不定期更新,为你带来最新的前端技术和知识。感谢你的关注和支持,我们一起探讨交流技术共同进步,期待与你一同探索前端开发的奇妙世界!

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是完整的 class 类代码实现: ```javascript class DragAndDrop { constructor(leftContainer, rightContainer) { this.leftContainer = leftContainer; this.rightContainer = rightContainer; this.draggedItem = null; this.draggedOverItem = null; this.draggedOverContainer = null; // 绑定拖拽事件 this.bindDragEvents(); } bindDragEvents() { // 绑定左侧容器的拖拽事件 this.leftContainer.addEventListener('dragstart', (event) => { this.draggedItem = event.target; event.dataTransfer.setData('text/plain', ''); // 设置数据类型 }); // 绑定右侧容器的拖拽事件 this.rightContainer.addEventListener('dragstart', (event) => { this.draggedItem = event.target; event.dataTransfer.setData('text/plain', ''); // 设置数据类型 }); // 绑定右侧容器的拖拽进入事件 this.rightContainer.addEventListener('dragenter', (event) => { event.preventDefault(); this.draggedOverContainer = event.target; this.draggedOverItem = this.getDraggedOverItem(event.clientY); // 添加移动动画 this.draggedOverItem.classList.add('dragged-over'); }); // 绑定右侧容器的拖拽移动事件 this.rightContainer.addEventListener('dragover', (event) => { event.preventDefault(); this.draggedOverItem = this.getDraggedOverItem(event.clientY); }); // 绑定右侧容器的拖拽离开事件 this.rightContainer.addEventListener('dragleave', () => { this.draggedOverItem.classList.remove('dragged-over'); }); // 绑定右侧容器的拖拽放置事件 this.rightContainer.addEventListener('drop', (event) => { event.preventDefault(); // 判断是否是拖拽的按钮 if (this.draggedItem.classList.contains('drag-handle')) { this.moveItem(); } else { this.copyItem(); } }); // 绑定右侧容器内的按钮的拖拽事件 this.rightContainer.querySelectorAll('.drag-handle').forEach((item) => { item.addEventListener('dragstart', (event) => { this.draggedItem = event.target.parentNode; event.dataTransfer.setData('text/plain', ''); // 设置数据类型 }); }); } getDraggedOverItem(y) { // 获取容器内最近的一个元素 const items = [...this.draggedOverContainer.querySelectorAll('.item:not(.dragged-item)')]; return items.reduce((closest, child) => { const box = child.getBoundingClientRect(); const offset = y - box.top - box.height / 2; if (offset < 0 && offset > closest.offset) { return { offset, element: child }; } else { return closest; } }, { offset: Number.NEGATIVE_INFINITY }).element; } moveItem() { // 移动拖拽元素到目标元素前面 this.draggedOverContainer.insertBefore(this.draggedItem, this.draggedOverItem); this.draggedOverItem.classList.remove('dragged-over'); } copyItem() { // 复制拖拽元素到目标元素前面 const newItem = this.draggedItem.cloneNode(true); this.draggedOverContainer.insertBefore(newItem, this.draggedOverItem); this.draggedOverItem.classList.remove('dragged-over'); } } ``` 在此基础上,还需要在 HTML 中添加相应的元素和一些 CSS 样式,以实现完整的拖拽排序功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值