前端面试宝典(4)——必掌握
前端面试宝典(4)——必掌握
小木fan 发表于5个月前
前端面试宝典(4)——必掌握
  • 发表于 5个月前
  • 阅读 3
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】如何购买服务器最划算?>>>   

摘要: 钻研其中原理,高效率学习
  1. DOM结构及操作                                                                                                                      DOM-(document object model)文档对象模型                                                                        文档-html页面                                                                                                                        文档对象-页面中元素                                                                                                                文档对象模型-为了能够让程序(js)操作页面中的元素
  2. DOM的作用及理解                                                                                                                   (1)可理解为操作html的API接口。(2)html结构模型。(3)html模型中的对象。
  3. DOM和BOM的区别                                                                                                                 BOM(browser object model)浏览器对象模型。DOM操作的是html中的元素,BOM是浏览器的API,操作的是浏览器。
  4. 面试DOM的长问点        
    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
    </head>
    <body>
        <ul id = "js-list">
        </ul>
        <script>
        (() => {
        var ndcontainer = document.getElementById("js-list");
        if(!ndcontainer) {
            return;
        }
        for (var i = 0; i < 3; i++) {
            var nditem = document.createElement("li");
            nditem.innerText = i + 1;
            ndcontainer.appendChild(nditem);
        }
        })();
        </script>
    </body>
    </html>
    
    /*
     1.id、class的命名区分是css用,还是js用。'js-list'.
     2.节点的变量命名最好前加nd.
     3.获取了节点,判断其是否存在.
     4.声明即运行的函数表达式(() => {})();
    */
         
  5. 如何绑定事件?  点击每一个li,则弹出li中的内容。
    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
       
    </head>
    <body>
        <ul id = "js-list">
        </ul>
        <script>
        (() => {
        var ndcontainer = document.getElementById("js-list");
        if(!ndcontainer) {
            return;
        }
        for (var i = 0; i < 3; i++) {
            var nditem = document.createElement("li");
            nditem.innerText = i + 1;
            //绑定事件
            nditem.addEventListener('click',function(){
                alert(i);
            })
            ndcontainer.appendChild(nditem);
        }
        })();
        </script>
    </body>
    </html>

    由于闭包和作用域的问题,i和nditem的作用域范围相同,则弹出来的都是3.可用ES6的块级作用域解决

    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
       
    </head>
    <body>
        <ul id = "js-list">
        </ul>
        <script>
        (() => {
        var ndcontainer = document.getElementById("js-list");
        if(!ndcontainer) {
            return;
        }
        for (let i = 0; i < 3; i++) {
            const nditem = document.createElement("li");
            nditem.innerText = i + 1;
            nditem.addEventListener('click',function(){
                alert(nditem.innerText);
            })
            ndcontainer.appendChild(nditem);
        }
        })();
        </script>
    </body>
    </html>

    element.click()不支持动态元素或样式绑定事件。支持给动态元素绑定事件的是.live()和.on()。

  6. 数据量很大怎么办,事件委托。若要插入的li是300个,则DOM中注册的事件监听函数增加了100倍。
    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
    
    </head>
    <body>
        <ul id = "js-list">
        </ul>
        <script>
            (() => {
                var ndcontainer = document.getElementById("js-list");
                if(!ndcontainer) {
                    return;
                }
                for (let i = 0; i < 300; i++) {
                    const nditem = document.createElement("li");
                    nditem.innerText = i + 1;
                    ndcontainer.appendChild(nditem);
                }
                //事件代理
                ndcontainer.addEventListener('click',function(e){
                    const target = e.target;
                    if(target.tagName === 'LI') {
                        alert(target.innerHTML);
                    }
                });
            })();
    </script>
    </body>
    </html>

    具体事件代理看:                                                                                                                      1.http://www.jianshu.com/p/2c68c8ceef1c                                                                           2.http://blog.csdn.net/majian_1987/article/details/8591385

  7. 如果是插入300000个的li呢?会有什么问题,该怎样改进,会出现明显的卡顿感,怎么解决?出现卡顿感的渲染帧率(FPS)过低。而实际上,包含300000个li,用户不会立即看到全部,大部分也不会看,那部分都没有渲染的必要,好在现代浏览器提供了requestAnimationFrameAPI来解决非常耗时的代码段对渲染的阻塞问题,不知道requestAnimationFrame用法和原理的请研究下这篇文章。                                                                                                                           所以,可以从减少DOM操作次数、缩短循环时间两个方面减少主线程阻塞的时间。减少DOM操作次数的良方是DocumentFragment;缩短循环时间则考虑用分治的思想把300000个li分批插入到页面中,每次插入的时机是在页面重新渲染之前。由于requestAniamtionFrame并不是所有的浏览器都支持,Paul lrish给出了对应的polyfill

    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
    
    </head>
    <body>
        <ul id = "js-list">
        </ul>
        <script>
            (() => {
                const ndContainer = document.getElementById('js-list');
                if(!ndContainer) {
                    return;
                }
                const total = 300000;
                const batchSize = 4; //每批插入的节点次数,越大越卡
                const batchCount = total / batchSize; //需要批量处理多少次
                let batchDone = 0;//已经完成的批处理个数
    
                function appendItems() {
                    const fragment = document.createDocumentFragment();
                    for(let i = 0;i < batchSize;i++) {
                        const ndItem = document.createElement('li');
                        ndItem.innerText = (batchDone * batchSize) + i + 1;
                        fragment.appendChild(ndItem);
                    }
    
                    //每次批处理只修改1次DOM
                    ndContainer.appendChild(fragment);
    
                    batchDone += 1;
                    doBatchAppend();
                }
    
                function doBatchAppend() {
                    if(batchDone < batchCount) {
                        window.requestAnimationFrame(appendItems);
                    }
                }
    
                //kickoff
                doBatchAppend();
                ndContainer.addEventListener('click',function(e){
                    const target = e.target;
                    if(target.tagName === 'LI') {
                        alert(target.innerHTML);
                    }
                });
    
            })();
    </script>
    </body>
    </html>

     

  8. DOM树的遍历                                                                                                                          使用广度优先遍历BFS,

    <!DOCTYPE html>
    <html lang="zh">
    <title>往空的ul中插入值为1,2,3的li</title>
    <head>
    
    </head>
    <body>
       <div class="root">
        <div class="container">
            <section class="sidebar">
                <ul class="menu"></ul>
            </section>
            <section class="main">
                <article class="post"></article>
                <p class="copyright"></p>
            </section>
        </div>
    </div>
    <script>
       const traverse = (ndRoot) => {
        const stack = [ndRoot];
        while (stack.length) {
            const node = stack.shift();
            printInfo(node);
            if (!node.children.length) {
                continue;
            }
            Array.from(node.children).forEach(x => stack.push(x));
        }
    };
    
    const printInfo = (node) => {
        console.log(node.tagName, `.${node.className}`);
    };
    
    // kickoff
    traverse(document.querySelector('.root'));
    
    </script>
    </body>
    </html>

     

  9. DOM操作的函数或属性       

  10. 事件-如何使用事件及IE和标准DOM事件模型之间存在的差别                                                       

  11.                                            

标签: 前端面试
共有 人打赏支持
粉丝 1
博文 51
码字总数 13186
×
小木fan
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: