多个 div 的多个字计数器

Multiple Word Counters For Multiple Divs

对于我的单词列表网站,我试图为每个列表制作一个自动单词计数器。我能够计算一个列表中的字数,但是当我添加更多时,计数器会计算所有列表。我无法在任何地方找到解决方案,因此非常感谢所有帮助。

JSFiddle link: http://jsfiddle.net/ge7akmzj/

$(function() {
    var text = $('.input').text();
    var wordsCount = text.split(',').length;
    $('.output').html('word count:' + wordsCount);
});
<span class="input">
  These, are, 7, words, as, a, demonstration
</span>
<br>
<br>
<span class='output'></span>
<br>
<br>
<span class="input">
  These, are, 7, words, as, a, demonstration
</span>
<br>
<br>
<span class='output'></span>

<script type = "text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

$(function() {
  $(".input").each(function(element) {
    var text = $(this).text();
    var wordsCount = text.split(',').length;
    $(this).parent().find('.output').html('word count:' + wordsCount);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
  <span class="input">
    These, are, 7, words, as, a, demonstrationd, demonstrationd,12,13,15,15
    </span>
  <br>
  <br>
    <span class='output'>
    </span>
</div>
<div class="box">
  <span class="input">
  These, are, 7, words, as, a, demonstration,
  </span>
  <br>
  <br>
  <span class='output'>
  </span>
</div>

$(function() {
    // iterate over the input DOM element
    $('.input').each(function (index) {
        const text = $(this).text()
        const wordsCount = text.split(',').length
        // select the corresponding output DOM element and update the text
        $('.output').eq(index).text('word count:' + wordsCount);
    });
});

您需要使用 .each 循环遍历每个元素

$(function() {
  $(".input").each(function(element) {
    var text = $(this).text();
    var wordsCount = text.split(',').length;
    $(this).parent().find('.output').html('word count:' + wordsCount);
    });
});
<div>
  <span class="input">
    These, are, 7, words, as, a, demonstration
  </span>
  <br>
  <br>
  <span class='output'></span>
  <br>
  <br>
</div>
<div>
  <span class="input">
    These, are, 4, words
  </span>
  <br>
  <br>
  <span class='output'></span>
</div>
<script type = "text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

虽然您已经接受了答案,但我想我会借此机会向您展示另一种方法,并强调一个事实——虽然您肯定必须迭代各种元素——但您 不需要使用each()来这样做。

此外,我选择展示一个简单的 JavaScript 方法来解决完全相同的问题,以证明尽管 jQuery 提供了一些语法糖,并抽象掉了一些冗长的方面JavaScript,JavaScript 本身采用了 jQuery 的一些方法和方法。

也就是说,代码的解释在下面对该代码的注释中:

// defining a named function, using Arrow syntax, passing
// the Event Object - passed automatically from the (later)
// use of EventTarget.addEventListener() - to the body of
// the function:
const wordCount_JS = (evt) => {
  // retrieving the element to which the function was bound
  // (evt.currentTarget, the <button>) and then using
  // Element.closest() to navigate to the closest ancestor
  // <section> element:
  let section = evt.currentTarget.closest('section'),
    // from that <section> we use Element.querySelectorAll()
    // to find all elements with a class of 'input':
    wordSources = section.querySelectorAll('.input');

  // we use NodeList.prototype.forEach(), along with its
  // anonymous function, to iterate over the NodeList of
  // elements:
  wordSources.forEach(
    // passing a reference to the current Node of the NodeList
    // over which we're iterating:
    (text) => {
      // taking the text-content of the current Node:
      let count = text.textContent
        // splitting it on the ',' character:
        .split(',')
        // and finding the length of that Array of strings:
        .length;

      // here find the next element-sibling of the current
      // 'text' Node, and set its text-content to the
      // number held in the 'count' variable:
      text.nextElementSibling.textContent = count;
    })
};

// here we use document.querySelector() to find the first of any
// element in the document that matches the CSS selector, and then
// use EventTarget.addEventListener() to bind the wordCount_JS()
// function (note the deliberate lack of parentheses) as the event-
// handler for the 'click' event:
document.querySelector('.JavaScript button').addEventListener('click', wordCount_JS);

// here we use jQuery, first to select the <button> element(s) held
// within any .jQuery element(s), and then use the on() method to
// bind the anonymous function of that method as the event-handler
// for the 'click' event:
$('.jQuery button').on('click', function() {
  // from the clicked <button> element(s) we navigate to the
  // closest ancestor <section> element:
  $(this).closest('section')
    // and from that element we find all elements with a class of
    // 'output':
    .find('.output')
    // and use the text() method, with its anonymous function:
    .text(function() {
      // to iterate over all elements to which the method was
      // chained.
      // here, we take $(this) the current '.output' element:
      return $(this)
        // find its previous sibling, if it matches the
        // supplied selector:
        .prev('.input')
        // retrieve the text-content of that element:
        .text()
        // split that string of text on the ',' character:
        .split(',')
        // and retrieve the number of elements in the
        // resulting Array of Strings; this is then -
        // thanks to the 'return' - returned to the
        // text() method chained to the '.output' elements:
        .length;
  });
});
/* a simple means of normalising the layout of the document to reduce
   cross-browser differences, as well as different default layout and
   sizing of various elements within the same browser: */
*,
 ::before,
 ::after {
  box-sizing: border-box;
  font-family: Roboto, Montserrat, system-ui;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

section {
  border: 0.1em solid currentColor;
  color: #363;
  display: grid;
  /* setting a gap between adjacent elements, whether
     vertically, or horizontally, adjacent: */
  gap: 0.5em;
  /* using CSS Logical properties, margin-block is the
     sets both the top (margin-block-start)
     and bottom (margin-block-end) margin in English
     (left-to-right, top-to-bottom) language: */
  margin-block: 1em;
  /* margin-inline sets the left (margin-inline-start)
     and right (margin-inline-end) margins in a 
     left-to-right language, such as English: */
  margin-inline: auto;
  /* again, using logical properties: */
  padding-block: 0.25em;
  padding-inline: 0.5em;
  /* defining the width as 70vw, with a minimum
     possible width of 25em and a maximum width
     of 700px: */
  width: clamp(25em, 70vw, 700px);
}

/* using CSS generated content to prepend the
   (presentational) information, concatenating
   the attribute-value of the 'class' attribute
   between the 'Using ' and ': ' strings: */
section::before {
  content: "Using " attr(class) ": ";
  /* logical properties, setting only the final
     border of the block axis: */
  border-block-end: 0.1em solid currentColor;
}

/* assigning a border to the edge of the element
   along its block-end border (the bottom border
   in English): */
.output {
  border-block-end: 0.1em solid currentColor;
}

.output:not(:last-of-type) {
  /* adding a margin of 0.5em following the end
     boundary of the .output element(s) which
     are not the :last-of-type (so not the last
     of its element-type (<span>) within this
     parent): */
  margin-block-end: 0.5em;
}

/* showing the "Word count: " string before the
   content of all elements with a class of
   'output': */
.output::before {
  color: #9a9;
  content: "Word count: ";
}

/* for those elements with a class of 'output'
   which are not empty (so which do not contain
   any child-elements, or text-nodes: */
.output:empty::before {
  content: "No count as yet.";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- I removed all <br> elements, and used CSS for layout and spacing; other
     than that I didn't really change the HTML other than varying the text a
     little, duping the content and wrapping it in a parent <section>: -->
<section class="JavaScript">
  <span class="input">These, are, 7, words, as, a, demonstration</span>
  <span class='output'></span>
  <span class="input">An, entirely, unplanned, and, typed, in, a, stream-of-consciousness, manner, string, of, sundry, words.</span>
  <span class='output'></span>
  <span class="input">Lorem, ipsum, dolor, sit, amet, consectetur, adipisicing, elit. Sequi, laboriosam, eius, magni, vitae, sit, velit, alias, ab, iusto, amet, similique, mollitia, magnam, quod, laudantium, facere, tempora, fugit, recusandae, adipisci, quaerat.</span>
  <span class="output"></span>
  <button type="button">Show word count</button>
</section>

<section class="jQuery">
  <span class="input">These, are, 7, words, as, a, demonstration</span>
  <span class='output'></span>
  <span class="input">An, entirely, unplanned, and, typed, in, a, stream-of-consciousness, manner, string, of, sundry, words.</span>
  <span class='output'></span>
  <span class="input">Lorem, ipsum, dolor, sit, amet, consectetur, adipisicing, elit. Sequi, laboriosam, eius, magni, vitae, sit, velit, alias, ab, iusto, amet, similique, mollitia, magnam, quod, laudantium, facere, tempora, fugit, recusandae, adipisci, quaerat.</span>
  <span class="output"></span>
  <button type="button">Show word count</button>
</section>

JS Fiddle demo.

参考文献: