DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> WEB網站前端 >> WEB前端代碼 >> 動態JS、動態樣式解析
動態JS、動態樣式解析
編輯:WEB前端代碼     
拜讀《JavaScript高級程序設計》 --- 站在巨人的肩上

動態JS、動態樣式就是頁面加載時不存在,但將來通過DOM操作動態添加的腳本;包括加載外部文件和添加內部代碼塊兩種;動態加載的外部文件能夠立即運行,而動態添加的代碼塊卻不能如願的立即執行;下面將主要以JS為例,小小的探索下動態腳本的加載、執行以及jQuery的做法、Angularjs的相關做法;

1、動態加載外部文件

因為動態加載的外部JS會立即執行,也沒什麼浏覽器兼容性問題,這個好處理;這裡的重點是怎麼知道腳本已加載完成呢?呵呵,那麼浏覽器的兼容性問題就來咯!bsie!

 //動態加載外部js文件
 //params:url,loaded,error
 var AsyncScripts=function() {
     function load() {
         var args=arguments;
         var head = document.getElementsByTagName('head')[0];          
         var js = document.createElement('script');          
         js.type='text/javascript';           
         js.src=args[0];           
         head.appendChild(js);          
         if (document.all) {       
             js.onreadystatechange = function () {     
                 if (js.readyState == 'loaded' || js.readyState == 'complete') {
                     args[1]&&args[1]();
                 }               
             }          
         } else {                 
             js.onload = function () {
                 args[1]&&args[1]();
             }           
         }
         js.onerror=function(){
             args[2]&&args[2]();
         }
     }
     function execJSblock() {
 
     }
     return {
         load:load,
         exec:execJSblock
     }
 }();
 
 AsyncScripts.load('http://cdn.famanoder.com/lib/jquery0.js',function() {
     alert($)
 });

2、立即執行動態加載的代碼塊

理論上講,script.appendChild(createTextNode(codeStr));能夠正常運行,在此不得不繼續bsie了,因為在IE中,<script>被視為一個特殊元素(<style>與其類似),不允許DOM訪問其子節點;不過,可以使用<script>的text屬性來指定代碼塊,讓其正常運行;

 //params:scriptsStr
 var AsyncScripts=function() {
     function execJSblock(scriptsStr) {
         var script=document.createElement('script');
         script.type='text/javascript';
         if (document.all) {
             script.text=scriptsStr;
         }else {
             script.appendChild(document.createTextNode(scriptsStr));
         }
         document.body.appendChild(script);
     }
     return {
         exec:execJSblock
     }
 }();
 AsyncScripts.exec('var a=1000;alert(document.body.clientWidth+";"+a)');
 //實際上該方法與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、成功錯誤的回調、代碼塊立即執行,稍作整理,大概這樣:

 var AsyncScripts=function() {
     function load() {
         var args=arguments;
         var head = document.getElementsByTagName('head')[0];          
         var js = document.createElement('script');          
         js.type='text/javascript';           
         js.src=args[0];           
         head.appendChild(js);          
         if (document.all) {       
             js.onreadystatechange = function () {     
                 if (js.readyState == 'loaded' || js.readyState == 'complete') {
                     args[1]&&args[1]();
                 }               
             }          
         } else {                 
             js.onload = function () {
                 args[1]&&args[1]();
             }           
         }
         js.onerror=function(){
             args[2]&&args[2]();
         }
     }
     function execJSblock(scriptsStr) {
         var script=document.createElement('script');
         script.type='text/javascript';
         if (document.all) {
             script.text=scriptsStr;
         }else {
             script.appendChild(document.createTextNode(scriptsStr));
         }
         document.body.appendChild(script);
     }
     return {
         load:load,
         exec:execJSblock
     }
 }();

4、jQuery怎麼做的

在jQuery1.4.1及之前動態DOM操作添加的腳本是不會執行的,這個問題在1.4.2及以後的版本做了修復,跪拜我偉大的jQuery吧!繼續bsie!那麼就是說下面的代碼裡的script和style都會立即看到效果:

 $(selector).append('<script>alert(1)</script>');
 
 $(selector).html('<script>alert(1)</script>');
 
 $(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達到我們想要的結果;

 ['$scope','$sce',function($scope,$sce) {
     $scope.trustHtml=function(_html) {
         return $sce.trustAsHtml(_html);
     };
 }];

為了方便其他地方調用,我們可以把它封裝成一個過濾器:

 app.filter('trustHTML', ['$sce', function ($sce) {    
     return function (_html) {
         return $sce.trustAsHtml(_html);
     };
 }]);

剛學Angularjs還碰到過個問題:動態添加的指令無法運行;由於頁面加載後angular會從ng-app開始搜集指令然後編譯,所以動態添加的指令已經不在范圍內了,這時需要再次編譯指令,由$compile服務在link裡做這件事;

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

6、叽叽歪歪完了

初學Angularjs,正在改造博客的後台程序,呵呵,繼續挖坑,慢慢填坑;

“高三”是本不錯的書,閒來多看看總有收獲;

有人說習慣了jQuery,要換個思維方式才能學好Angular;有人說寫Angular最好不要用jQuery的搞法,比如DOM操作;可也有人Angular與jQuery一起混用;

我感覺jQuery與Angular是兩種完全不同的思維方式下的產物,因為避免不了操作DOM,所以有人二者混用是可以理解的,但我看著總感覺別扭;我想以當一個項目適合Angular的思維來做,就應該摒棄腦子裡大量的DOM操作,試著以Angular的搞法來做,即便有DOM操作,angular也有對應的做法,這時jQuery可以歇歇了;看看Angular的服務都帶著$符,自帶土豪氣啊,同學們一起加油!!!

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved