標籤:android des style blog java color
單頁應用現在很流行,特別是移動前端開發方面,用web頁面做出來的應用,幾乎可以達到java,C++等開發的用程式一樣的效果。基於web天生就有跨平台的優勢,使得前端開發也越來越受重視了。要想在移動端做出原生應用的效果,單頁應用首當其衝,但是呢,單頁應用有一個重要的知識點,那就是非同步過程太明顯,你想,大量的樣式操作,事件邦定,都要在dom節點繪製完成之後才能進行。怎樣確定我們在操作某個dom節點的時候,它已經在頁面上存在了呢。以前呢,我們都是用定時器設一個時間來保證的。例如:
var element = document.createElement(‘svg‘); //大量的文檔資料 //..... document.body.appendChild(element);setTimeout(function(){ element.style.background = ‘‘; //其它對於element的操作},1000);
這樣做,通常都不會有問題,特別是在pc上,即便你的延時設的更小一點,也可能看不到問題,但是一旦在手機或平板上,就會發現,如果你設的延時比較小,那可能後面的節點操作會報undefined沒有style屬性之類的錯誤。如果設的比較大,就會發現,操作反應變得很遲頓了。有沒有一種方式可以在節點繪製好了,就通知我們進行下一步的操作呢?當然是有的,在現代瀏覽器的一些進階版本上大多都實現了變動事件,再再進階一點的瀏覽版本,還實現了MutationObserver這個東東。於是呢,我們就可以解決上面的問題了。下面是我寫的一個外掛程式:
/** * 當監聽的節點內容發生變化時,觸發指定的回調 * @param opts { * container:父容器,dom對象或jQuery對象 * content :要加入父容器的內容,字串或jQuery對象 * position :內容插入父容器的位置,‘first‘ 表示在前加入,預設在末尾 * delay :延時,預設0 * } * @version 1.02 * @author [author] bjtqti * @return {[type]} [description] */Xut.nextTick = new function() { var DOC = document, MutationObserver = window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver; function nextTick(opts,callback) { var container = opts.container, content = opts.content, delay = opts.delay||0, position = opts.position, animatId = ‘T‘+ (Math.random()*10000 << 1), tick = DOC.createElement(‘input‘), observer = null; if (!container || !content) { return; } //檢查容器---$(container) 轉為dom對象 if(typeof container === ‘object‘ && container.selector !== undefined){ container = container[0]; } if(container.nodeType !== 1){ console.log(‘container must be HTMLLIElement ‘); return; } //標記任務 tick.setAttribute(‘value‘,animatId); //檢查內容 if(typeof content ===‘string‘){ var temp = $(content); if(!temp[0]){ //純文字內容 temp = DOC.createTextNode(content); temp = $(temp); } content = temp; } //組裝內容到臨時片段 function _createFragment(){ var frag = DOC.createDocumentFragment(), len = content.length; for(var i=0;i<len;i++){ frag.appendChild(content[i]); } return frag; } //將內容加入父容器 function _appendChild(){ //拼接內容 content = _createFragment(); content.appendChild(tick); //判斷插入的位置 if(position === ‘first‘){ container.insertBefore(content, container.firstChild); }else{ container.appendChild(content); } //觸發變動事件 tick.setAttribute(‘value‘,animatId); } //完成任務後處理&Event function _finishTask(event) { if(event.target.value === animatId){ container.removeEventListener(‘DOMNodeRemoved‘,_finishTask,false); callback(); } } //完成任務後處理&Observer function _completeTask() { container.removeChild(tick); callback(); } if(MutationObserver){ observer = new MutationObserver(function(mutations) { mutations.forEach(function(record) { if(record.oldValue === animatId){ _completeTask(); observer = null; } }); }); //設定要監聽的屬性 observer.observe(tick, { attributes: true, //childList: true, attributeOldValue :true, attributeFilter:["value"]//只監聽value屬性,提高效能 }); _appendChild(); }else{ //檢測是否支援DOM變動事件 if(DOC.implementation.hasFeature("MutationEvents","2.0")){ container.addEventListener(‘DOMNodeRemoved‘,_finishTask,false); _appendChild(); container.removeChild(tick); }else{ //歉容Android2.xx處理 _appendChild(); setTimeout(function () { _completeTask(); }, delay); } } } return nextTick;}
都是項目中實踐過的功能。如果有用就直接拿走吧。關於這些進階事件的解釋,在部落格園已有前輩寫的很詳細了,有想法深入瞭解的,就要靠自己百度或Google了。