jQuery-如何删除此代码冗余

时间:2018-11-25 19:37:37

标签: javascript jquery

我正在上一门有关客户端Web开发的课程,我们目前正在学习jQuery。我的作业看起来很简单,但是我被困住了。这些说明是为了重构我们的代码,使其遵循OOP DRY原则。换句话说,删除面部零件点击功能代码中的冗余。

这是html:

scoring = 'accuracy'

# Spot Check Algorithms
models = []
models.append(('LR', LogisticRegression()))
models.append(('LDA', LinearDiscriminantAnalysis()))
models.append(('KNN', KNeighborsClassifier()))
models.append(('CART', DecisionTreeClassifier()))
models.append(('NB', GaussianNB()))
models.append(('SVM', SVC()))
# evaluate each model in turn
results = []
names = []
for name, model in models:
kfold = model_selection.KFold(n_splits=10, random_state=seed)
cv_results = model_selection.cross_val_score(model, X_train, Y_train, 
cv=kfold, scoring=scoring)
results.append(cv_results)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
print(msg)

这是脚本:

<div id="frame">
  <div id="pic_box">
    <div id="head" class="face"><img src="images/headsstrip.jpg"></div>
    <div id="eyes" class="face"><img src="images/eyesstrip.jpg"></div>
    <div id="nose" class="face"><img src="images/nosesstrip.jpg"></div>
    <div id="mouth" class="face"><img src="images/mouthsstrip.jpg"></div>
  </div>
 </div>
</div>

这是我尝试过的:

看着它似乎很愚蠢,我对此很陌生,所以我确定我还没有接近。

$(document).ready(function () {
var headclix = 0,
    eyeclix = 0,
    noseclix = 0,
    mouthclix = 0;

$("#head").click(function () {
    if (headclix < 9) {
        $("#head").animate({
            left: "-=367px"
        }, 500);
        headclix++;
    } else {
        $("#head").animate({
            left: "0px"
        }, 500);
        headclix = 0;
    }
});

$("#eyes").click(function () {
    if (eyeclix < 9) {
        $("#eyes").animate({
            left: "-=367px"
        }, 500);
        eyeclix++;
    } else {
        $("#eyes").animate({
            left: "0px"
        }, 500);
        eyeclix = 0;
    }
});

$("#nose").click(function () {
    if (noseclix < 9) {
        $("#nose").animate({
            left: "-=367px"
        }, 500);
        noseclix++;
    } else {
        $("#nose").animate({
            left: "0px"
        }, 500);
        noseclix = 0;
    }
});

$("#mouth").click(function () {
    if (mouthclix < 9) {
        $("#mouth").animate({
            left: "-=367px"
        }, 500);
        mouthclix++;
    } else {
        $("#mouth").animate({
            left: "0px"
        }, 500);
        mouthclix = 0;
    }
});

}); //end doc.onready function

3 个答案:

答案 0 :(得分:0)

这样的事情怎么样?

$(document).ready(function() {

  var clicks = {
    head: 0,
    eyes: 0,
    nose: 0,
    mouth: 0,
  }

  $("#head, #eyes, #nose, #mouth").click(function() {

    var clickedElementId = this.id;

    if (clicks[clickedElementId] < 9) {
      $(this).animate({
        left: "-=367px"
      }, 500);

      clicks[clickedElementId]++;
    } else {
      $(this).animate({
        left: "0px"
      }, 500);

      clicks[clickedElementId] = 0;
    }
  });

});

fiddle

答案 1 :(得分:0)

您可以将它们组合到单个事件处理程序中,然后检查ID:

$("#head, #eyes, #nose, #mouth").click(function () {
    var clix;
    switch (this.id) {
        case "head": 
            clix = headclix;
            break;
        case "eyes":
            clix = eyesclix;
            break;
        case "nose":
            clix = noseclix;
            break;
        case "mouth":
            clix = mouthclix;
            break;
    }
    if (clix < 9) {
        $(this).animate({
            left: "-=367px"
        }, 500);
        headclix++;
    } else {
        $(this).animate({
            left: "0px"
        }, 500);
        headclix = 0;
    }
    switch (this.id) {
        case "head": 
            headclix = 0;
            break;
        case "eyes":
            eyesclix = 0;
            break;
        case "nose":
            noseclix = 0;
            break;
        case "mouth":
            mouthclix = 0;
            break;
    }
});

如果将单独的变量替换为键为ID的对象,这将更加简单。

答案 2 :(得分:0)

至少有两种方法可以使脚本DRY达到目标。

1。基本重构

实施工厂函数createEventHandler,应调用该函数创建相应的处理程序。这种方法可能在您的要求范围之内,但是由于它忽略了脚本执行的 context ,因此它很幼稚。

function createEventHandler( targetElementId, clickCountFrequencyMap ) {

    var targetElementSelector = "#" + targetElementId;

    function targetElementClickHandler( /* event */ ) {

        var targetElementClix = clickCountFrequencyMap[ targetElementId ];

        if ( targetElementClix < 9 ) {
            $( targetElementSelector ).animate( {
                left: "-=367px"
            }, 500 );
            targetElementClix++;
        } else {
            $( targetElementSelector ).animate( {
                left: "0px"
            }, 500 );
            targetElementClix = 0;
        }

        // Update the click frequency map.
        // --
        // Even though we're doing so at this point in the scope
        // of the objective you want to reach,
        // do note though that it's an absolute bad practice
        // to mutate a reference that's passed to a function.
        // Please do NOT take this comment lightly.

        clickCountFrequencyMap[ targetElementId ] = targetElementClix;
    }
}

这样您的原始脚本可以简化为以下内容:

$( document ).ready( function () {
    var clickCountFrequencyMap = {
        head: 0,
        eyes: 0,
        nose: 0,
        mouth: 0
    };

    $( "#head" ).click( createEventHandler( "head", clickCountFrequencyMap ) );

    $( "#eyes" ).click( createEventHandler( "eyes", clickCountFrequencyMap ) );

    $( "#nose" ).click( createEventHandler( "nose", clickCountFrequencyMap ) );

    $( "#mouth" ).click( createEventHandler( "mouth", clickCountFrequencyMap ) );
} );

第一种方法可能适合您当前的学习范围。最终,随着您的进步,您将了解如何对其进行改进。

2。使用event delegation

这种方法充分考虑了脚本的执行环境:脚本正在浏览器中执行,并且正在操纵DOM。

当前,它专门处理4个项目(头部,眼睛,鼻子和嘴巴)的点击。但是您会正确地期望,将要求您另外处理脖子,胸部等的咔嗒声。在这种情况下,要保证面向未来和可扩展性的方法是使用event delegation。 / p>

@Adamanswer已对此进行了演示。为了完整起见,我将在下面共享一个修订版本:

$( document ).ready( function () {
    var clickCountFrequencyMap = {
        head: 0,
        eyes: 0,
        nose: 0,
        mouth: 0
    };

    $( document ).click( function () {

        var targetElement = $( this );
        var targetElementClix = clickCountFrequencyMap[ this.id ];

        if ( targetElementClix < 9 ) {
            targetElement.animate( {
                left: "-=367px"
            }, 500 );
            targetElementClix++;
        } else {
            targetElement.animate( {
                left: "0px"
            }, 500 );
            targetElementClix = 0;
        }

        // Update the click frequency map.
        // --
        // Even though we're doing so at this point in the scope
        // of the objective you want to reach,
        // do note though that it's an absolute bad practice
        // to mutate a reference that's passed to a function.
        // Please do NOT take this comment lightly.
        clickCountFrequencyMap[ targetElementId ] = targetElementClix;
    } );
} );