• 积累js中的一些问题及解决方案


    一.取字符串的第i位不兼容的问题

    1.问题:对于字符串str来说,要获取第i位,常见的是str[i],但是在低版本的浏览器中不兼容,例如ie7。

    2.解决:使用str.charAt(i);

    二.使用定时器,第一次执行也会延时

    1.问题:在实现数码时钟的时候,想要1s刷新一次当前时间,因此将刷新的代码写在一个1s执行一次的定时器中,但是第一次打开页面,第一次刷新时间的时候仍然需要1s才能显示出当前时间,我们希望的是第一次不用等待,直接显示当前时候,以后才是1s刷新一次。

    2.解决方案:首先将该函数写在定时器的外面,然后在window.onload里加上函数的调用。

    即类似于

    window.onload=function ()
    {
       //定义执行函数
       function tick(){
       //具体实现
       }
      //定时器
      setInterval(tick,1000);
      //调用执行函数
      tick();
    };

    完整代码如下:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script>
    //将一位数字补零变成2位
    function toDou(n){
        if(n<10){
          return ''+n;    
        }else{
          return n+"";    
        }
    }
    window.onload=function ()
    {
        var aImg=document.getElementsByTagName('img');
        function tick(){
        //根据系统时间修改字符串
        //var str='012321';
        var oDate=new Date();
        //问题1:这里获得的是number类型
        //问题2:如果是01只会获得1
        
        var str=toDou(oDate.getHours())+toDou(oDate.getMinutes())+toDou(oDate.getSeconds());
        //alert(str);
        for(var i=0;i<aImg.length;i++)
        {
            aImg[i].src='img/'+str.charAt(i)+'.png';    
        }
            }
        
        setInterval(tick,1000);
        //这样可以保证第一次执行该代码不需要等待
        tick();
        
    };
    </script>
    </head>
    
    <body style="background:black;color:white;font-size:50px;">
    <img src="img/0.png" />
    <img src="img/0.png" />
    :
    <img src="img/0.png" />
    <img src="img/0.png" />
    :
    <img src="img/0.png" />
    <img src="img/0.png" />
    </body>
    </html>
    数码时钟

    三.解决使用childNodes对子节点操作的问题

    1.问题:使用childNodes对子节点操作时,对子节点不起作用,并且会报错。

    <script>
    window.onload=function ()
    {
        var oUl=document.getElementById('ul1');
        //会将空隙(空的文本节点)也记为1个子节点
        //alert(oUl.childNodes.length);    
        
        for(var i=0;i<oUl.childNodes.length;i++){
            oUl.childNodes[i].style.background='red';
        
        }
    };
    </script>
    View Code

    2.解决办法:原因在于childNodes会将空的文本节点也记为一个子节点,文本节点当然没有background属性。

    可以使用nodeType属性进行过滤,nodeType==1是元素节点,nodeType==3是文本节点。

    因此可以将上述代码改为:

    <script>
    window.onload=function ()
    {
        var oUl=document.getElementById('ul1');
        //会将空隙(空的文本节点)也记为1个子节点
        //alert(oUl.childNodes.length);    
        
        for(var i=0;i<oUl.childNodes.length;i++){
            //oUl.childNodes[i].style.background='red';
            //nodeType==1  ->    元素节点
            //nodeType==3    ->    文本节点
            //alert(oUl.childNodes[i].nodeType);
            if(oUl.childNodes[i].nodeType==1){
                oUl.childNodes[i].style.background='red';
            }    
        }
    };
    </script>
    View Code

     另一种方式是将childNodes替代为children,就不存在上述问题

    <script>
    window.onload=function ()
    {
        var oUl=document.getElementById('ul1');
        alert(oUl.children.length);    
        for(var i=0;i<oUl.children.length;i++){
                oUl.children[i].style.background='red';
        }
    };
    </script>
    View Code

    四.对第一个子元素进行操作的兼容性问题

    1.问题:想对第一个子元素进行操作,出现兼容性问题,即firstChild只适合低版本浏览器(因为对于高版本浏览器来说,类似于三的问题,firstChild也是对那个空的文本节点进行操作,因此报错),如IE6-8,而类似功能的firstElementChild只适合高版本浏览器,如IE9以上,火狐和谷歌。

    2.解决办法,可以利用简单的if..else语句,判断firstElementChild是否为真,从而选用不同的操作方法。

    <script>
    window.onload=function (){
        var oUl=document.getElementById('ul1');
        
        //只适合低版本(IE6-8)
        //OUl.firstChild.style.background='red';
        
        //只适合高版本浏览器
        //oUl.firstElementChild.style.background='red';
        if(oUl.firstElementChild)
        {oUl.firstElementChild.style.background='red';    
        }else{
         oUl.firstChild.style.background='red';    
        }
    };
    </script>
    View Code

     3.类似的问题,如下所示:

    五.想往最前面插入新的元素,而不是后面

    1.问题:做仿新浪的项目时,每次发表一条微博,在前面显示。使用appendChild是在最后面插,我们想要的是最新的能在最前面显示。

    window.onload=function (){
        var oBtn=document.getElementById('btn1');
        var oUl=document.getElementById('ul1');
        var oTxt=document.getElementById('txt1');
        
        oBtn.onclick=function (){
            //创建新的li
            var oLi=document.createElement('li');
            oLi.innerHTML=oTxt.value;
            oTxt.value='';
            
            oUl.appendChild(oLi);
        };
    };
    原始

    2.使用insertBefore即可解决该问题,注意条件的判断。

    window.onload=function (){
        var oBtn=document.getElementById('btn1');
        var oUl=document.getElementById('ul1');
        var oTxt=document.getElementById('txt1');
        
        oBtn.onclick=function (){
            //创建新的li
            var oLi=document.createElement('li');
            oLi.innerHTML=oTxt.value;
            oTxt.value='';
            
            //oUl.appendChild(oLi);
            if(oUl.children.length>0){
                oUl.insertBefore(oLi,oUl.children[0]);    
            }
            else{
                oUl.appendChild(oLi);
            }
        };
    };
    View Code

    3.效果:

     

    六.兼容的获取事件对象

    var oEvent=event||ev;

    七.兼容的创建ajax对象

    1.new XMLHttpRequest()适用于非ie6的大多数情况,而new ActiveXObject("Microsoft.XMLHTTP")只适用于ie6的情况

    2.代码:

            if(window.XMLHttpRequest){
            var oAjax=new XMLHttpRequest();
            }else{
            var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
            }
    View Code

    3.这里必须加window.,因为在js中未定义的变量会报错,而未定义的属性才不会报错而是显示undefined,而所有的变量都是window的属性,所以加了window.才能解决ie6的兼容性问题。

  • 相关阅读:
    如何在perl中一次执行多条shell命令
    Spring.netAOP 搭建网站通知服务(1)
    使用Spring.net AOP 实现积分服务
    我得第一帖@2011
    ADO.NET+存储过程+事务的一个奇怪问题,求探讨
    (一)项目说明及程序框架说明——.NET开发完整案例(企业邮箱系统)
    2.系统设置网站配置网站信息配置
    .NET企业邮箱系统项目说明及文章索引——20118.13更新
    .Net内容管理系统开发实例项目说明及文章索引——2011825更新
    后端小记录
  • 原文地址:https://www.cnblogs.com/sunnyCx/p/8439681.html
Copyright © 2020-2023  润新知