前端开发学习之——利用模板实现涉及url问题时的bug分析及解决(chrome源码)

例如我们要实现如下页面,其中历史页面列表想来自底层返回的数据,此处用testData代替:

最初我写的实现代码如下:

html文件:

<!doctype html>
<html class="starting-up" i18n-values="dir:textdirection; lang:language">
  <head>
    <meta charset="utf-8">
    <title i18n-content="title"></title>
    <link rel="stylesheet" type="text/css" href="last_tabs_list.css">
    <link rel="stylesheet" href="cdosbrowser://resources/css/tree.css">
    <link rel="stylesheet" href="cdosbrowser://resources/css/widgets.css">
    <script src="cdosbrowser://resources/js/cr.js"></script>
    <script src="cdosbrowser://resources/js/cr/ui.js"></script>
    <script src="cdosbrowser://resources/js/cr/ui/tree.js"></script>
    <script src="cdosbrowser://resources/js/util.js"></script>
   <script src="cdosbrowser://resources/js/icon.js"></script>

  </head>
  <body>
  <div class="container">
    <div class="nav_container">
        <div class="top_nav">
            <p>上次未关闭的页面</p>
        </div>
    </div>

    <div class="content">
        <div class="content_top">
            <div class="select_all_container">
                <input type="checkbox" id="check_all"></input>
                <span class="select_all">全选</span>
            </div>
            <div class="open_selected_tabs">
                <button class="open_all_selected" id="open_all_selected">打开选中页面</button>
            </div>
        </div>        
        <div id="tabs_list" class="tabs_list">
            <div class="tab_container" id="tab_{{index}}">
                <input type="checkbox" class="check" id="check_{{index}}"></input>
                <div class="favicon" style="background-image: {{bgimage}};"></div>
                <!--<div class="favicon" style='background-image: {{bgimage}};'></div>-->
                <div class="title">
                    <a href="{{url}}" target="_blank" title="{{title}}" focus-type="title" tabindex="0">{{title}}</a>
                </div>
            </div> 
        </div>
    </div>
    </div>
    <script src="last_tabs_list.js"></script    

 

js文件:

    var testData =
     [ {
       title: "历史记录",
       url: "cdosbrowser://history-frame/#range=3&offset=3"
    }, 
    {
       title: "cdosbrowser://help",
       url: "cdosbrowser://help/"
    },
     {
       title: "百度一下,你就知道",
       url: "https://www.baidu.com/"
    }, 
    {
       title: "爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看",
       url: "http://www.iqiyi.com/"
    } ]
    
    function checkAll(){
        console.log("checkEl.length="+checkEl.length);
        if(checkAllEl.checked){
            for(var i=0; i<checkEl.length; i++){
                checkEl[i].checked = true;
                console.log(checkEl.length);
                console.log(checkEl[i].checked);
            }
        }else{
            for(var i=0; i<checkEl.length; i++){
                checkEl[i].checked = false;
                $("open_all_selected").disabled = true;
            }
        }
        updateButtonStatus();
    }

    function tabsListDOM(data){
        var tabsListTemplate = $("tabs_list").innerHTML;
        var wrap=[];
        for(var i=0; i<data.length; i++){
            var backgroundImage  = cr.icon.getFavicon(data[i].url);
            var _tabsListTemplate  =   tabsListTemplate.replace(/{{index}}/g,i)
                                                       .replace(/{{url}}/,data[i].url)
                                                       .replace(/{{bgimage}}/,backgroundImage)
                                                       .replace(/{{title}}/g,data[i].title);
            
            wrap.push(_tabsListTemplate);
        }
        $("tabs_list").innerHTML = wrap.join('');
        //console.log("wrap.join('')="+wrap.join(''));
        //console.log("$('tabs_list').innerHTML="+$("tabs_list").innerHTML);
        checkEl = $("tabs_list").querySelectorAll(".check");
         checkAllEl = $("check_all");
        checkAllEl.checked =true;
        checkAll();
    }
    tabsListDOM(testData);

    function updateButtonStatus(){
        var anyChecked = document.querySelectorAll('#tabs_list input:checked') .length!= 0;
        $('open_all_selected').disabled = !anyChecked;
        console.log("anyChecked="+anyChecked);
    }

    function checkOne(){
        var flag = true;
        for(var i=0; i<checkEl.length; i++){
            if(!checkEl[i].checked){
                flag = false;
            }
        }
        if(flag){
            checkAllEl.checked = true;
        }else{
            checkAllEl.checked = false;
        }
        updateButtonStatus();
    }

    function openAllSelected(){
        var selectedUrl=[];
        for(var i=0; i<checkEl.length; i++){
            if(checkEl[i].checked){
                selectedUrl.push(testData[i].url);
                console.log(testData[i].url);
            }
        }
    }

    checkAllEl.addEventListener("click", checkAll);

    for(var i=0; i<checkEl.length; i++){
        checkEl[i].addEventListener("click", checkOne);
    }

    if((!$('open_all_selected').disabled)){
        $("open_all_selected").addEventListener("click", openAllSelected);    
    }

