0

I am having some trouble getting the text of elements using querySelectorAll. I already tried using querySelector but it only gives me the value of the first element. What I want to achieve is to get the text of the clicked element. Here's my code:

function __(selector){

   var self = {};
   self.selector = selector;

   if(typeof selector == 'undefined'){
      self.element = [self.selector];
   }else{
      self.element = document.querySelectorAll(self.selector);
   }

   // creating a method (.on)

    self.on = function(type, callback){
        self.element.forEach(function(elements){
           elements['on' + type] = callback;
        });
    }

     self.text = function(elems){
          [].slice.call(self.element).forEach(function(el,i){
                return el.innerHTML;
           });
     }

     return self;
}

And the HTML File:

<script src="selector.js"></script>
<script>
   window.onload = function(){

        __('p').on('click', function(){
               alert(__(this).text());
        });
   }
</script>

<p>Hello</p>  
<p>World</p>

The code above gives me an undefined value.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Trish Siquian
  • 495
  • 3
  • 11
  • 22

1 Answers1

0

Your code actually throws an error: SyntaxError: '[object HTMLElement]' is not a valid selector. This is because at __(this) you’re passing the selected element itself to the function, not a selector. You could account for this by including this as a third case:

if(typeof selector == "undefined"){
  self.element = [self.selector];
}
else if(typeof selector == "string"){
  self.element = document.querySelectorAll(self.selector);
}
else if(selector instanceof HTMLElement){
  self.element = [selector];
}

Now, the actual problem you’ve described occurs because you don’t return anything in the self.text function. The return is for the forEach function argument, which is ignored. Return the texts in the self.text function itself and use map instead of forEach. Something like this:

self.text = function(elems){
  return [].slice.call(self.element).map(function(el,i){
    return el.innerHTML;
  });
}

This will return an array with the inner HTML texts for each element.

Code in action

function __(selector) {

  var self = {};
  self.selector = selector;

  if (typeof selector == "undefined") {
    self.element = [self.selector];
  } else if (typeof selector == "string") {
    self.element = document.querySelectorAll(self.selector);
  } else if (selector instanceof HTMLElement) {
    self.element = [selector];
  }

  // creating a method (.on)

  self.on = function(type, callback) {
    self.element.forEach(function(elements) {
      elements['on' + type] = callback;
    });
  }

  self.text = function(elems) {
    return [].slice.call(self.element).map(function(el, i) {
      return el.innerHTML;
    });
  }

  return self;
}

console.log(__("p").text()); // Logs texts of all <p>s

__("p").on("click", function() {
  console.log(__(this).text()); // Logs text of clicked <p>
});
<p>Hello</p>
<p>World</p>
Community
  • 1
  • 1
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75