简体   繁体   中英

Convert object to HTML element

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);
}

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; } 

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

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) 

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_(); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM