angularjs特效之分散的字符串--解析compile link $compile $inte
效果预览来自codepen的效果预览:(引用了angularjs,已被墙,请谨慎预览) 转载声明这篇文章其实源自BenNadel的博客。在此我要分享一下自己的收获和一些更改。 主要内容整个效果都建立在angularjs的directive里面。可以想到,作者绑定了mousemove事件,通过勾股定理计算的距离,除此之外,我还有些小收获要跟大家分享一下:
directive中compile和link函数的区别根据BenNadel自己在博客中的解释:
翻译成汉字就是:当我需要根据原始DOM(文档对象模型,说详细了可能看不懂,还是用简称吧~)的结构对Dom进行改变时,我使用compile函数。 其实很多时候,在link和compile中处理的结果是一样的,但是细节上有些差异,比如以下情况: <span ng-repeat="word in [ 'Word','to','your','mother' ]" bn-compile bn-link> {{ word }} </span> 其中bn-compile和bn-link分别是2个directive,一个在compile函数中打印出日志“compile”,并且给element增加class "c1",一个在link函数中打印出“link”,并且给element增加class "c2",c1、c2都有css样式进行展示。最终结果是生成的4个span都可以看到c1、c2的样式,但是console中compile只打印了1次,link却打印了4次。 当然,在link函数中,也有一些地方是compile做不到的,有的时候你可能就是要对已经部分渲染后的Dom结构进行修改,而且link函数中可以传入scope,此时你可以进行数据绑定了。这也就是下面我要讲到的。 $interpolate和$compile这2个service的区别在BenNadel的原始文章中,他使用了compile对dom结构进行修改。但是如果我的文本内容是通过数据绑定了,如下: <div scatter-effect="#c2" scatter-distance="1000" class="tagline"> {{hello}} </div> 特效就失败了,如下: 第二个div因为绑定的是动态数据,最终是以模板形式显示的。 angular.module("Demo").directive( "scatterEffect",// $compile是把字符串编译为element,所以字符串必须是dom形式 // $interpolate是把表达式和data 绑定到一起,$compile中会调用$interpolate function ($document,$interpolate) { return ({ link: link,restrict: "A" }); function link(scope,element,attributes) { // 如果是compile,则无法获取scope var realContent = $interpolate(element.html())(scope); element.empty().append(realContent); // 这是原来compile中的函数,element处理后,再放到link中调用 wrapLetters(element); /* other code */ } }) 在以上代码中, 如何把node内部包含的所有文本字母都用span包裹起来这句话尽管很长,但是做起来,其实也很难(⊙﹏⊙)b。在此我只能奉上大神的代码和我的膝盖了,谨和诸君分享: function findTextNodes(parent) { // node是一个DOMElement,map返回一个jQuery对象,所以要想获得array可以使用toArray() or get() /* 我的注释 If the node is an element node,the nodeType property will return 1. If the node is an attribute node,the nodeType property will return 2. If the node is a text node,the nodeType property will return 3. If the node is a comment node,the nodeType property will return 8. */ // 此处的angular.element就是jQuery var textNodes = angular.element(parent).contents().map( function operator(i,node) { return ((node.nodeType === 1) ? findTextNodes(node) : node); } ); return (textNodes.toArray()); } // I find and wrap each text-based letter,within the given parent,// in its own Span tag. function wrapLetters(parent) { findTextNodes(parent).forEach( function(node) { // Replace each individual letter with a Span tag. var wrappedHtml = node.nodeValue.replace(/(S)/g,"<span class='scatter-item'>$1</span>"); // 最值得推敲的在这里: var fragment = angular.element(document.createDocumentFragment()) .append(wrappedHtml); node.parentNode.insertBefore(fragment[0],node); node.parentNode.removeChild(node); // 以下方法不行:jquery生成的元素列表默认丢弃了首尾空格! //$(wrappedHtml).insertBefore(node); //node.parentNode.removeChild( node ); } ); } 其实提取textNode,然后正则替换,最后插入原来的位置,听起来不难,但是如果利用jQuery把字符串转换为dom,那么两头的空格就会丢掉,比如 jQuery转换后,前后的空格都没了。所以不能用它来转换。 relative定位和absolute定位的差别下面我们说点关于css的知识。我经常对absolute元素进行top、left、right、bottom定位,我也知道这样做之前,父元素必须用relative,但是我还真不知道原来relative元素也可以用TLRB这四兄弟进行操作!真是丢人,确实需要反思啊。下面附上英文解释和中文对照翻译:
static是position的默认值,什么都不加就是那种效果; span.scatter-item { position: relative ; z-index: 100 ; } 然后,在mousemove事件中,调整top、left的值,使它们在鼠标距离目标元素远的时候,偏离自己的位置;在鼠标进入目标元素时,重新回到自己的位置。 结语终于码完了 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- angularjs – 具有Access-Control-Allow-Origin的Angular 2
- 开放才能进步!Angular和Wijmo一起走过的日子
- bootstrap输入提示的使用及格式
- bash – Ant没有加载salesforce任务定义?
- WebService之CXF注解之五(配置文件)
- scala – 类型推断仍然需要增强,这个例子有什么更好的建议吗
- shell – 如何在“docker run container”上自动启动两个JA
- WebService介绍(三):使用WebService代理类
- @ angular / core / testing没有导出成员’MockApplication
- 集Backbone,Mustache,Bootstrap,JQuery于一身的DEMO--Cool