-1

I want to set a Max length of 60 characters in titles, using pure JavaScript. But it does not want to work.

Here is the html

<div class="limiter">
Pandemic deaths are spiraling 
out of control since the 
opening of the country 
and now we test the limiter
</div>

Here is the JavaScript

document.querySelector(".limiter").each(function () {
  var a = 60;
  var b = document.querySelector(this).text();
  if (b.length > a) {
    document.querySelector(this).text(b.substring(0, a + 1) + " ...");
  } else {
    document.querySelector(this).text(b);
  }
});

Any idea why it does not work ?

doğukan
  • 23,073
  • 13
  • 57
  • 69
Kamikaza
  • 1
  • 1
  • 18
  • 1
    There is no `each`, `document.querySelector(this)` does not work like jQuery does, and there is no `text()` method. Someone is coding JavaScript as it it works like jQuery. – epascarello Jul 10 '23 at 13:01
  • In addition to the previous comment, you'll need to use [`document.querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) instead, loop over the result, and set the truncated value to each item. – M0nst3R Jul 10 '23 at 13:10
  • Are you aware that css can do this without ending on x amount of characters but rather when it runs out of space in the element. See [`text-overflow: ellipsis;`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow). If you really want to end it after 60 chars then this css solution is useless. – Mark Baijens Jul 10 '23 at 13:16
  • I want it at 60, and my own solution/answer only worked for the first item :( so if someone else have another better answer please add it – Kamikaza Jul 10 '23 at 13:18
  • Ref: https://stackoverflow.com/q/9329446/125981 then use `document.querySelectorAll(".limiter")` to get them all not just the one OR just use the one not a loop perhaps. – Mark Schultheiss Jul 10 '23 at 13:20

2 Answers2

2

It looks like you're moving from jQuery to vanilla JavaScript. You'll notice that the code isn't transferable. The code looks similar but the syntax is different.

Updating your code:

  1. To pick up an array-like list of nodes you'll need to use querySelectorAll.

  2. each should become forEach. Note there are a few other methods for iterating over the node list but forEach is the closest match for your use-case. The first argument in its callback is the current iterated element.

  3. JavaScript doesn't have a text() function. You need to get/set the textContent property directly. (Or innerText depending on your needs - here you can see the differences between the two).

  4. You need one condition - to change the text if its length exceeds the limit you've imposed. In this example I've used slice and a template string to create the new truncated string.

  5. These days its better to move on from var and use const or let to declare your variables.

// Set the limit
const limit = 60;

// Grab all the elements with a "limiter" class
// The callback's first argument "el" is the current
// iterated element
document.querySelectorAll('.limiter').forEach(el => {

  // For convenience assign the text content of the current
  // iterated element to a variable called "text",
  // and trim the beginning/end whitespace it
  const text = el.textContent.trim();

  // If the text length is greater than the limit
  // set the element's text content to the truncated content
  if (text.length > limit) {
    el.textContent = `${text.slice(0, limit + 1)}...`;
  }
});
body > * ~ * { margin-top: 0.5rem; }
<div class="limiter">
  Pandemic deaths are spiraling out of control since the opening of the country and now we test the limiter
</div>
<div class="limiter">
  Lions and Tigers and Bears, Oh My!
</div>
Andy
  • 61,948
  • 13
  • 68
  • 95
1

Refer here to learn more Ref: stackoverflow.com/q/9329446/125981

/* one way */
/*
const limiters = document.querySelectorAll(".limiter");
limiters.forEach(function (element) {
  const a = 60;
  let b = element.textContent;
  if (b.length > a) {
    element.textContent = (b.substring(0, a + 1) + " ...");
  }
  console.log(b, element.textContent);
});
*/

/* another way */ 
const limiters = document.querySelectorAll(".limiter");
for(const el of limiters) {
  const a = 60;
  if (el.textContent.length > a) {
    el.textContent = (el.textContent.substring(0, a + 1) + " ...");
  }
}
<div class="limiter">
Pandemic deaths are spiraling 
out of control since the 
opening of the country 
and now we test the limiter
</div>
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • I never heard about querySelectorAll, but it worked perfect. Thank you very much Mark. I learned something new today – Kamikaza Jul 10 '23 at 13:31