【问题标题】:Javascript DRY Design Patterns - Functions vs ObjectJavascript DRI 设计模式 - 函数和对象
【发布时间】:2014-09-21 04:15:55
【问题描述】:

下面是创建和附加 div HTML 对象的函数的代码 sn-p。该函数是从另一个函数调用的,该函数将附加元素附加到它。

我发现自己正在编写如下所示的类似代码。我知道必须有另一种更有效的方式来编写这段代码。我应该使用什么枯燥的设计模式?对象表示法是否更适合这样的事情?例子会很棒。

function create_element_container(){
  var newElement = document.createElement('div'); //create container element
      newElement.className = 'dropped'; //add classes to container element      

  var controllerContainer = document.createElement('div');
      controllerContainer.className = 'drop-element-controls';

      newElement.appendChild(controllerContainer);//Append controller container to main div

  var controller_left = document.createElement('div');
      controller_left.className = 'drop-move-controller';

      controllerContainer.appendChild(controller_left);

      var controller_left_move = document.createElement('div');
          controller_left_move.className = 'drop-move';

            controller_left.appendChild(controller_left_move);

            var controller_left_icon = document.createElement('span');
                controller_left_icon.className = 'fa fa-question fa-lg';

                controller_left_move.appendChild(controller_left_icon);

      controllerContainer.appendChild(controller_left); //Append controller Left


  var controller_middle = document.createElement('div')
      controller_middle.className = 'drop-sortable-controller';

      controllerContainer.appendChild(controller_middle);

      var controller_middle_sortable = document.createElement('div');
          controller_middle_sortable.className = 'drop-sortable';

          controller_middle.appendChild(controller_middle_sortable);

            var controller_middle_icon = document.createElement('span');
                controller_middle_icon.className = 'fa fa-arrows fa-lg';

                controller_middle_sortable.appendChild(controller_middle_icon);

      controllerContainer.appendChild(controller_middle); //Append controller Left


  var controller_right = document.createElement('div')
      controller_right.className = 'drop-remove-controller';

      controllerContainer.appendChild(controller_right);

      var controller_right_move = document.createElement('div');
          controller_right_move.className = 'drop-remove';

          controller_right.appendChild(controller_right_move);

            var controller_right_icon = document.createElement('span');
                controller_right_icon.className = 'fa fa-remove fa-lg';

                controller_right_move.appendChild(controller_right_icon);

  return newElement;

}

【问题讨论】:

  • 别写那么多var,这里有强迫症的人
  • @vsync:vars 没有任何问题。 奇怪的是看似随意的缩进,以及对controllerContainer.appendChild(controller_*)的双重调用
  • 是的,它们有问题。其中不止一个。缩进也很明显。
  • 大家好,感谢您的 cmets。我不认为 vars 有什么问题,用 var 声明一个新变量不是很好的做法吗?另外,对 controllerContainer 的双重调用是什么意思?这些调用是按顺序附加到元素的。下面的人确实列出了另一种去掉冗余的样式。 @vsync 你将如何编写函数/对象?
  • 用最干净的解决方案查看我的答案。

标签: javascript function object design-patterns dry


【解决方案1】:

首先我会写一个createElement函数:

function createElement(tagName, className) {
    var element = document.createElement(tagName);
    element.className = className;
    return element;
}

接下来我将重写你的create_element_container 函数如下:

function create_element_container() {
    var newElement = createElement("div", "dropped");

    var controllerContainer = newElement
        .appendChild(createElement("div", "drop-element-controls"));

    controllerContainer
        .appendChild(createElement("div", "drop-move-controller"))
        .appendChild(createElement("div", "drop-move"))
        .appendChild(createElement("span", "fa fa-question fa-lg"));

    controllerContainer
        .appendChild(createElement("div", "drop-sortable-controller"))
        .appendChild(createElement("div", "drop_sortable"))
        .appendChild(createElement("span", "fa fa-arrows fa-lg"));

    controllerContainer
        .appendChild(createElement("div", "drop-remove-controller"))
        .appendChild(createElement("div", "drop-remove"))
        .appendChild(createElement("div", "fa fa-remove fa-lg"));

    return newElement;
}

您可以这样做,因为parent.appendChild(child) 返回child 元素。

【讨论】:

    【解决方案2】:

    您的代码由以下重复组成:

    var controllerContainer = document.createElement('div');
        controllerContainer.className = 'drop-element-controls';
    
        newElement.appendChild(controllerContainer);
    

    您可能需要考虑put-selector。与put

    var controllerContainer = put(newElement, 'div.drop-element-controls');
    

    这样做会将该功能减少 2/3。然后甚至合并调用:

    put(controllerContainer, 'div.drop-move-controller div.drop-move span.fa.fa-question.fa-lg <<');
    

    替换:

     var controller_left = document.createElement('div');
          controller_left.className = 'drop-move-controller';
    
          controllerContainer.appendChild(controller_left);
    
          var controller_left_move = document.createElement('div');
              controller_left_move.className = '';
    
                controller_left.appendChild(controller_left_move);
    
                var controller_left_icon = document.createElement('span');
                    controller_left_icon.className = 'fa fa-question fa-lg';
    
                    controller_left_move.appendChild(controller_left_icon);
    
          controllerContainer.appendChild(controller_left); //Append controller Left
    

    这减少了 15/16 日。

    另一种选择是只创建第一个元素:

    var newElement = document.createElement('div'); //create container element
        newElement.className = 'dropped'; //add classes to container element 
    

    然后做:

    newElement.innerHTML = '<div class="drop-move-controller"><div class="drop-move"><span class="fa fa-question fa-lg"></span></div></div>...';
    

    请注意,上面的 HTML 仅包含 div 和类 drop-move-controller

    【讨论】:

    • 我正在寻找不涉及其他插件的解决方案,但无论如何感谢。
    【解决方案3】:

    这取决于它会运行多少次。如果不是很多,那么我会准备一个 DOM 字符串,然后使用 innerHTML 将所有内容放入某个容器中。这将更具可读性和可维护性。

    基本示例:

    function create_element_container(){
        var elm, template;
        
        elm = document.createElement('div'); //create container element
        elm.className = 'dropped';
        
        template = '<div class="something another"> \
                        <span></span> \
                    </div> \
                    <span class="foo"></span>';
        
        // this makes our template text into a real DOM elements
        elm.innerHTML = template;
        
        return elm;
    }
    

    【讨论】:

    • 很好的方法,很干净!我认为这个和@Aadit 代码的组合会完美运行。
    • 没有组合 :) 他和我的完全不同。您可以使用这个或那个,但没有什么比我的方法更简单的了,除非您使用的是 jQuery……而且,仍然没有太多。
    • 您的代码缺少控制器元素容器。此外,我的代码涉及更多,我刚刚发布了该函数的 sn-p。
    • 我的代码只是一个示例,您可以编写任何您想要的“模板”......数千行HTML。它将是可维护的,因为它看起来与 HTML 完全一样。使用实际模板会更好。见handlebarsjs.com
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    相关资源
    最近更新 更多