开发者社区> 小结巴巴> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

中高级前端应该必会,js实现事件委托代理、切换样式、元素获取相对于文档位置等

简介: 1、介绍   随着组件开发大流行,现在三大框架已经基本占领了整个前端。   这时候,我们要是引入一个 jq 是不是先得你的项目非常臃肿,jq 也很不适合。   这个时候,你就需要来增加你 js 的功底。
+关注继续查看

1、介绍

  随着组件开发大流行,现在三大框架已经基本占领了整个前端。

  这时候,我们要是引入一个 jq 是不是先得你的项目非常臃肿,jq 也很不适合。

  这个时候,你就需要来增加你 js 的功底。

 

2、各种操作

  

  1、事件委托

  案例分析:

<ul id= "list">
    <li>1</li>
    <li>2</li>    
    <li>3</li>    
    <li>4</li>    
    <li>5</li>    
</ul>

  如上面的页面机构,我们需要个每一个 li 添加同一个事件。

  常规操作:

  选择出所有的 li 标签,然后为所有的标签都添加这个事件。

var liList = document.querySelectorAll('#list li')
liList.foreach(function(item,index)=>{
  item.addEventListener('click',doSomething)
})

  

  很简单,也是非常好的。

  但是当这里的 li 标签多了之后,那么你获取所有的 li 标签并绑定事件就会变慢,也就是说性能就会不好了。

  这个时候该如何处理呢?

 

  事件委托:

  解释下事件委托吧,可能新手不知道。

  就是把子元素想要绑定的事件,绑定到子元素的父元素上面。

  然后当事件触发的时候,通过事件冒泡来获取到当前事件源对应的的元素。(事件冒泡和捕获如果不知道还是需要补习下的)

  代码展示:

var liList = document.querySelectorAll('#list')
liList.addEventListener('click',function(e)=>{ 
    if(e.target && e.target.nodeName.toUpperCase == 'LI'){
    console.log('你点击了'+e.target.innerText )
  }
})

  

  给一个比较完整的例子,没有验证...

function delegate(element, eventName, name, func) {
	element.addEventListener(eventName, function (e) {
		var target = e.target, parent = target;
		while (target && parent != element) {
			if (parent.nodeName.toLowerCase() == name) {
				e.target = parent
				func.apply(parent,e);
				break;
			}
			parent = parent.parentNode;
		}
	});
}

  

  上面的例子,name 字段可以是 类命,id 的值,也可以是 标签。

  自行修改,更灵活。。

 

  总结:

  事件代理委托主要是通过给父元素绑定事件。

  通过事件的冒泡来确定当前的事件源。

  确定事件源,并执行具柄。

  

  

 

  2、es5 的元素获取、class 的操作

  

  es5 的元素获取

 

  在之前我一直都是使用的 es3 做元素获取的,如:

 

document.getElementById(id)
document.getElementsByClassName(class)

  上面的相信是大家以前最熟悉的 js 获取方法。

  但是在 es5 出来后,你会惊奇的觉得 Jquery 选择器可以被替代了

 

document.querySelector(selector)
document.querySelectorAll(selector)
// 例如
document.querySelector('.classs p')  // 获取 class 类下面的 p 标签
// 可以看到和 jquery 选择器差不多,只是功能精简了

  

  上面很清楚的可以知道:

  querySelector 是获取单个元素

  querySelectorAll 是获取多个匹配元素

  最大的变化就是 selector。

  它可以是 .className  、  #id   、也可以是多级选择  .className p

 

 

  class 类的一些 es5 操作 

 

  Dom 的 classList 属性:

<div id = "test" class = "red big hot"></div>

  

  获取样式类列表

  document.querySelector('test').classList

  这里会返回一个 TokenList 也就是是个类数组:

  

{
  0:red,
  1:big,
  2:hot,
  length:3,
  value:'red big hot'
}

  

  添加类名

  document.querySelector('test').classList.add('good','new')

  添加类 good , new 。如果类名已经存在,则不添加

 

  移除某类

  document.querySelector('test').classList.remove('good','new')  

  移除 good , new 类。移除不存在的类,会报错

 

  切换类

  document.querySelector('test').classList.toggle('good')

  切换 good 类。如果 good 存在返回true,否则false

 

  判断是否存在某类

  document.querySelector('test').classList.contains('good')

  返回 boolean 值。

 

  

  3、获取元素在父元素中第几个

 

  其实这个在现在的组件模式中很容易实现。

  但是 js 中是如是实现的呢 ?

 

 <ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

  

   获取方法及其封装:

 

