如何在为表单输入分别处理$(this)和$时编写DRY代码

How to write DRY code when working $(this) and $each for form inputs

本文关键字:this 代码 DRY 表单 输入 处理 别处      更新时间:2023-09-26

我已经编写了一些代码,可以在一系列表单上启用和禁用输入和选择字段。我已经重复了很多代码,我想知道如何以DRY、可扩展的方式编写这些代码。

我创建了一个Fiddle,它重复了三次——编辑、取消和保存。

$(edit).each(function(){
$(this).on('click', function(){ }); });

这是我的小提琴。

https://jsfiddle.net/tellmehow/5tcs6f82/9/

我会继续努力,但如果有人有任何建议或类似的问题,请告诉我。谢谢

您可以通过将表单/按钮操作放在一个单独的函数中来减少隐藏/显示/禁用等操作的重复:

function setFormMode($form, mode){
    switch(mode){
        case 'view':
            $form.find('.save-button, .cancel-button').hide();
            $form.find('.edit-button').show();
            $form.find("input, select").prop("disabled", true);
            break;
        case 'edit':
            $form.find('.save-button, .cancel-button').show();
            $form.find('.edit-button').hide();
            $form.find("input, select").prop("disabled", false);
            break;
    }
}

创建三个"onclick"函数(因为,可能您还想做其他事情):

function edit_onclick(){
    setFormMode($(this).closest("form"), 'edit');
}
function cancel_onclick(){
    setFormMode($(this).closest("form"), 'view');
    //TODO: Undo changes?
}
function save_onclick(){
    setFormMode($(this).closest("form"), 'view');
    //TODO: Send data to server?
}

然后绑定:

$('.save-button').on('click', save_onclick);
$('.cancel-button').on('click', cancel_onclick);
$('.edit-button').on('click', edit_onclick);

Fiddle:https://jsfiddle.net/5tcs6f82/10/

您还可以执行以下操作。它不使用jQuery,但演示了一种替代方法,即添加或删除一个名为hidden的类来隐藏或显示按钮。它还使用事件委派来减少侦听器的数量。

.hidden {
  display: none;
}

以下是主要函数,如果使用toggle类函数,它可以更简洁。

/* If click is from element with class edit-button, hide it and show
 * buttons with class cancel-button or save-button.
 * If click is from element with class cancel-button or save-button,
 * hide them and show button with class edit-button
 */
function toggleButtons(event) {
  var form = this;
  var target = event.target;
  // If the click came from a button with class edit-button, hide it and
  // show the cancel and save buttons, otherwise show the edit button and
  // hide the cancel and show buttons
  if (hasClass(target, ['cancel-button','save-button','edit-button'])) {
    var buttons = form.querySelectorAll('.cancel-button, .save-button, .edit-button');
    Array.prototype.forEach.call(buttons, function(el) {
      if (hasClass(el, 'hidden')) {
        removeClass(el, 'hidden');
      } else {
        addClass(el, 'hidden');
      }
    });
  }
}

不需要为每个元素添加一个监听器,只需为每个表单添加一个侦听器:

window.onload = function() {
  for (var forms=document.forms, i=0, iLen=forms.length; i<iLen; i++) {
    // Add listener to each form
    forms[i].addEventListener('click', toggleButtons, false);
    // Hide the cancel and save buttons
    Array.prototype.forEach.call(forms[i].querySelectorAll('.cancel-button, .save-button'),
                                 function(el){addClass(el, 'hidden')}
    );
  }
}

取代等价jQuery 的一些库函数

// Return true if el has class className
// If className is an array, return true if el has any class in className
function hasClass(el, className) {
  if (typeof className == 'string') {
    className = [className];
  }
  var re = new RegExp('(^|''s+)(' + className.join('|') + ')(''s+|$)');
  return re.test(el.className);
}
// Add class className to el
function addClass(el, className) {
  var classes;  
  if (!hasClass(el, className)) {
    classes = el.className.match(/'S+/g) || [];
    classes.push(className);
    el.className = classes.join(' ');
  }
}
// Remove class className from el
function removeClass(el, className) {
  var re;
  if (hasClass(el, className)) {
    var re = new RegExp('(^|''s+)' + className + '(''s+|$)','g');
    classes = el.className.replace(re, ' ').match(/'S+/g);
    el.className = classes.join(' ');
  }
}