打印结果如下:

其中cr.icon.getFavicon(data[i].url)返回的数据是url("cdosbrowser://favicon/http://www.iqiyi.com/")

wrap.join('')=
            <div class="tab_container" id="tab_0">
                <input type="checkbox" class="check" id="check_0">
                <div class="favicon" style="background-image: url("cdosbrowser://favicon/cdosbrowser://history-frame/#range=3&offset=3");"></div>
                <div class="title">
                    <a href="cdosbrowser://history-frame/#range=3&offset=3" target="_blank" title="历史记录" focus-type="title" tabindex="0">历史记录</a>
                </div>
            </div>
        
            <div class="tab_container" id="tab_1">
                <input type="checkbox" class="check" id="check_1">
                <div class="favicon" style="background-image: url("cdosbrowser://favicon/cdosbrowser://help/");"></div>
                <div class="title">
                    <a href="cdosbrowser://help/" target="_blank" title="cdosbrowser://help" focus-type="title" tabindex="0">cdosbrowser://help</a>
                </div>
            </div>
        
            <div class="tab_container" id="tab_2">
                <input type="checkbox" class="check" id="check_2">
                <div class="favicon" style="background-image: url("cdosbrowser://favicon/https://www.baidu.com/");"></div>
                <div class="title">
                    <a href="https://www.baidu.com/" target="_blank" title="百度一下,你就知道" focus-type="title" tabindex="0">百度一下,你就知道</a>
                </div>
            </div>
        
            <div class="tab_container" id="tab_3">
                <input type="checkbox" class="check" id="check_3">
                <div class="favicon" style="background-image: url("cdosbrowser://favicon/http://www.iqiyi.com/");"></div>
                <div class="title">
                    <a href="http://www.iqiyi.com/" target="_blank" title="爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看" focus-type="title" tabindex="0">爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看</a>
                </div>
            </div>
        
$('tabs_list').innerHTML=
<div class="tab_container" id="tab_0"> <input type="checkbox" class="check" id="check_0"> <div class="favicon" style="background-image: url(" cdosbrowser:="" favicon="" history-frame="" #range="3&amp;offset=3&quot;);&quot;"></div> <div class="title"> <a href="cdosbrowser://history-frame/#range=3&amp;offset=3" target="_blank" title="历史记录" focus-type="title" tabindex="0">历史记录</a> </div> </div> <div class="tab_container" id="tab_1"> <input type="checkbox" class="check" id="check_1"> <div class="favicon" style="background-image: url(" cdosbrowser:="" favicon="" help="" ");"=""></div> <div class="title"> <a href="cdosbrowser://help/" target="_blank" title="cdosbrowser://help" focus-type="title" tabindex="0">cdosbrowser://help</a> </div> </div> <div class="tab_container" id="tab_2"> <input type="checkbox" class="check" id="check_2"> <div class="favicon" style="background-image: url(" cdosbrowser:="" favicon="" https:="" www.baidu.com="" ");"=""></div> <div class="title"> <a href="https://www.baidu.com/" target="_blank" title="百度一下,你就知道" focus-type="title" tabindex="0">百度一下,你就知道</a> </div> </div> <div class="tab_container" id="tab_3"> <input type="checkbox" class="check" id="check_3"> <div class="favicon" style="background-image: url(" cdosbrowser:="" favicon="" http:="" www.iqiyi.com="" ");"=""></div> <div class="title"> <a href="http://www.iqiyi.com/" target="_blank" title="爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看" focus-type="title" tabindex="0">爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看</a> </div> </div>

由上可见background-image的赋值产生了问题,而且神奇的是wrap.join('')打印的结果竟然和$('tabs_list').innerHTML不一样,而且前者看上去好像还是对的,后者已然是乱码。

这是为什么呢?

实际上wrap.join('')将模板拼接的时候还只是进行的字符串的运算,只是把我们组合的内容按部就班的展示给我们,但是赋值给innerHTML的时候就存在一个解析的过程了。

而且其实在wrap.join('')打印的时候就能看出问题所在了,双引号包裹双引号产生的冲突,导致浏览器没办法正常解析。而且即使把外层的双引号改成单引号,打印结果仍然是双引号,不知道是否跟chrome内部有关。

<div class="favicon" style="background-image: {{bgimage}};"></div>
<!--<div class="favicon" style='background-image: {{bgimage}};'></div>-->

解决办法:

法一:将除background-image之外的其他DOM结构构建好,再动态设置其background-image。

法二:将整个模板直接作为变量,实现如下:

