2012-11-23 30 views
0

我想动态加载CSS文件使用javascript,并且一会儿我认为它的工作。但在下一刻我意识到,页面上的元素没有从css文件中获得“宽度”。其他一切工作都可以。我从同一页面的Chrome浏览器中检查css,并且它已完全加载。我做错了什么?动态加载的CSS不设置宽度属性

脚本负载的CSS/JS文件(我发现它的网络):

function loadjscssfile(filename, filetype){ 
    if (filetype=="js"){ //if filename is a external JavaScript file 
     var fileref=document.createElement('script') 
     fileref.setAttribute("type","text/javascript") 
     fileref.setAttribute("src", filename) 
    } 
    else if (filetype=="css"){ //if filename is an external CSS file 
     var fileref=document.createElement("link") 
     fileref.setAttribute("rel", "stylesheet") 
     fileref.setAttribute("type", "text/css") 
     fileref.setAttribute("href", filename) 
    } 
    if (typeof fileref!="undefined") 
     document.getElementsByTagName("head")[0].appendChild(fileref) 
    } 
} 

而其他jQuery代码:

$(this).addClass('iG_Main'); 
loadjscssfile(data.theme_url,'css'); 
createGrid($($(this).selector+'.iG_Main')); 

function createGrid(selector){ 
    var cellWidth, columnValue; 
    var blank = ' '; 


    selector.append('<div class="iG_Header"></div>'); 
    selector.append('<div class="iG_Container"></div>'); 
    selector.append('<div class="iG_Footer">This is footer!</div>'); 
    selector_header = selector.children('.iG_Header'); 
    selector_container = selector.children('.iG_Container'); 
    selector_footer = selector.children('.iG_Footer'); 
    selector_header.append('<div class="iG_Cell iG_CheckBox inHead"><div id="iG_CheckBox">'+ blank +'</div></div>'); 

    if(undefinedVal(data.width)) 
     data.width = 1000; 
    if(undefinedVal(data.height)) 
     data.height = 400; 

    for(var i in data.headerData) 
     selector_header.append('<div id="'+ data.headerData[i].name +'" class="iG_Cell inHead"><div>'+ data.headerData[i].label +'</div></div>'); 

    if(data.options){ 
     selector_header.append('<div class="iG_Cell Options inHead"><div>'+ blank +'</div></div>'); 
    // cellWidth = (data.width-40-15)/(data.headerData.length); 
     cellWidth = (data.width-$('.iG_Cell.inHead.Options').width()-selector_header.children('.iG_CheckBox').width())/(data.headerData.length); 
    }else cellWidth = (data.width-15-selector_header.children('.iG_CheckBox').width())/(data.headerData.length); //15 - in sake of scrollbar 
    //}else cellWidth = (data.width-15-40)/(data.headerData.length); //15 - in sake of scrollbar 

    for(var i in data.contentData){ 
     selector_container.append('<div class="iG_Content"></div>'); 
     selector_container.children('.iG_Content:last-child').append('<div class="iG_Cell iG_CheckBox inContent"><div id="iG_CheckBox">'+ blank +'</div></div>'); 
     for(var j in data.headerData){ 
      columnValue = (undefinedVal(data.contentData[i][data.headerData[j].name])) ? blank : data.contentData[i][data.headerData[j].name]; 
      selector_container.children('.iG_Content:last-child').append('<div class="iG_Cell"><div>'+ columnValue +'</div></div>'); 
     } 


    selector.css({'width':data.width, 'height':data.height}); 
    selector_header.children('.iG_Cell').not('.Options').not('.iG_CheckBox').css('width',cellWidth); 
    selector_container.children('.iG_Content').children('.iG_Cell').not('.iG_CheckBox').css('width',cellWidth); 
    selector_container.css('height', data.height-selector_header.height()-selector_footer.height()); 
} 
+0

CSS是异步加载的,所以你的代码可能会在css完全加载和应用之前执行。尝试在'setTimeout'中包装'createGrid'调用几秒钟来测试这个问题? – Inferpse

+0

确定使用setTimeout()我调用createGrid()函数。它以这种方式工作。但这不是最好的方式,对吗?如何避免这种情况?谢谢 – Clem

+0

添加了代码示例的答案。 – Inferpse

回答

1

既然你加载CSS的方式从是异步的JS执行可能发生代码在加载CSS之前执行。

为了避免这样的问题,我会创建一个内联样式,对CSS文件做一个XHR请求并将内容放到样式元素中,例如,像这样:

$.get(the_url, function(response) { 
    $('head').append('<style id="the_theme"></style>'); 
    $('#the_theme').text(response); 

    // do the rest 
}); 

编辑:当然这可能会导致相对URL的问题与现在相对于您的文档,不再是您的CSS文件。如果这是你的问题,你必须这样做,复杂的方法:检查规则长度区间:

cssLoaded = 0; 
var iv = window.setInterval(function() { 
    var cssStylesheet = document.getElementById("the_link_element"); 
    if(cssStylesheet.sheet && cssStylesheet.sheet.cssRules.length > 0) { 
    cssLoaded = 1; 
    } 
    else if(cssStylesheet.styleSheet && cssStylesheet.styleSheet.cssText.length > 0) { 
    cssLoaded = 1; 
    } 
    else if(cssStylesheet.innerHTML && cssStylesheet.innerHTML.length > 0) { 
    cssLoaded = 1; 
    } 

    if(cssLoaded) { 
    window.clearInterval(iv); 
    } 
}, 500); 
+0

这是好方法。但是使用内联'