Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript native equivalent to JQuery .each() & $(this)

I have the following code which looks at each div with class .comment and shortens the text if more than 100 characters. Using JQuery.

Question is how to convert to native javascript, I can't find equivalents for .each() or $(this)

var showChar = 100;
var ellipsestext = "...";
var moretext = "more";
var lesstext = "less";
$('.comment').each(function() {
    var content = $(this).html();

    if(content.length > showChar) {

        var c = content.substr(0, showChar);
        var h = content.substr(showChar-1, content.length - showChar);

        var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span></span>';

        $(this).html(html);
    }

});

Is this possible?

like image 224
StudioTime Avatar asked Aug 11 '14 15:08

StudioTime


3 Answers

You're not going to find a native equivalent to $(this) because that is the jQuery function. There wouldn't be any reason to write the $ function if it already existed natively.

As for the .each part, you can work with any array like this:

var $comments = $('.comment');
comments.forEach(function(comment) { ... });

or using a simple for loop:

for (var i = 0, len = $comments.length; i < len; i++) {
    var comment = $comments[i];
}

If you want to remove jQuery entirely, you'll need to get your elements using document.getElementsByClassName. This will return an HTMLCollection which does not have the forEach function so you'll need to use a for loop like above.

Also note that you won't have access to the .html function. Instead, you can access and modify it with the .innerHTML property of each node.

var comments = document.getElementsByClassName('comment');
for (var i = 0, len = comments.length; i < len; i++) {
    var comment = comments[i];
    var content = comment.innerHTML;
    ...
    comment.innerHTML = html;
}

Update: 2019-12-02

Nowadays it is more common to use document.querySelectorAll for querying elements and you can use Array.from if you would like to convert the NodeList to an array.

function boldComments() {
  const comments = document.querySelectorAll('.comment');
  comments.forEach(comment => {
    comment.innerHTML = '<b>' + comment.innerHTML + '</b>';
  })
}

document.querySelector('button').addEventListener('click', boldComments);
<ul>
  <li class="comment">Comment A</li>
  <li class="comment">Comment B</li>
  <li class="comment">Comment C</li>
  <li class="comment">Comment D</li>
</ul>
<button>Bold comments</button>
like image 190
Mike Cluck Avatar answered Sep 25 '22 03:09

Mike Cluck


See EcmaScript 6 example:

document.querySelectorAll('.comments').forEach(function (comment) {
     var content = comment.innerHTML

        if(content.length > showChar) {

            var c = content.substr(0, showChar);
            var h = content.substr(showChar-1, content.length - showChar);

            var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span></span>';

            comment.innerHTML=html;
        }
});
like image 28
realmag777 Avatar answered Sep 22 '22 03:09

realmag777


Actually this refers to the current context. It is the window object if used without event listener. If used in oo Javascript this is the object's context. So $(this) is is the element you are currently listening an event on.
It is the current context of the element on which event triggers. In your case it is an object upon which jQuery.each method is invoked.

Implementing jQuery $.each method in Vanilla JavaScript

You can actually implement jQuery as a whole but it requires knowledge of Core JavaScript. In the case of .each method we are going to prototype Object class. The simplest each method is:

 Object.prototype.each = function(callback){
       if(typeof callback !== 'function') throw new Error('Callback should 
                    be a function');
       for(i = 0; i < this.length; i++){
        callback(this[i]);
    }
    return this;
} 

Look at this now this refers to the context of Object. By returning this you can allow method chaining.
This each method gives you the easy way to traverse on DOM. Give it a try. It gives parent + childs of the current parent in callback's first argument.

like image 20
Saqlain Ishtiaq Avatar answered Sep 25 '22 03:09

Saqlain Ishtiaq