<!doctype html>
<html class="starting-up" i18n-values="dir:textdirection; lang:language">
  <head>
    <meta charset="utf-8">
    <title i18n-content="title"></title>
    <link rel="stylesheet" type="text/css" href="last_tabs_list.css">
    <link rel="stylesheet" href="cdosbrowser://resources/css/tree.css">
    <link rel="stylesheet" href="cdosbrowser://resources/css/widgets.css">
     <script src="cdosbrowser://resources/js/cr.js"></script>
    <script src="cdosbrowser://resources/js/cr/ui.js"></script>
    <script src="cdosbrowser://resources/js/cr/ui/tree.js"></script>
    <script src="cdosbrowser://resources/js/util.js"></script>
<script src="cdosbrowser://resources/js/icon.js"></script>

  </head>
  <body>
  <div class="container">
    <div class="nav_container">
        <div class="top_nav">
            <p>上次未关闭的页面</p>
        </div>
    </div>

    <div class="content">
        <div class="content_top">
            <div class="select_all_container">
                <input type="checkbox" id="check_all"></input>
                <span class="select_all">全选</span>
            </div>
            <div class="open_selected_tabs">
                <button class="open_all_selected" id="open_all_selected">打开选中页面</button>
            </div>
        </div>        
        <div id="tabs_list" class="tabs_list">
        </div>
    </div>
    </div>
    <!-- <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script> -->
    <script src="last_tabs_list.js"></script>
  </body>
</html>

js代码如下:

//cr.define('last_tabs_list', function(){
//    'use strict'

    var testData =
     [ {
       title: "历史记录",
       url: "cdosbrowser://history-frame/#range=3&offset=3"
    }, 
    {
       title: "cdosbrowser://help",
       url: "cdosbrowser://help/"
    },
     {
       title: "百度一下,你就知道",
       url: "https://www.baidu.com/"
    }, 
    {
       title: "爱奇艺-全球领先的在线视频网站-海量正版高清视频在线观看",
       url: "http://www.iqiyi.com/"
    } ]
    
    
    function checkAll(){
        console.log("checkEl.length="+checkEl.length);
        if(checkAllEl.checked){
            for(var i=0; i<checkEl.length; i++){
                checkEl[i].checked = true;
                console.log(checkEl.length);
                console.log(checkEl[i].checked);
            }
        }else{
            for(var i=0; i<checkEl.length; i++){
                checkEl[i].checked = false;
                $("open_all_selected").disabled = true;
            }
        }
        updateButtonStatus();
    }

    function tabsListDOM(data){
        var tabsListTemplate = '<div class="tab_container" id="tab_{{index}}">' +
                '<input type="checkbox" class="check" id="check_{{index}}"></input>'+
                "<div class='favicon' style='background-image: {{bgimage}};'></div>" +
                '<div class="title">' +
                    '<a href="{{url}}" target="_blank" title="{{title}}" focus-type="title" tabindex="0">{{title}}</a>'+
                '</div>' +
            '</div>';
        var wrap=[];
        for(var i=0; i<data.length; i++){
            var backgroundImage  = cr.icon.getFavicon(data[i].url);
            var _tabsListTemplate  =   tabsListTemplate.replace(/{{index}}/g,i)
                                                       .replace(/{{url}}/,data[i].url)
                                                       .replace(/{{bgimage}}/,backgroundImage)
                                                       .replace(/{{title}}/g,data[i].title);
            
            wrap.push(_tabsListTemplate);
        }
        $("tabs_list").innerHTML = wrap.join('');
        console.log("wrap.join('')="+wrap.join(''));
        console.log("$('tabs_list').innerHTML="+$("tabs_list").innerHTML);
        checkEl = $("tabs_list").querySelectorAll(".check");
         checkAllEl = $("check_all");
        checkAllEl.checked =true;
        checkAll();
    }
    tabsListDOM(testData);

    function updateButtonStatus(){
        var anyChecked = document.querySelectorAll('#tabs_list input:checked') .length!= 0;
        $('open_all_selected').disabled = !anyChecked;
        console.log("anyChecked="+anyChecked);
    }

    function checkOne(){
        var flag = true;
        for(var i=0; i<checkEl.length; i++){
            if(!checkEl[i].checked){
                flag = false;
            }
        }
        if(flag){
            checkAllEl.checked = true;
        }else{
            checkAllEl.checked = false;
        }
        updateButtonStatus();
    }

    function openAllSelected(){
        var selectedUrl=[];
        for(var i=0; i<checkEl.length; i++){
            if(checkEl[i].checked){
                selectedUrl.push(testData[i].url);
                console.log(testData[i].url);
            }
        }
    }

    checkAllEl.addEventListener("click", checkAll);

    for(var i=0; i<checkEl.length; i++){
        checkEl[i].addEventListener("click", checkOne);
    }

    if((!$('open_all_selected').disabled)){
        $("open_all_selected").addEventListener("click", openAllSelected);    
    }
//});

//document.addEventListener('DOMContentLoaded', last_tabs_list.onLoad);

 

posted on 2017-04-13 12:11  P妞酱儿  阅读(527)  评论(0编辑  收藏  举报

导航