Omi框架学习之旅 - 获取DOM节点 及原理说明

虽然绝大部分情况下,开发者不需要去查找获取DOM,但是还是有需要获取DOM的场景,所以Omi提供了方便获取DOM节点的方式。

这是官网的话,但是我一直都需要获取dom,对dom操作,所以omi提供的获取dom的方式对我来说还是比较重要的。

老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明。

        class Hello extends Omi.Component {
            constructor(data) {
                super(data);
            }

            style() {
                return `
                    h1 {
                        cursor: pointer;
                    }
                `;
            }

            handleClick() {
                console.log(this.refs.aa);
                console.log(this.refs.bb);
                console.log(this.refs.pp);
            }

            render() {
                return `
                    <div ref='aa'>
                        <h1 ref="bb" onclick="handleClick()">
                            <p ref="pp"> 只在在标签中写ref="xxx", this.refs.xxx就只表示这个dom节点 </p>
                            Hello, {{name}}!
                        </h1>
                    </div>
                `;
            }
        };

        var hello = new Hello({name: 'Sorrow.X'});
        Omi.render(hello, '#app');

看看结果:

 

 

 

demo的疑问和疑问的说明:

疑问1:

render方法中html的含有ref属性的dom好像都被实例的refs管理起来了诶,作者是怎么实现的啊?

答:

是的,都被挂载到实例的refs对象上去了。具体实现如下:

当html被插入到指定的dom后,也就是_render方法的结尾处,如下

 

在 1 这里的这个方法,可不仅仅只是查询dom,此demo的话,我只讲其对应的方法:

 

    _mixRefs() {    // 查找dom,放入实例的refs属性中
        let nodes = Omi.$$('*[ref]',this.node);    // 根节点下面的拥有ref属性的孩子
        nodes.forEach(node => {
            if(node.hasAttribute(this._omi_scoped_attr) ) {
                this.refs[node.getAttribute('ref')] = node;    // 把值添加到refs中去
            };
        });
        let attr = this.node.getAttribute('ref');    // 根节点自己如果也写了ref属性
        if(attr) {
            this.refs[attr] = this.node;    // 把自己放进refs去
        };
    }

这段代码便是把含有ref属性的元素放入实例属性refs的代码,当然还用到了一个Omi的静态函数$$,如下

    Omi.$$ = function(selector,context){
        if(context){
            return  Array.prototype.slice.call(context.querySelectorAll(selector))
        }else{
            return Array.prototype.slice.call(document.querySelectorAll(selector))
        }
    }

至此,就完美了,其实这个实现还是比较简单的。

 

ps:

    这个功能,好很是喜欢,获取dom很方便。

posted @ 2017-03-25 15:09  Sorrow.X  阅读(441)  评论(0编辑  收藏  举报