8

In input of function is an object who has this structure:

{
  tag: 'a', //type of html object
  content: "blabal", //inner content
  attr: {
    href: "vk.com",
    id: 'someId'
  },
  events: {
    click: 'alert(this.href)',
    focus: 'this.className="active"'
  },
  style: {
    width:"100px"
  }
}

It describes an HTML element. It has to return an HTML element with specified properties. How to parse it? I have something like this:

elemen={
  tag:'a',
  content:"blabal",
  attr:{
    href:"vk.com",
    id:'someId'
  },
  events:{
   click:'alert(this.href)',
   focus:'this.className="active"'
  },
  style:{
    width:"100px"
  }
};
console.log(elemen.tag);
var node = document.createElement(elemen.tag);
node.innerHTML= elemen.content;

for(var prop in elemen.events){

  var fun =new Function(elemen.events[prop]);
  console.log(fun);
  node.bind(prop, fun);
//   divv.bind(prop, fun);
}
3
  • Is templates such as mustache or jquery tmpl an alternative? Commented May 20, 2016 at 6:15
  • Yes. He has only structure like i described. There is no alternative Commented May 20, 2016 at 6:24
  • Note that a JavaScript object is not JSON. JSON is a data format, and in JavaScript you can only have JSON in a string. See What is the difference between JSON and Object Literal Notation? Commented May 20, 2016 at 13:28

4 Answers 4

7

Use addEventListener to register events on Element and .bind(thisArg) to have specified argument as this-context

var elemen = {
  tag: 'a',
  content: "blabal",
  attr: {
    href: "vk.com",
    id: 'someId'
  },
  events: {
    click: 'alert(this.href)',
    focus: 'this.className="active"'
  }
};
var node = document.createElement(elemen.tag);
node.innerHTML = elemen.content;
for (var attr in elemen.attr) {
  node.setAttribute(attr, elemen.attr[attr]);
}
for (var prop in elemen.events) {
  node.addEventListener(prop, new Function(elemen.events[prop]).bind(node));
}
document.body.appendChild(node);
.active {
  color: red;
}

Sign up to request clarification or add additional context in comments.

Comments

4

Using only javascript

 var _createElem = document.createElement(""+_elem.tag+""); 
 _createElem.innerHTML = _elem.content;

//set attributes
for(var keys in _elem.attr){
  _createElem.setAttribute(''+keys+'',_elem.attr[keys])
 }
//set style 
 for(var keys in _elem.style){
  _createElem.setAttribute(''+keys+'',_elem.style[keys])
 }
//set events
for(var keys in _elem.events){
_createElem.setAttribute('on'+keys,_elem.events[keys])
} 
document.getElementById("demoDiv").appendChild(_createElem)

Note: The elem has got both onclick & href , you may need to return true/false as per your requirement

2 Comments

Wrong fiddle. And whats up with all these unneeded quotes?
0

Use the following function:

const objectToHTML = function(obj) {
  const element = document.createElement(obj.tag)
  element.innerHTML = obj.content
  for (const name in obj.attr) {
    const value = obj.attr[name]
    element.setAttribute(name, value)
  }
  for (const name in obj.events) {
    const listener = new Function(obj.events[name]).bind(element)
    element.addEventListener(name, listener)
  }
  for (const property in obj.style) {
    const value = obj.style[property]
    element.style[property] = value
  }
  return element
}

To create an event listener from string, you have to convert it to function using the Function constructor, bind context to it using Function.prototype.bind() (otherwise the function would be executed with window as context), and finally, use element.addEventListener().

The rest is rather obvious.

You can use this function like that:

const element = objectToHTML({
  tag: 'a',
  content: "blabal",
  attr: {
    href: "vk.com",
    id: 'someId'
  },
  events: {
    click: 'alert(this.href)',
    focus: 'this.className="active"'
  },
  style: {
    width: "100px"
  }
})

document.body.appendChild(element)

See demo:

const objectToHTML = function(obj) {
  const element = document.createElement(obj.tag)
  element.innerHTML = obj.content
  for (const name in obj.attr) {
    const value = obj.attr[name]
    element.setAttribute(name, value)
  }
  for (const name in obj.events) {
    const listener = new Function(obj.events[name]).bind(element)
    element.addEventListener(name, listener)
  }
  for (const property in obj.style) {
    const value = obj.style[property]
    element.style[property] = value
  }
  return element
}

const element = objectToHTML({
  tag: 'a',
  content: "blabal",
  attr: {
    href: "vk.com",
    id: 'someId'
  },
  events: {
    click: 'alert(this.href)',
    focus: 'this.className="active"'
  },
  style: {
    width: "100px"
  }
})

document.body.appendChild(element)

Comments

-1

I recommend this form, is more adaptable.

window.onload = function() {
 
  function init_() {

    function action__(type, element, convert, a) {
      if (type == "function") {
        if (convert.create[a] != null) {
          try {
            var new_ = convert.create[a](element[a]);
          } catch (rrr) {
            rrr = (rrr.toString());

            if (rrr.indexOf('2 arguments') != -1 && Object.keys(element[a]).length != 0) {
              for (v in element[a]) {
                convert.create[v] = element[a][v];
                var new_ = convert.create;
              }
            };
          }
          convert['create'] = new_;
        }

      };

      if (type == "object") {
        for (f in element[a]) {
          convert.create[a][f] = element[a][f];
        }
      }

      if (type == "string" && a != "events") {
        convert.create[a] = (element[a]);
      } else if (type == "string" && a == "events") {
        for (ev in element[a]) {
          var type = convert.detectType(convert.create, ev);
          if (type == "function") {
            convert.create.addEventListener(ev, new Function(element[a][ev]));
          }
        };
      };



      return convert.create;
    };


    function createElement(elements) {

      var finished = [];

      if (typeof elements.tagName == "undefined" && !elements.length) {
        elements = [elements];
      }

      for (r = 0; r < elements.length; r++) {
        var element = elements[r];
        if (element) {
          var convert = {
            create: document,
            detectType: function(element, attribute) {
              var type = "string";
              if (typeof element[attribute] != "undefined") {
                type = typeof element[attribute];
              };
              return type;
            },
            add: function(new_) {
              if (new_ && new_ != "undefined") {
                this.create = new_;
              }
            }

          };

          for (a in element) {

            var type = convert.detectType(convert.create, a);
            var returner = action__(type, element, convert, a);
            convert.add(returner);
          }


          finished.push(convert.create);
        };

      }
      return (finished);

    };

    var minifi_function = init_.toString();
    
    var elements = [{
      createElement: 'a', 
      innerHTML: "blabal", 
      setAttribute: {
        href: "vk.com",
        id: 'someId',
        style: "height:200px;"
      },
      events: {
        click: 'alert(this.href)',
        focus: 'this.className="active"'
      },
      style: {
        width: "100px"
      }
    }, {
      createElement: 'div', 
      innerHTML: "see my content", 
      setAttribute: {
        ['data-link']: "vk.com",
        id: 'someId2',
        style: "height:200px;background:red;"
      },
      events: {
        click: 'prompt("Copy",' + minifi_function + ')',
        focus: 'this.className="activediv"'
      },
      style: {
        width: "100px"
      }
    }];



    var elementos = createElement(elements);
    console.log(elementos);
    for (p = 0; p < elementos.length; p++) {
      document.body.appendChild(elementos[p]);
    }

  }

  init_();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.