包装HTML元素 - 如何实现接口节点

时间:2017-04-16 23:13:37

标签: javascript inheritance wrapper

我正在创建自定义HTML元素,并且已经读过你不应该扩展HTMLElement类,而是为它创建一个包装器。我希望能够使用与标准元素相同的语法来操作属性,属性和方法:点表示法:myDiv.id = "id"和括号表示法:myDiv["id"] = "id"。我也希望与方法兼容。全部使用香草js。

以下是包装div的概念尝试以及我能够弄清楚的。

  • 样式 - 看起来我可以将div.style指定给我的class元素,并且所有属性都可以自然获取/设置
  • 属性 - 我为属性列表创建了getter / setter,这可用于设置属性,例如idinnerHTML
  • 具有on语法的事件 - 这似乎适用于getter和setter。
  • “实现界面元素”的方法(例如setAttribute) - 这些似乎需要手动定义每个元素
  • 那些使用需要它的元素来“实现接口节点”的操作。例如document.body.appendChild(myDiv)

我的问题按重要性顺序排列:

  1. 我是否正在以“正确的方式”包装元素?
  2. 是否有可接受的解决方案让我的元素实现接口Node,因此可以在document.body.appendChild(myDiv)等操作中使用?
  3. 对于那些“实现接口元素”而不是我所做的方法的解决方案 - 通过一次定义一个吗?
  4. window.onload = function() {
      var myDiv = new DivWrapper();
      document.body.appendChild(myDiv.div);
    
      // using the style property object
      myDiv.style.height = "200px";
      myDiv.style.width = "200px";
      myDiv.style.background = "aliceblue";
    
      // using manually created methods setAttribute() getAttribute()
      myDiv.setAttribute("id", "newId");
      
      // using automatically generated getter and setter
      myDiv.innerHTML = "Height: " + myDiv.style.height;
      myDiv.innerHTML += "<br>id: " + myDiv.getAttribute("id");
      myDiv.contentEditable = "true";
    
      // listener - using getter setter
      myDiv.onclick = function(e) {
        console.log("Click")
      };
    }
    
    DivWrapper = (function() {
      var instanceCounter = 0;
    
      function DivWrapper() {
        this.id = "div" + instanceCounter++;
        this.div = document.createElement("div");
        this.style = this.div.style;
    
        var attributes = ["align", "class", "contentEditable", "id", "innerHTML", "lang", "tabindex", "title", "value"];
        this.createGetSet(attributes);
    
        var methods = ["onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover", "onmousemove", "onmouseout", "onkeypress", "onkeydown", "onkeyup"];
        this.createGetSet(methods);
      }
    
      DivWrapper.prototype.createGetSet = function(attributes) {
        //	for (var i = 0; i < attributes.length; i++) {
        var _this = this;
        attributes.forEach(function(attribute) {
          var getter = function() {
            return _this.div[attribute];
          };
          var setter = function(val) {
            _this.div[attribute] = val;
          };
          Object.defineProperty(_this, attribute, {
            get: getter,
            set: setter
          })
        })
      }
    
      DivWrapper.prototype.setAttribute = function(attribute, value) {
        this.div[attribute] = value;
      }
      DivWrapper.prototype.getAttribute = function(attribute) {
        value = null;
        try {
          value = this.div[attribute];
        } catch (e) {}
        return value;
      }
    
      return DivWrapper;
    })();

0 个答案:

没有答案