function index(parent,son) {
       return [].indexOf.call(parent.children,son);
   }

  

  如上面:

  parent 是父元素,son 很显然是子元素

 

 

 

  4、元素相对于文档 / 窗口视图的位置 

 

   相对于文档的位置

  

  在 jquery 中我们实现的方法是 $(s).offset() 来回去相对于文档的位置。

  那 js 中如何实现的呢?

 

  代码:

const getDocPosition = (element) => {
    let eleCom = element;
    if (typeof element === 'string') eleCom = document.querySelector(eleCom);
    let x = eleCom.offsetLeft;
    let y = eleCom.offsetTop;
    let parent = eleCom.offsetParent;
    while (parent) {
        x += parent.offsetLeft;
        y += parent.offsetTop;
        parent = parent.offsetParent;
    }
    return {
        x,
        y,
    };
};

  

  代码很简单:

  可以看出,通过不断的获取 offsetLeft / offsetTop ,并且与它的父元素相加。

  直到相加到顶级元素为止。 

 

   

  相对于窗口视图位置

   

  getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。

 

  

 

rectObject = object.getBoundingClientRect();

  

   rectObject.top:元素上边到视窗上边的距离;

   rectObject.right:元素右边到视窗左边的距离;

   rectObject.bottom:元素下边到视窗上边的距离;

   rectObject.left:元素左边到视窗左边的距离;

 

  如果你看过 lazyImg 图片的懒加载,你们就会发现,他的实现原理就是这个。

  当它图片出现在窗口的视图中,就会加载真的图片资源。 

 

 

  后续继续添加常用的、容易忘的一些 js 功能。

 

  https://www.cnblogs.com/jiebba/p/9663268.html 

   我的博客 :  XiaoLong's Blog

   博客园小结巴巴: https://www.cnblogs.com/jiebba

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
#yyds干货盘点# 前端歌谣的刷题之路-第一百零四题-proxy代理
#yyds干货盘点# 前端歌谣的刷题之路-第一百零四题-proxy代理
0 0
挑战21天手写前端框架 day15 Proxy 代理,前端代理,开发代理
挑战21天手写前端框架 day15 Proxy 代理,前端代理,开发代理
0 0
前端培训-初级阶段-场景实战(2019-6-13)-Nginx代理正确食用方式
前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。 截止到 2019-05-30 期,所有成员都进行了一次分享。内部对课程进行了一些调整,之后会针对项目开始 review 。我这边预期准备进入中级阶段,中间还是会穿插一些实战。
0 0
使用 Envoy 作为前端代理
使用 Envoy 作为前端代理
0 0
5 分钟解决前后端联调问题,说一说前端代理这件事
简洁,又能触达痛点的一站式前端代理解决方案,你值得拥有。
0 0
【前端直播资料】《基于 Service Worker 实现在线代理》
在线代理大家都见过,可以直接在网页里访问某个目标网站,无需安装代理工具。不过传统的在线代理大多很简单,只是在后端替换网页里的路径而已,存在有不少问题。 本次分享讲解一种新概念的在线代理,充分利用前端新技术,实现更完善的代理效果,并能大幅降低后端开销。
4164 0
NGINX前端代理TOMCAT取真实客户端IP
nginx前端代理tomcat取真实客户端IP 使用Nginx作为反向代理时,Tomcat的日志记录的客户端IP就不在是真实的客户端IP,而是Nginx代理的IP。要解决这个问题可以在Nginx配置一个新的Header,用来存储$remote_add,然后再Tomcat获取记录这个值。
403 0
两年经验以下的web前端们需要注意什么?
前些年自己堆前端岗位的经验总结
0 0
QGS
zabbix5.0.8修改web前端logo等相关配置及添加自定义菜单
记zabbix5.0.8修改web前端logo等相关配置及添加自定义菜单
0 0
+关注
小结巴巴
高级前端工程师,喜欢写一些总结和例子
文章
问答
文章排行榜
最热
最新
相关电子书
更多
万物互联语音交互从端开始——前端处理从技术到商业
立即下载
2022 前端技术趋势解读
立即下载
智能前端技术与实践
立即下载