再起航,我的学习笔记之JavaScript设计模式26(解释器模式)
解释器模式
概念介绍
解释器模式(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
获取元素在页面中的路径
我们都知道获取一个元素很简单通过document.getElementById方法我们可以很轻易的获取到文档中ID为某个字段的元素,那么如果我们想要获取元素在页面中的路径我们又改怎么办呢?
我们可以想象一下,页面就是一个很大的文档树。从最开始的html开始到同级的head,body再到body下的子元素。最后再定位到我们按钮,比如下面这个简单的文档树。
<html>
<head></head>
<body>
<div></div>
<div><input type="button" /></div>
</body>
</html>
如果我们想获取按钮的位置,我们可以这样理解html>head|body>div2>input。
我们一层一层的定位知道最后确定我们按钮的所在位置。
解释器
我们刚刚相当于定义了一组语言规则,现在我们要做的就是使用解释器来完成我们刚刚定义的规则,这就是解释器模式。
下面我们就开始实现我们的解释器:
首先我们需要写一个方法去获取兄弟元素的名称
function getSublingName(node){
//如果存在兄弟元素
if(node.previousSibling){
//返回的兄弟元素名称字符串
var name='',
//紧邻兄弟元素中相同名称的元素个数
count=1,
//原始节点名称
nodeName=node.nodeName,
//前一个兄弟元素
sibling=node.previousSibling;
//如果存在前一个兄弟元素
while(sibling){
//如果节点为元素,并且节点类型与前一个兄弟元素相同,并且前一个兄弟元素名称存在
if(sibling.nodeType==1&&sibling.nodeType===node.nodeType&&sibling.nodeName){
//如果节点名称和前一个兄弟元素名称相同
if(nodeName==sibling.nodeName){
//节点名称后面添加技数
name+= ++count;
}else{
//重复相同紧邻节点名称节点个数
count=1;
//追加新的节点名称
name+='|'+sibling.nodeName.toUpperCase();
}
}
//向前获取一个兄弟元素
sibling=sibling.previousSibling;
}
return name
}else{
//如果不存在兄弟元素返回‘’
return '';
}
}
有了这个方法我们处理每一层的元素节点就方便很多了,下面我们开始实现我们的解释器
//元素位置解释器
var Interpreter=(function(){
//node目标节点,wrap容器节点
return function(node,wrap){
//路径数组
var path=[],
//如果不存在容器节点,默认为document
wrap=wrap||document;
//如果当前(目标)节点等于容器节点
if (node===wrap) {
//容器节点为元素
if (wrap.nodeType==1) {
//路径数组中输入容器节点名称
path.push(wrap.nodeName.toUpperCase());
}
//返回最终路径数组结果
return path;
}
//如果当前节点的父节点不等于容器节点
if (node.parentNode!==wrap) {
//对当前节点的父节点执行遍历操作
path=arguments.callee(node.parentNode,wrap);
}else{
//如果容器节点为元素
if(wrap.nodeType==1){
//路径数组中输入容器节点名称
path.push(wrap.nodeName.toUpperCase());
}
}
//获取元素的兄弟元素名称的统计
var sublingNames=getSublingName(node);
//如果节点为元素
if(node.nodeType==1){
//输入当前节点元素名称及其前面兄弟元素名称统计
path.push(node.nodeName.toUpperCase()+sublingNames);
}
//返回最终路径数组结果
return path;
}
})();
好的现在我们的解释器就完成了,下面我们测试一下
首先我们创建一个简单的页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div></div>
<div id="container">
<div>
<div>
<ul>
<li><span id="span1">1</span></li>
<li><span id="span2">2</span></li>
</ul>
</div>
</div>
<div>
<div>
<ul>
<li><span id="span3">3</span></li>
<li><input type="button" id='btn' value="获取我的位置" /></li>
</ul>
</div>
</div>
</div>
</body>
</html>
页面创建好了我们来测试一下
document.getElementById('btn').addEventListener('click',function(){
var path=Interpreter(this);
console.log(path.join('>'));
})

好了现在我们通过解释器就能很轻易地获取元素在文档中的位置了
总结
解释器即是对客户提出的需求,经过解析而形成的一个抽象解释程序。而是否可以应用解释器模式的一条重要准则是能否更根据需求解析出一套完整的语法规则,无论语法规则简单或是复杂都是必须的。因为解释器要按照这套规则才能实现相应的功能。
也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~
好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。
欢迎转载,转载请注明作者,原文出处。
再起航,我的学习笔记之JavaScript设计模式26(解释器模式)的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式09(原型模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
- 再起航,我的学习笔记之JavaScript设计模式11(外观模式)
经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习. 结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何 ...
- 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)
桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...
- 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- 再起航,我的学习笔记之JavaScript设计模式22(访问者模式)
访问者模式 概念介绍 访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法 解决低版本IE兼容性 我们来看下面这段代码,这段代码,我们封装了一个绑定 ...
- 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)
备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...
- 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)
迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...
随机推荐
- SpringMVC(二)--处理数据模型、ModelAndView、Model、Map、重定向、@ModelAttribute、
1.处理模型数据 Spring MVC 提供了以下几种途径输出模型数据: – ModelAndView:处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据 ...
- Tomcat闪退的问题
问题:双击tomcat bin下的startup.bat,tomcat的窗口一闪而过,未成功启动: 原因是:在启动tomcat是,需要读取环境变量和配置信息,缺少了这些信息就会导致了tomcat的闪退 ...
- Ext.data.Store添加动态参数
多条件查询页面的参数都是动态的,并且我们通常还会有默认加载页面.此时,动态添加参数非常重要,其中baseparam是解决问题的关键. @ 将查询条件定义为一个全局变量 var param_01 = & ...
- C# 爬虫 Jumony html解析
前言 前几天写了个爬虫,然后认识到了自己的不足.感谢 "倚天照海- -" ,我通过你推荐的文章,意外的发现了html解析的类库——Jumony. 研究了2天,我发现这个东西简单粗暴 ...
- 【搬运工】——初识Lua(转)
使用 Lua 编写可嵌入式脚本 Lua 提供了高级抽象,却又没失去与硬件的关联. 虽然编译性编程语言和脚本语言各自具有自己独特的优点,但是如果我们使用这两种类型的语言来编写大型的应用程序会是什么样子呢 ...
- JSON创建键值对(key是中文或者数字)方式详解
JSON创建键值对(key是中文或者数字)方式详解 先准备好一个空的json对象 var obj = {}; 1. 最原始的方法 obj.name = 'zhangsan'; //这种方式很简单的添加 ...
- Java 反射之动态代理
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt205 利用Java反射机制你可以在运行期动态的创建接口的实现.java.la ...
- 开源项目Druid的提取SQL模板
在数据库审计中,常常用到SQL模板,这样提取一次模板,下一次就不用对相同的模板的SQL进行相关操作.对此Druid提供相应的工具类进行SQL模板提取: package com.dbappsecurit ...
- web程序员标准环境之DreamWeaver【…
Adobe Dreamweaver,简称"DW",中文名称 "梦想编织者",是美国MACROMEDIA公司开发的集网页制作和管理网站于一身的所见即所得网页编辑器 ...
- MySQL (六)--外键、联合查询、子查询
1 外键 外键:foreign key,外面的键(键不在自己表中),如果一张表中有一个字段(非主键)指向另外一张表的主键,那么将该字段称为外键. 1.1 增加外键 外键可以在创建表的时候或创建表之后增 ...