码迷,mamicode.com
首页 > Web开发 > 详细

“高三”笔记之动态JS、动态样式

时间:2016-04-03 23:45:47      阅读:298      评论:0      收藏:0      [点我收藏+]

标签:

拜读《JavaScript高级程序设计》 --- 站在巨人的肩上

动态JS、动态样式就是页面加载时不存在,但将来通过DOM操作动态添加的脚本;包括加载外部文件和添加内部代码块两种;动态加载的外部文件能够立即运行,而动态添加的代码块却不能如愿的立即执行;下面将主要以JS为例,小小的探索下动态脚本的加载、执行以及jQuery的做法、Angularjs的相关做法;

1、动态加载外部文件

因为动态加载的外部JS会立即执行,也没什么浏览器兼容性问题,这个好处理;这里的重点是怎么知道脚本已加载完成呢?呵呵,那么浏览器的兼容性问题就来咯!bsie!

 1 //动态加载外部js文件
 2 //params:url,loaded,error
 3 var AsyncScripts=function() {
 4     function load() {
 5         var args=arguments;
 6         var head = document.getElementsByTagName(‘head‘)[0];          
 7         var js = document.createElement(‘script‘);          
 8         js.type=‘text/javascript‘;           
 9         js.src=args[0];           
10         head.appendChild(js);          
11         if (document.all) {       
12             js.onreadystatechange = function () {     
13                 if (js.readyState == ‘loaded‘ || js.readyState == ‘complete‘) {
14                     args[1]&&args[1]();
15                 }               
16             }          
17         } else {                 
18             js.onload = function () {
19                 args[1]&&args[1]();
20             }           
21         }
22         js.onerror=function(){
23             args[2]&&args[2]();
24         }
25     }
26     function execJSblock() {
27 
28     }
29     return {
30         load:load,
31         exec:execJSblock
32     }
33 }();
34 
35 AsyncScripts.load(‘http://cdn.famanoder.com/lib/jquery0.js‘,function() {
36     alert($)
37 });

2、立即执行动态加载的代码块

理论上讲,script.appendChild(createTextNode(codeStr));能够正常运行,在此不得不继续bsie了,因为在IE中,<script>被视为一个特殊元素(<style>与其类似),不允许DOM访问其子节点;不过,可以使用<script>的text属性来指定代码块,让其正常运行;

 1 //params:scriptsStr
 2 var AsyncScripts=function() {
 3     function execJSblock(scriptsStr) {
 4         var script=document.createElement(‘script‘);
 5         script.type=‘text/javascript‘;
 6         if (document.all) {
 7             script.text=scriptsStr;
 8         }else {
 9             script.appendChild(document.createTextNode(scriptsStr));
10         }
11         document.body.appendChild(script);
12     }
13     return {
14         exec:execJSblock
15     }
16 }();
17 AsyncScripts.exec(‘var a=1000;alert(document.body.clientWidth+";"+a)‘);
18 //实际上该方法与eval(scriptsStr)是一样的;

3、动态加载style

动态加载JS与动态加载style二者基本上是一样的做法,存在基本一样的问题;不一样的是一个创建script,一个创建style/link;在IE上是script.text,而正常的做法是script.appendChild(document.createTextNode(scriptsStr));在IE上是style.stylesheet.cssText,正常的做法还是style.appendChild(document.createTextNode(stylesStr));还要注意link只在head里有效,这个不能像script/style标签可以在body里;

动态加载JS、成功错误的回调、代码块立即执行,稍作整理,大概这样:

 1 var AsyncScripts=function() {
 2     function load() {
 3         var args=arguments;
 4         var head = document.getElementsByTagName(‘head‘)[0];          
 5         var js = document.createElement(‘script‘);          
 6         js.type=‘text/javascript‘;           
 7         js.src=args[0];           
 8         head.appendChild(js);          
 9         if (document.all) {       
10             js.onreadystatechange = function () {     
11                 if (js.readyState == ‘loaded‘ || js.readyState == ‘complete‘) {
12                     args[1]&&args[1]();
13                 }               
14             }          
15         } else {                 
16             js.onload = function () {
17                 args[1]&&args[1]();
18             }           
19         }
20         js.onerror=function(){
21             args[2]&&args[2]();
22         }
23     }
24     function execJSblock(scriptsStr) {
25         var script=document.createElement(‘script‘);
26         script.type=‘text/javascript‘;
27         if (document.all) {
28             script.text=scriptsStr;
29         }else {
30             script.appendChild(document.createTextNode(scriptsStr));
31         }
32         document.body.appendChild(script);
33     }
34     return {
35         load:load,
36         exec:execJSblock
37     }
38 }();

4、jQuery怎么做的

在jQuery1.4.1及之前动态DOM操作添加的脚本是不会执行的,这个问题在1.4.2及以后的版本做了修复,跪拜我伟大的jQuery吧!继续bsie!那么就是说下面的代码里的script和style都会立即看到效果:

1 $(selector).append(‘<script>alert(1)</script>‘);
2 
3 $(selector).html(‘<script>alert(1)</script>‘);
4 
5 $(selector).append(‘<style>.a{color:red;}</style>‘);

5、Angularjs对动态添加的html及指令的处理

在Angular里如果ng-bind=‘html string‘,Angular会把html string当做text对待,而不像上面的jQuery会帮你执行里面的脚本;即使ng-bind-html=‘html string‘,也不会如你所愿;是的,angular很强大的,这个问题它早想到了,$sce服务即是处理这个的,$sce翻译过来就是“严格的上下文模式”;那么可以先注入$sce服务,然后调用trustAsHtml(_html),通过ng-bind-html达到我们想要的结果;

1 [‘$scope‘,‘$sce‘,function($scope,$sce) {
2     $scope.trustHtml=function(_html) {
3         return $sce.trustAsHtml(_html);
4     };
5 }];

为了方便其他地方调用,我们可以把它封装成一个过滤器:

1 app.filter(‘trustHTML‘, [‘$sce‘, function ($sce) {    
2     return function (_html) {
3         return $sce.trustAsHtml(_html);
4     };
5 }]);

刚学Angularjs还碰到过个问题:动态添加的指令无法运行;由于页面加载后angular会从ng-app开始搜集指令然后编译,所以动态添加的指令已经不在范围内了,这时需要再次编译指令,由$compile服务在link里做这件事;

1 link:function($scope,$element,$attrs) {
2     angular.element(DOMobj).html(_html);
3     $compile(angular.element(DOMobj).contents())($scope);
4 };

6、叽叽歪歪完了

初学Angularjs,正在改造博客的后台程序,呵呵,继续挖坑,慢慢填坑;

“高三”是本不错的书,闲来多看看总有收获;

有人说习惯了jQuery,要换个思维方式才能学好Angular;有人说写Angular最好不要用jQuery的搞法,比如DOM操作;可也有人Angular与jQuery一起混用;

我感觉jQuery与Angular是两种完全不同的思维方式下的产物,因为避免不了操作DOM,所以有人二者混用是可以理解的,但我看着总感觉别扭;我想以当一个项目适合Angular的思维来做,就应该摒弃脑子里大量的DOM操作,试着以Angular的搞法来做,即便有DOM操作,angular也有对应的做法,这时jQuery可以歇歇了;看看Angular的服务都带着$符,自带土豪气啊,同学们一起加油!!!

 

 

“高三”笔记之动态JS、动态样式

标签:

原文地址:http://www.cnblogs.com/hufeng/p/5350996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!