• js问题总结


    1. Call 和 Apply 的区别

    语法:
    function.call(thisObj [, arg1[, arg2[, [, ...argN]]]]);
    function.apply(thisObj [, argArray] );

    定义: call 和 apply 可以让我们手动设置 this 指向
    两个参数: 第一个参数是 绑定 this 指向;第二个参数是 向将要执行的函数传递的参数
    区别: 第二个参数, call 以一个一个的形式传递参数;apply 以数组的形式传递参数

    复制代码
    var a = 10;
    function sum(num1, num2) {
        console.log(this.a + num1 + num2);
    }
    var obj = {
        a: 20
    }
    
    sum(10, 10);    //30
    sum.call(obj, 10, 10);       // 40
    sum.apply(obj, [10, 10]);    // 40
    复制代码

    2. 键盘事件属性

    event.keyCode;    // 获取按下的键盘按键的键码值(Unicode值)
    event.ctrlKey;    // 获取是否按下了ctrl键
    event.shiftKey;   // 获取是否按下了shift键
    event.altKey;     // 获取是否按下了alt键
    event.metaKey;    // 获取是否按下了meta键

    3. 鼠标事件属性

    event.screenX/event.screenY     // 获取鼠标基于屏幕的X轴/Y轴坐标
    event.clientX/event.clientY     // 获取鼠标基于浏览器窗口的X轴/Y轴坐标
    event.pageX/event.pageY         // 获取鼠标基于文档的X轴/Y轴坐标
    
    event.button   // 获取鼠标按下的键。非IE浏览器中0为鼠标左键,1为鼠标中键,2为鼠标右键
    event.which    // 获取指定事件上哪个键盘键或鼠标按钮被按下

    4. addEventListener 和 attachEvent 区别

    attachEvent方法适用于IE
    attachEvent中的事件带on, 而addEventListener中的事件不带on
    attachEvent 方法有两个参数:第一个参数为事件名称,第二个参数为接收事件处理的函数; addEventListener 方法有三个参数:第一个参数为事件名称(不含 on,如 "click"),第二个参数为要接收事件处理的函数,第三个参数为一个bool值,默认为false

      1. 添加多个事件处理程序执行的顺序不同

    复制代码
    addEventListener: 
    var btn=document.getElementById("myBtn");  
    btn.addEventListener("click",function(){  
        alert(1);     
        },false);  
      
    btn.addEventListener("click",function(){  
          alert(2);     
        },false); 
    
    //执行结果 1 ,2
    复制代码
    复制代码
    attachEvent: 
    var btn=document.getElementById("myBtn");  
     btn.attachEvent("onclick",function(){  
         alert(1);     
       });  
     btn.attachEvent("onclick",function(){  
         alert(2);     
       });  
    
    //执行结果 2 ,1
    复制代码

      2. 事件处理程序的作用域不同

    DOM2级事件添加的事件处理程序,它的作用域是所属的元素,而IE的事件处理程序会在全局作用域中运行。

    addEventListener: 
    var btn=document.getElementById("myBtn");  
    btn.addEventListener("click",function(){  
        console.log(this.id);    // myBtn   
        },false);  
    attachEvent: 
    var btn=document.getElementById("myBtn");  
    btn.attachEvent("onclick",function(){  
      alert(this===window);    // true   
      });  

      3. 移除绑定事件 removeEventListener() 和 detachEvent()

    复制代码
    移除 addEventListener 事件:
    element.removeEventListene(event, function, useCapture)
    event: 事件名,注意不使用“on”前缀,如 click
    function: 指定事件触发时执行的函数
    useCapture: 指定事件是否在捕获或冒泡阶段执行
    true: 在捕获阶段执行
    false: 在冒泡阶段进行,默认值为false
    如果添加时用的捕获阶段,那么在移除时也要用捕获阶段,否则无法移除它们
    如果是同一个元素同一个调用函数同一个useCapture值绑定多次,在移除时只需要执行一次移除
    复制代码
    移除 attachEvent 事件:
    element.detachEvent(event, function)
    event: 事件名,注意要使用“on”前缀,如 onclick
    function: 指定事件触发时执行的函数

     5. addEventListener 和 on 区别

    1
    <div id="box">addEventListener 和 on 区别</div>
    复制代码
    window.onload = function(){
         var box = document.getElementById("box");
         box.onclick = function(){
             console.log("我是box1");
         }
         box.onclick = function(){
             console.log("我是box2");
         }
    }
    
    //运行结果:“我是box2”
    复制代码
    复制代码
     window.onload = function(){
         var box = document.getElementById("box");
         box.addEventListener("click", function(){
             console.log("我是box1");
         })
         box.addEventListener("click", function(){
             console.log("我是box2");
         })
    }
    运行结果:我是box1
         我是box2
    复制代码

    第二个onclick会把第一个onclick给覆盖了,虽然大部分情况我们用on就可以完成我们想要的结果,但是有时我们又需要执行多个相同的事件,很明显如果用on完成不了我们想要的,而addEventListener可以多次绑定同一个事件并且不会覆盖上一个事件。

    6. HTML5 新增的事件

    contextmenu事件
    这个事件是当鼠标右击的时候触发的,但是触发这个属性的时候默认的行为也会被触发,所以需要通过preventDefault()方法来阻止。

    beforeunload事件
    beforeunload在页面卸载之前触发,该事件会弹出一个对话框,询问是否确定离开。

    hashchange事件
    该事件当URL中的hash值改变时触发,通常用于Ajax应用中利用URL参数保存导航信息;这个在前端路由的制作中是非常有用得。

    7. 阻止事件默认行为和阻止事件冒泡

    1
    2
    3
    4
    <div id="wrap" style=" 200px; height: 200px; background: gray;">
        <div id="btn" style=" 100px; height: 100px; background: orangered;"></div>
        <a id="prevent" target="_blank" href="http://www.baidu.com">preventDefault</a>
    </div>

    标准浏览器的使用方法

    preventDefault(): 用于阻止事件的默认行为;
    比如: a 链接的跳转行为和表单自动提交行为  

    var prevent = document.getElementById("prevent");
        prevent.addEventListener("click", function(event){
            event.preventDefault();
        }, false);
    
    //使用preventDefault()方法就阻止了a标签打开新窗口的默认行为 

    stopPropagation(): 用于阻止事件的进一步获取和传播;
    比如:阻止事件继续向上层冒泡

    复制代码
    var btn = document.getElementById("btn"),
        wrap= document.getElementById("wrap");
        btn.addEventListener("click",function(event){
            alert("btn");
            event.stopPropagation();
        },false);
        wrap.addEventListener("click",function(){
            alert("wrap");
        },false);
    
    //点击btn时,这样就阻止了id="btn"向上级id="wrap"冒泡,打印出来的结果是:弹窗仅弹出btn。否则,将会先弹出btn,然后弹出wrap。
    复制代码

    低版本IE浏览器的使用方法

    event.returnValue = false;   //阻止事件的默认行为;
    event.cancelBubble = true;   //阻止事件的进一步获取或者冒泡;

    示例

    复制代码
    function prevent(event) {
        event = event || window.event;
        if(event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false; 
        }
    }
    //使用 if else 去判断
    复制代码

    8. 事件捕获和事件冒泡

    事件冒泡执行过程:从最具体的的元素(你单击的那个元素)开始向上开始冒泡,下面的案例的顺序是:content > wrap
    事件捕获执行过程:从最不具体的元素(最外面的那个盒子)开始向里面冒泡,下面的案例的顺序是:wrap > content

    1
    2
    3
    <div id="wrap">
        <div id="content"></div>
    </div>
    复制代码
    (addEventListener第三个参数写的是false, 默认为false)
     window.onload = function(){
         var wrap= document.getElementById("wrap");
         var content= document.getElementById("content");
         wrap.addEventListener("click", function(){
             console.log("我是wrap");
         }, false)
         content.addEventListener("click", function(){
             console.log("我是content");
         })
    }
    运行结果:我是content
         我是wrap
    复制代码
    复制代码
    (addEventListener第三个参数写的是true, 默认为false)
      window.onload = function(){
         var wrap= document.getElementById("wrap");
         var content= document.getElementById("content");
         wrap.addEventListener("click", function(){
             console.log("我是wrap");
         }, true)
         content.addEventListener("click", function(){
             console.log("我是content");
         })
    }
    运行结果:我是wrap
         我是content
    复制代码

    第三个参数写的是true,则按照事件捕获的执行顺序进行。

      

     9. 给 select 标签 option 内容加链接

    1
    2
    3
    4
    <select onchange="window.open(options[selectedIndex].value, '_self')">
        <option value="http://www.bj-hmk.com/">中文</option>
        <option value="http://en.bj-hmk.com/">English</option>
    </select>

      

    10. Null 和 Undefined

    undefined 表示根本不存在定义
    null 表示一个值被定义了,定义为“空值”

    (1)变量被声明了,但没有赋值时,就等于undefined。
    (2)调用函数时,应该提供的参数没有提供,该参数等于undefined。
    (3)对象没有赋值的属性,该属性的值为undefined。
    (4)函数没有返回值时,默认返回undefined。

    所以设置一个值为 null 是合理的,如
    objA.valueA = null;

    但设置一个值为 undefined 是不合理的,如
    objA.valueA = undefined; // 应该直接使用 delete objA.valueA; 任何一个存在引用的变量值为undefined都是一件错误的事情。
    这样判断一个值是否存在,就可以用
    objA.valueA === undefined // 不应使用 null 因为 undefined == null,而 null 表示该值定义为空值。

    11. 解决slideDown()和slideUp()鼠标快速移入移出,出现反复执行的问题

    复制代码
    方法一:
    $(".orderDivMain").hover(function () {
        if (!$(".orderDivId").is(":animated")) {
            $(this).find('.orderDivId').slideDown(500);
        }
    }, function () {
        if (!$(".orderDivId").is(":animated")) {
            $(this).find('.orderDivId').slideUp(500);
        }
    });
    
    方法二:
    $(".orderDivMain").hover(function () {
        $(".orderDivId").slideDown(500);
    });
    $(".orderDivId").mouseleave(function () {
        $(".orderDivId").slideUp(500);
    });
    复制代码

    12. web应用整体性能的考虑

    12 13两点 参考于 《JavaScript DOM编程艺术(第2版)》

    尽量少访问DOM和尽量减少标记

    if(document.getElementsByTagName("a").length > 0){
        var links = document.getElementsByTagName("a");
        for(var i = 0; i < links.length; i++){
            something...
        }
    }

    上面这段代码使用了两次getElementsByTagName方法去执行相同的操作,浪费了一次搜索。更好的办法是把第一次搜索的结果保存在一个变量中,然后重用该结果:

    var links = document.getElementsByTagName("a");
    if(links.length > 0){
        for(var i = 0; i < links.length; i++){
            something...
        }
    }

    合并和放置脚本

    <script src="js/functionA.js"></script>
    <script src="js/functionB.js"></script>
    <script src="js/functionC.js"></script>
    <script src="js/function.js"></script>

    上面两种做法,推荐的做法是把第一种functionA.js、functionB.js、functionC.js合并到一个脚本文件中。这样就可以减少加载页面时发送的请求数量,而减少请求数量通常都是性能优化时首先要考虑的。

    位于<head>块中的脚本会导致浏览器无法并行加载其他文件,把<script>标签放在</body>标记之前,就可以让页面变的更快。  

    13. 使你所写的页面能够向后兼容、平稳退化

    针对这一问题的最简单的解决方案是,检测浏览器对javascript的支持程度,即对象检测。几乎所有的东西(包括各种方法在内)都可以被当作对象来对待,这意味着我们可以很容易的把不支持某个特定的DOM方法的浏览器检测出来:

    if(method){
        statements
    }

    例如,检测浏览器是否支持getElementById方法:

    if(document.getElementById){
        statements using getElementById
    }

    但是如果需要检测多个DOM方法或者属性是否存在,那么最重要的语句可能会被深埋在一层又一层的花括号里,使得代码将会很难阅读和理解。

    那么就可以把测试的条件改为“如果你不理解这个方法,请离开”则会变得简单明了。

    if(!document.getElementById){
        return false;
    }

    若需要测试多个方法或属性是否支持,可以使用“逻辑或”操作符将其合并:

    if(!document.getElementById || !document.getElementsByTagName){
        return false;
    }

    14. jQuery中attr和prop的区别

    处理HTML元素本身就带有的固有属性时使用prop方法

    处理HTML元素我们自己定义的Dom属性时使用attr方法

    1
    2
    <input class='check1' type='checkbox'>选择1
    <input class='check2' type='checkbox' checked>选择2

    checked属于checkbox元素的固有属性,让我们来看看prop和attr的结果有什么不同:

    prop方法:
    $('.check1').prop('checked') -- false
    $('.check2').prop('checked') -- true 
    attr方法:
    $('.check1').attr('checked') -- undefined 
    $('.check2').attr('checked') -- 'checked'

    15. 在选中的元素上绑定事件和通过代理绑定事件的区别

    在选中的元素上绑定click事件:
    $('a').on('click', function(){});
    通过代理绑定click事件:
    $(document).on('click', 'a', function(){});

    在选中的元素上绑定事件只能为页面现有的a元素绑定点击事件,如果是动态生成的新的a元素是没有事件的。

    通过代理绑定事件是将指定的事件绑定在document上,新添加的a元素也能触发此事件。

    16. reload 方法,强迫浏览器刷新当前页面。

    语法:location.reload([falseOrTrue]) ;
    参数: falseOrTrue, 可选参数。 默认为 false,从客户端缓存里取当前页。true,则以 GET 方式,从服务端取最新的页面,相当于客户端点击 F5(“刷新”)。

    1
    2
    <a href="javascript:location.reload();">点击刷新页面</a>
    <span onclick="location.reload(true);">点击刷新页面</span>

     

    17. 禁止页面选取内容

    适用于IE、Chrome浏览器,在 head 的 <script> 标签里面添加 js 代码

    document.onselectstart = function (e) { return false; }
    或者
    document.onselectstart = new Function('event.returnValue = false;');

    在firefox火狐浏览器中,禁止元素被选取可以采用 CSS 样式在来控制

    body{
        -moz-user-focus: ignore;  
        -moz-user-input: disabled; 
        -moz-user-select: none;
    }

    禁止鼠标右键

    document.oncontextmenu = function(e){return false;}

    18. 正则表达式验证

    复制代码
    //  验证是否为手机号
    function phone(num) {
        return /^1[34578]d{9}$/.test(num);
    }
    
    //  验证是否为邮箱
    function email(e) {
        return /^(w)+(.w+)*@(w)+((.w+)+)$/.test(e);
    }
    复制代码

    19. 返回顶部

    复制代码
    window.onscroll = function () {
        if (document.body.scrollTop || document.documentElement.scrollTop > 0) {
            document.getElementById('back_top').style.display = "block";
        } else {
            document.getElementById('back_top').style.display = "none";
        }
    }
    $('.back_top').click(function () {
        $("html,body").animate({ scrollTop: 0 }, 500);
        return false;
    });
    复制代码

    20. js 中 Error 错误

    ReferenceError:作用域判别错误,通过作用域链的搜寻找不到相应的变量。

    TypeError:可以通过作用域搜索到变量,但是对变量的操作不合法。

    SyntaxError:语法错误。

    如果真的不知道将来要做什么,索性就先做好眼前的事情。只要今天比昨天过得好,就是进步。长此以往,时间自然会还你一个意想不到的未来。
    生活像一个杯子。一开始,里面是空的,之后,要看你怎么对待它。如果你只往不如意的方面想,那么你最终辉得到一杯苦水。如果你往好的方面想,那么你最终会得到一杯清泉。
    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
  • 相关阅读:
    Scala之eq,equals,==的区别
    Spark Streaming流计算特点及代码案例
    刷题50—水壶问题
    刷题49(力扣3道题)
    刷题48——最长回文串
    刷题47——矩形重叠
    刷题46——拼写单词
    刷题45(力扣两道题)
    刷题44——岛屿的最大面积
    刷题43——最长上升子序列
  • 原文地址:https://www.cnblogs.com/lipengze/p/11461179.html
Copyright © 2020-2023  润新知