阻止默认行为和超链接

在浏览器上运行网页后,右击会弹出菜单,这属于浏览器的默认行为。如何禁止这一默认行为:

<script>window.onload = function () {document.oncontextmenu = function () {return false}}
</script>

对于a链接,如果点击a链接后,会默认直接进行跳转,如何组织这一默认行为,在点击a连接后,想用户进行询问之后,在进行是否跳转。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_a = $("baidu");tag_a.onclick = function () {return confirm("Quit?");   // confirm会返回true和false};}</script>
</head>
<body><a id="baidu" href="https://ww.baidu.com" target="_blank">百度</a>
</body>
</html>

另一种方法,阻止超链接默认行为的方法,由系统提供的属性和方法实现:

1. preventDefault();      W3C, 阻止默认行为

2. window.event.returnValue = false;    // IE浏览器,阻止默认行为

在实际应用中,需要自定义个能兼容不同浏览器的版本:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_a = $("baidu");tag_a.onclick = function (ev) {let e = ev || window.event;preventDefaultAction(e);alert("后续操作");};};// 跨浏览器阻止默认行为function preventDefaultAction(e) {if(e.preventDefault){e.preventDefault();}else{window.event.returnValue = false;}}</script>
</head>
<body><a id="baidu" href="https://ww.baidu.com" target="_blank">百度</a>
</body>
</html>

拖拽实现:

1. mousedown

记录鼠标按下时鼠标相对于被拖拽的物体的位置:

offsetX =  e.clientX - offsetX

offsetY = e.clientY - offsetY

2. mousemove

在鼠标一定的过程中,需要一致保持被拖拽物体与鼠标的相对距离

3. mouseup

