为什么我的计数器不像我期望的那样在现场工作

时间:2015-02-03 04:27:45

标签: javascript jquery ruby-on-rails

我在我的应用程序中实现了一个JS计数器。我有两个表单字段,我的两个不同的计数器应该工作。 #post_title#body-field

这是我的JS:

counter = function() {
	var title_value = $('#post_title').val();		
    var body_value = $('#body-field').val();

    if (title_value.length == 0) {
        $('#wordCountTitle').html(0);
        return;
    }

    if (body_value.length == 0) {
        $('#wordCountBody').html(0);
        return;
    }

    var regex = /\s+/gi;
    var wordCountTitle = title_value.trim().replace(regex, ' ').split(' ').length;
    var wordCountBody = body_value.trim().replace(regex, ' ').split(' ').length;

    $('#wordCountTitle').html(wordCountTitle);
    $('#wordCountBody').html(wordCountBody);
};

$(document).on('ready page:load', function () {
  $('#count').click(counter);
	$('#post_title, #body-field').on('change keydown keypress keyup blur focus', counter);
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>

<body>
<label for="title">Title</label>
   <textarea id="post_title" placeholder="Enter Title"></textarea>
   <span id="wordCountTitle">0</span> words<br/>

<label for="report">Report</label>
   <textarea id="body-field"placeholder="Provide all the facts." rows="4">
</textarea><br />
<span id="wordCountBody">0</span> / 150 words
  
</body>

</html>

看似迷路的$(document).ready(ready);对应于我之前在文件中调用的var ready = function(),我为了简洁起见而遗漏了这些文件。但是,我按照它出现的顺序离开了document.ready()电话,只是因为它可能导致问题。

所以我遇到的问题是,无论何时单击#post_title字段并输入单词,计数器都不会更新。但是,只要我点击#body-field并开始输入,#body-field的计数器不仅可以立即开始更新,而且#post_title的计数器也会开始工作并显示正确的字段数量。

导致这种情况的原因是什么?

修改1

只是玩那个代码片段我意识到错误也存在于另一个状态。如果您只是在输入标题之前首先将文本添加到第二个字段(即#body-field)...正文字段的计数器将不会增加。它只会在您开始在#post_title中输入标题后更新。所以他们都以某种方式联系在一起。

2 个答案:

答案 0 :(得分:1)

您遇到的错误是因为这两个代码块

if (title_value.length == 0) {
    $('#wordCountTitle').html(0);
    return;
}

if (body_value.length == 0) {
    $('#wordCountBody').html(0);
    return;
}

这意味着为了让计数器运行,标题和正文都应该有一些值。只需删除两者上的return即可。

修改

我认为删除两个if块也会给你你想要的相同行为。如果你想同时拥有两个if块,你必须将标题和正文的计数器分开。

编辑2

这是一个更简单的计数器功能实现。

counter = function() {
  var title_value = $('#post_title').val();     
  var body_value = $('#body-field').val();

  $('#wordCountTitle').html(title_value.split(' ').length);
  $('#wordCountBody').html(body_value.split(' ').length);
}

答案 1 :(得分:1)

您不应该对counter函数进行检查并对这两个字段执行操作。 counter函数应该执行完全相同的操作,方法是使用jquery中的this关键字,或者使用event参数并使用event.target作为替代。

这是重构:

var counter = function(event) {
    var fieldValue = $(this).val();
    var wc = fieldValue.trim().replace(regex, ' ').split(' ').length;
    var regex = /\s+/gi;
    var $wcField = $(this)[0] === $('#post_title')[0] ? $('#wordCountTitle') : $('#wordCountBody');

    if (fieldValue.length === 0) {
        $wcField.html('');
        return;
    }

    $wcField.html(wc);
};

$(document).on('ready page:load', function () {
    $('#post_title, #body-field').on('change keyup paste', counter);
});

JSBin playground

另外,我不完全确定你为什么要在change keyup paste应该这样做的时候听那些textareas上的那么多事件。