码迷,mamicode.com
首页 > 其他好文 > 详细

高级前端开发不可或缺的知识

时间:2014-07-16 18:03:48      阅读:207      评论:0      收藏:0      [点我收藏+]

标签: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;
}

都是项目中实践过的功能。如果有用就直接拿走吧。关于这些高级事件的解释,在博客园已有前辈写的很详细了,有想法深入了解的,就要靠自己百度或谷歌了。

高级前端开发不可或缺的知识,布布扣,bubuko.com

高级前端开发不可或缺的知识

标签:android   des   style   blog   java   color   

原文地址:http://www.cnblogs.com/afrog/p/3847471.html

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