前端開發學習之——利用模板實現涉及url問題時的bug分析及解決(chrome源碼)

例如咱們要實現以下頁面,其中歷史頁面列表想來自底層返回的數據,此處用testData代替:css

最初我寫的實現代碼以下:html

html文件:jquery

<!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文件:chrome

    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不同,並且前者看上去好像仍是對的,後者已然是亂碼。ui

這是爲何呢?url

實際上wrap.join('')將模板拼接的時候還只是進行的字符串的運算,只是把咱們組合的內容循序漸進的展現給咱們,可是賦值給innerHTML的時候就存在一個解析的過程了。spa

並且其實在wrap.join('')打印的時候就能看出問題所在了,雙引號包裹雙引號產生的衝突,致使瀏覽器沒辦法正常解析。並且即便把外層的雙引號改爲單引號,打印結果仍然是雙引號,不知道是否跟chrome內部有關。3d

<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);
相關文章
相關標籤/搜索