2013-04-23 67 views
1

我的递归函数正在崩溃,我找不到原因。我正在尝试为json编写一个解析器,以便使用准系统JavaScript,并且似乎无法包装我的头以解释为什么我的函数无法正常工作。任何人都可以借我一只手吗?JSON CSS解析器

在CSS中你会得到属于你的东西解决这样的

#nav li{ 
    some style here 
} 

试图操纵JavaScript中的同样的事情只有它不工作的特定元素的子元素。我的代码到目前为止简单的选择器工作正常。

var json = { 
    "body" : { 
     "background": "#303030", 
     "color": "#FFFFFF", 
     "font-family": "Arial, Helvetica, sans-serif" 
    }, 
    "#nav": { 
     "li": { 
      "display": "inline-block", 
      "list-styles": "none", 
      "margin-right": "10px", 
      "padding": "10px, 10px" 
     } 
    } 
} 
// How to use: 
// json is an obj 
// body is a selector 
// background is a property belong to a selector 
// #303030 is a value for the property 


//apply css changes to document without writing any css 
//by default the first values are 
//    selector = background 
//    parent = document 
//    object = json 
function styleApply(selector, parent, object){ 
    var element, onSelector, signal; 

    //checks the first character of the selector and grabs element from page depending on what type of element it is 
    switch(selector[0]){ 
     case ".": 
      element= parent.getElementsByClassName(selector.substring(1)); 
      newParent = element[0]; //checks to see what is in the first index of the obtained element 
      break; 
     case "#": 
      element= parent.getElementById(selector.substring(1)); 
      newParent = element; 
      break; 
     default: 
      element= parent.getElementsByTagName(selector); 
      newParent = element[0]; 
      break; 
    } 

    //only works if there is actually an element in the page corresponding with the selector 
    if(newParent != null){ 
     //loops through all elements with the same selector or in the case of id just does one loop 
     for(var i=0; i<element.length; i++){ 

      //loops through all properties in the selector 
      for (var property in object[selector]){ 
       //grabs the associated value with the selector could be string or object 
       var value= object[selector][property]; 

       //if it is a string it is a style, if it is an object, it is targeting the elements inside the current selector only 
       if(typeof(value) === "string"){ 
        element[i].style.setProperty(property, value); 
       }else{ 

/*I am breaking my code right here*/ 

        //reusing the same function, this time selector is equal to property for the case of nav, it is the element 'li' 
        //newParent is the element who is a parent of the current element (e.g 'nav' is parent of 'li') 
        //value is the new object that is replacing json, 
        styleApply(property, newParent, value); //since value is an object it did not pass the string test and now the new object is value 
/*Problem ends here */ 


       } 
      } 
     } 
    } 
} 

my code for looping over all the values in json 
for (var selector in json){ 
    styleApply(selector, document, json); 
} 
+0

'getElementById'返回一个元素,而不是一个集合。你需要将它包装在一个数组中。 – Barmar 2013-04-23 03:04:39

+0

当你递归地调用你的函数时,你需要传递'element [i]'作为新的父类,而不是'newParent'。 – Barmar 2013-04-23 03:11:19

+0

YAY非常感谢Barmar,我设法缩短了我的代码并获得了继承者的工作!并感谢xbonez查看我的工作。我做了一个额外的更改是在我的价值=对象[选择] 我需要回去一个参数来复制我的json的结构 – 2013-04-23 04:14:10

回答

0

这是一个短小的代码,我读到解析JSON成CSS,我想尝试一下

- 选择指的是您在JSON编写CSS选择器

- 父开始引用文档中的文档,如在javascript中的文档对象模型中所示。

- 对象是传入的json对象

如果我滥用任何行话

function styleApply(selector, parent, object){ 
    var element, onSelector, signal; 

    switch(selector[0]){ 
     case ".": 
      element= parent.getElementsByClassName(selector.substring(1)); 
      break; 
     case "#": 
      element= [parent.getElementById(selector.substring(1))]; 
      break; 
     default: 
      element= parent.getElementsByTagName(selector); 
      break; 
    } 

    if(element[0] != null){ 
     for(var i=0; i<element.length; i++){ 
      for (var property in object[selector]){ 

       var value= object[selector][property]; 

       if(typeof(value) === "string"){ 
        element[i].style.setProperty(property, value); 
       }else{ 
        styleApply(property, element[i], object[selector]); 
       } 
      } 
     } 
    } 
} 
0

我只是碰巧寻找到JSON写的不是直上连接字符串和数字一起更清洁的CSS请不要再指正。我不是直接将样式应用于每个元素,而是将它们放入<style>元素中,这使得在页面的整个生命周期中更容易更改。它也能够针对伪元素,例如:之前,我使用过。

总之,这里的功能:

// convert json to css 
function jsonToCss(obj) { 
    var x, finalStr='' 
    for (x in obj) { 
     var y, decStr='' 
     for (y in obj[x]) { 
      decStr+= y + ':' + obj[x][y] + ';' 
     } 
     finalStr+= x + '{' + decStr + '}' 
    } 
    return finalStr 
} 

由于函数只递归通过两个级别(一个用于选择器和一个用于声明)您的JSON需要如下修改:

var json = { 
    "body" : { 
     "background": "#303030", 
     "color": "#FFFFFF", 
     "font-family": "Arial, Helvetica, sans-serif" 
    }, 
    "#nav li": { 
     "display": "inline-block", 
     "list-styles": "none", 
     "margin-right": "10px", 
     "padding": "10px, 10px" 
    } 
} 

饲料是到函数,你会得到以下字符串:

body{background:#303030;color:#FFFFFF;font-family:Arial, Helvetica, sans-serif;}#nav li{display:inline-block;list-styles:none;margin-right:10px;padding:10px, 10px;} 

然后您可以将其放入样式元素中。我没有验证函数产生的字符串,看它是否正确,但它在我的结尾很好。