取消拖拽

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_div = $("box");let absolute_x = 0;let absolute_y = 0;let current_x = 0;let current_y = 0;tag_div.onmousedown = function (ev) {let e = ev || window.event;absolute_x = e.clientX - tag_div.offsetLeft;absolute_y = e.clientY - tag_div.offsetTop;// 绑定鼠标移动事件 document上document.onmousemove = function (ev) {let e = ev || window.event;current_x = e.clientX;current_y = e.clientY;tag_div.style.left = current_x - absolute_x + "px";tag_div.style.top = current_y - absolute_y + "px";}};window.onmouseup = function () {document.onmousemove = null;};}</script><style>#box{width: 200px;height: 100px;border: 1px solid black;background: #ffcf3f;position: absolute;}</style>
</head>
<body><div id="box"></div>
</body>
</html>

对拖拽的改进,使得被推拽的物体不能超过屏幕的范围:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_div = $("box");let absolute_x = 0;let absolute_y = 0;let current_x = 0;let current_y = 0;tag_div.onmousedown = function (ev) {let e = ev || window.event;absolute_x = e.clientX - tag_div.offsetLeft;absolute_y = e.clientY - tag_div.offsetTop;// 获取窗口的大小let window_width = document.documentElement.clientWidth || document.body.clientWidth;let window_height = document.documentElement.clientHeight || document.body// 绑定鼠标移动事件 document上document.onmousemove = function (ev) {let e = ev || window.event;current_x = e.clientX;current_y = e.clientY;let adjust_x = current_x - absolute_x;let adjust_y = current_y - absolute_y;if(adjust_x < 0){adjust_x = 0;}if(adjust_x >= window_width - tag_div.offsetWidth){adjust_x = window_width - tag_div.offsetWidth;}if(adjust_y < 0){adjust_y = 0;}if(adjust_y >= window_height - tag_div.offsetHeight){adjust_y = window_height - tag_div.offsetHeight;}tag_div.style.left = adjust_x + "px";tag_div.style.top = adjust_y + "px";};};window.onmouseup = function () {document.onmousemove = null;}}</script><style>#box{width: 200px;height: 100px;border: 1px solid black;background: #ffcf3f;position: absolute;}</style>
</head>
<body><div id="box"></div>
</body>
</html>

可以对上述的实现拖拽代码进行封装,成为一个独立的函数,放到too.js中可供使用

事件委托:

例如,对于如下的结构:

<body><ul id="list"><li>11</li><li>22</li><li>33</li><li>44</li></ul>
</body>

需要给<li>标签添加相同的点击事件,按照之前的做法,是先获得所有的<li>标签,再通过循环为每一个<li>标签添加点击事件。如果需要在添加一个按钮,每次点击按钮后,都需要新增一个<li>标签,则新增的<li>标签是没有绑定点击事件的。

这样做的缺点是:

1. for循环添加相同的事件函数,浪费资源

2. 不能解决新增的节点事件绑定问题

解决方法:事件委托

A委托---->B代理,B执行动作,A受益

1. 找到当前节点的父节点或者祖先节点

2. 将事件添加到父节点或者祖先节点

3. 找到触发对象,判断触发对象是否满足条件,如果是执行后续操作

所以可以通过上述的操作,实现<li>标签委托<ul>,此时只需要为<ul>标签添加事件函数,同时新增的<li>节点也可以响应点击事件,这个事件是<li>委托给ul的。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let btn = $("add");let tag_ul = $("list");   // 找到li的父节点tag_ul.onclick = function (ev) {let e = ev || window.event;let target_e = e.target || window.event.srcElement;  // 获取事件对象if(target_e.nodeName.toLowerCase() === "li")   // 判断触发对象是否满足条件{target_e.style.background = "red";}};let cnt = 1;    // 增加新节点btn.onclick = function () {let newLi = document.createElement("li");newLi.innerHTML = (cnt++ * 1111).toString();tag_ul.appendChild(newLi);}}</script><style></style>
</head>
<body><button id="add">增加</button><ul id="list"></ul>
</body>
</html>

可以利用事件委托对前面的增加记录案例进行改进:
这样只需要添加一个点击就可以实现所有按钮绑定事件:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let input_tag = $("input_text");let bottom_section = $("bottom");$("add").onclick = function (){let input_content = input_tag.value;if(!input_content){alert("请输入内容");}else{// 开始创建节点let node = document.createElement("div");let text_node = document.createTextNode(input_content);let btn_node = document.createElement("button");let btn_text_node = document.createTextNode("x");btn_node.appendChild(btn_text_node);node.appendChild(text_node);node.appendChild(btn_node);node.style.background = randomColor();bottom_section.appendChild(node);input_tag.value = "";   // 清空输入框// updateItemsButtons();}};$("delete").onclick = function () {let last_node = bottom_section.lastChild;bottom_section.removeChild(last_node);// updateItemsButtons();};$("clone").onclick = function () {let last_node = bottom_section.lastChild;let clone_node = last_node.cloneNode(true);   // 深拷贝bottom_section.appendChild(clone_node);// updateItemsButtons();};// 事件委托bottom_section.onclick = function (ev) {let e = ev || window.event;let target = e.target || window.event.srcElement;   // 找到触发对象if(target.nodeName.toLowerCase() === "button")   // 要转换成小写{bottom_section.removeChild(target.parentNode);   // 删除当前对象的父节点}};input_tag.onkeydown = function (ev){// 给输入框添加快捷键let e = ev || window.event;let key_code = e.keyCode || e.which;   // 判断回车键if(e.ctrlKey && key_code===13){$("add").onclick();}}}</script><style>#container{width: 200px;border: 1px solid black;}#top{width: 100%;height: 30px;}#top input{height: 20px;line-height: 30px;margin: 0 auto;}#middle{width: 100%;height: 50px;border: none;display: flex;flex-direction: row;justify-content: space-around;background: #0f6674;}#middle button{/*width: 25%;*/height: 50%;align-self: center;/*margin-top: 10px;*/}#bottom{}#bottom div{height: 25px;position: relative;}#bottom div button{position: absolute;top: 1px;right: 2px;}</style>
</head>
<body><div id="container"><div id="top"><input type="text" id="input_text" placeholder="请输入内容"></div><div id="middle"><button id="add">添加</button><button id="delete">删除</button><button id="clone">克隆</button></div><div id="bottom"><!--<div>content<button>x</button></div>--></div></div>
</body>
</html>

事件监听器:

传统的事件绑定,需要先获取到相应的节点,再去绑定事件,但是在一些场景中,这种传统的方法不能够满足需求:
1. 例如,对一个按钮重复绑定同一个是按,当事件被触发的时候,前面的事件会被后面的事件覆盖

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let btn = $("add");btn.onclick = function () {alert("点击1");};btn.onclick = function () {alert("点击2");};}</script><style></style>
</head>
<body><button id="add">增加</button>
</body>
</html>

当点击按钮后只能出现"点击2","点击1"会被覆盖掉。

而事件监听器是另一种绑定事件的方式,addEventListener()用于向指定元素添加事件句柄,IE8以下不支持,火狐和谷歌支持/

removeEventListener()删除事件监听器。

addEventListener("click", functionName, bool):

第一个参数表示需要监听的操作,例如click

第二个参数表示绑定的事件函数,函数名或者匿名函数

第三个参数表示 true: 事件捕获,false事件冒泡, 默认/    事件捕获:与事件冒泡案例中的顺序正好相反。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let btn = $("add");btn.addEventListener("click", function () {alert("点击1");}, false);btn.addEventListener("click", function () {alert("点击2");}, false);}</script><style></style>
</head>
<body><button id="add">增加</button>
</body>
</html>

而利用事件监听器就可以执行所有绑定的事件。利用事件监听器,可以给标签绑定多个事件函数,同时,也能够精确的去删除标签上绑定的某一个事件函数,但是传统事件绑定方法,一是会后绑定的事件函数会覆盖掉前面的事件函数,在一个是,如果需要删除事件函数,则会将所有的事件函数都删除。(node.onclick = null)

低版本浏览器需要兼容事件监听器:

1. attachEvent()

2. detachEvent()

function addEvent(node, eventType, funcName) {if (node.addEventListener)   // 判断是否支持{node.addEventListener(eventType, funcName, false);}else {node.attachEvent("on" + eventType, funcName);}
}function removeEvent(node, eventType, funcName) {if(node.removeEventListener){node.removeEventListener(eventType, funcName);}else{node.detachEvent("on" + eventType, funcName);}
}

案例:动态生成表格

输入表格的行数和列数,自动生成表格:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let btn = $("gen");let row = $("row");let col = $("col");let table = $("t1");btn.onclick = function () {let row_num = row.value;let col_num = col.value;if(!row_num || !col_num){alert("请输入完整的行列");}else{let row_max = parseInt(row_num);let col_max = parseInt(col_num);if (isNaN(row_max) || isNaN(col_max))   //行列必须是数字{alert("行列必须是数字");}else{for(let row_cnt=0; row_cnt<row_max; row_cnt++){// 控制行数let tr = document.createElement("tr");  // 创建行for (let col_cnt=0; col_cnt<col_max; col_cnt++){let td = document.createElement("td");tr.appendChild(td);}let td_del = document.createElement("td");td_del.innerHTML = "<button>删除</button>";tr.appendChild(td_del);table.appendChild(tr);}}}};table.onclick = function (ev) {let e = ev || window.event;let target = e.target || window.event.srcElement;if(target.nodeName.toLowerCase() === "button"){table.removeChild(target.parentNode.parentNode);}};}</script><style>#t1 tr td{width: 100px;height: 30px;border: 1px solid black;}#t1 tr td:last-child button{display: block;margin: 0 auto;}#t1{border: 1px solid black;border-collapse: collapse;margin-top: 10px;}</style>
</head>
<body><input type="text" placeholder="行数" id="row"><input type="text" placeholder="列数" id="col"><button id="gen">生成</button><table id="t1"></table>
</body>
</html>

效果如下图所示:

案例:放大镜

在图片中,随着鼠标的移动,图片的局部区域会在另一个地方被放大一定的倍数:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_mark = $("mark");let tag_sourcePic = $("source-pic");let tag_largePic = $("large-pic");let tag_img = tag_largePic.getElementsByTagName("img")[0];tag_sourcePic.onmouseover = function () {tag_mark.style.display = "block";};tag_sourcePic.onmouseout = function () {tag_mark.style.display = "none";};tag_sourcePic.onmousemove = function (ev) {let e = ev || window.event;let temp_x = e.clientX - tag_sourcePic.offsetLeft -tag_mark.offsetWidth /2;let temp_y = e.clientY - tag_sourcePic.offsetTop - tag_mark.offsetHeight/2;if (temp_x < 0){temp_x = 0;}if (temp_x > tag_sourcePic.offsetWidth - tag_mark.offsetWidth){temp_x = tag_sourcePic.offsetWidth - tag_mark.offsetWidth;}if (temp_y < 0){temp_y = 0;}if (temp_y > tag_sourcePic.offsetHeight - tag_mark.offsetHeight){temp_y = tag_sourcePic.offsetHeight - tag_mark.offsetHeight;}tag_mark.style.left = temp_x + "px";tag_mark.style.top = temp_y + "px";// 放大效果tag_img.style.left = temp_x * -3.2 +"px";tag_img.style.top = temp_y * -3.2 + "px";}}</script><style>*{margin: 0;padding: 0;}#source-pic{width: 336px;height: 200px;position: absolute;left: 20px;top: 25px;}#source-pic img{display: block;width: 100%;height: 100%;}#source-pic #mark{width: 50px;height: 50px;opacity: 0.5;background: white;position: absolute;left: 0;top: 0;display: none;}#large-pic{width: 200px;height: 200px;border: 1px solid black;position: absolute;left: 20px;top: 250px;overflow: hidden;}#large-pic img{position: absolute;left: 0;top: 0;}</style>
</head>
<body><div id="source-pic"><img src="../picture/others/timg1.jpg" alt=""><div id="mark"></div></div><div id="large-pic"><img src="../picture/others/timg1.jpg" alt=""></div>
</body>
</html>

Web前端JavaScript笔记(5)事件-拖拽相关推荐

  1. Web前端JavaScript笔记(4)节点

    如何获取元素节点的属性: 在Web前端JavaScript笔记(3)对象中,介绍了访问行间属性的方法,除此之外,系统还提供了三个方法访问元素的属性: 1. setAttribute: 2. getAt ...

  2. Web前端Javascript笔记(5)事件

    1. 什么是事件:事件是指发生并得到处理的操作 JavaScript中的事件是由访问web页面的用户引起的一系列操作,例如,用户的点击操作,JavaScript中有两种事件模型:内联模型,脚本模型. ...

  3. Web前端Javascript笔记(6)正则表达式

    在web前端中,假设用户需要提交表单,在表单提交到服务器进一步处理之前,Javascript程序会检查表单,以确认用户输入的信息是符合规范要求的.这些工作可以使用正则表达式完成,正则表达式是一个描述字 ...

  4. Web前端Javascript笔记(8)Ajax前后端交互

    认识Ajax 全名Asynchronous Javascript and XML(异步JavaScript和XML),节省用户操作时间,提高用户体验,减少数据请求,传输获取数据.Ajax相当于前后台数 ...

  5. Web前端 Javascript笔记(1)数组

    结构 :html构建 样式:css控制 行为:JavaScript实现 什么是JavaScript? JavaScript是一种跨平台的脚本语言,平台,即运行环境,一般指操作系统. --------- ...

  6. Web前端JavaScript笔记(3)对象

    在JavaScript中没有类这个概念,只有对象,在新ECMA6新版中增加了类的概念,和数组,字符串类似,对象的声明方法也有三种: 1. 通过new运算符进行传件对象 2. 省略new运算符创建对象 ...

  7. Web前端JavaScript笔记(7)ECMA6新增数组方法

    新增数组方法: 1. Array.from():  将伪数组转化为真数组 <script>window.onload = function () {let tag_li = documen ...

  8. Web前端JavaScript笔记(2)字符串

    字符串: 字符串的声明方式: 1.  通过new运算符声明字符串         // 声明的是对象 2. 省略new运算符 3. 字符串常量赋值 <script>var str1 = n ...

  9. web前端学习笔记(最新)

    web前端学习笔记 大家好,我是链表哥,新的学期,新的学习,我会为您展示我的学习进程. 一:什么是WEB前端? 所谓的Web前端指的是用户所能接触到的,并服务于用户的前沿端口,经我们程序员编辑修饰后展 ...

最新文章

  1. this class is not key value coding-compliant for the key ##
  2. Spring Boot实战pdf
  3. 计算机视觉与模式识别方面的代码code
  4. 库的标准实现和私有实现的选择
  5. 撬锁锤怎么用_安全锤是啥?消防蜀黍教你怎么选?如何快速破拆逃生?
  6. 计算机基础知识:什么是位、字节、字、KB、MB
  7. 电脑开机3秒就重启循环_电脑修好后客户不愿支付上门费,行,那电脑开机60秒自动关机吧!...
  8. Linux故障解决(2)——使用yum安装netcat 及报错问题解决
  9. 基于百度tts-实现文字转语音,支持下载,在线预览
  10. 最新EyouCMS发布工具
  11. Android隐藏状态栏实现沉浸式体验
  12. 7-5 jmu-Java-03面向对象基础-05-覆盖 (20 分)
  13. 各种群体寻优算法的比较
  14. 全链路前端性能优化方案
  15. CVPR 二十年,影响力最大的 10 篇论文
  16. jquery创建html标签并添加样式
  17. 深度学习电脑硬件配置
  18. 用一个小故事告诉你什么叫做大数据
  19. CSS+html:天涯网页仿照制作
  20. 无法验证到服务器的安全证书,打开outlook提示…无法验证的安全证书……

热门文章

  1. ASP.Net学习笔记007--ASP.Net Input版自增
  2. 【C#编程基础学习笔记】4---Convert类型转换
  3. 论文阅读:FaceBoxes: ACPUReal-timeFaceDetectorwithHighAccuracy
  4. linux 下小技巧之-统计文件夹下面子文件夹下面的个数
  5. 经典线程同步总结 关键段 事件 互斥量 信号量
  6. 杭电4535吉哥系列故事——礼尚往来
  7. 有必要月底Linux内核,如何确定linux内核是否会在月底插入闰秒
  8. mysql的数据备份问题_mysql数据库备份的问题
  9. python super 多重继承_解决python super()调用多重继承函数的问题
  10. win32开发(文件、字体和色彩)