12

I have an HTML list of links with data-… attributes on each one:

<ul id="list">
    <li><a data-info="link1"> **** </a></li>
    <li><a data-info="link2">****</a></li>
    <li><a data-info="link3">**** </a></li>
    <li><a data-info="link4">****</a> </li>
</ul>

I need to receive the data-info value of a link whenever it is clicked. So I thought something like this:

var my_links = $('#list').find('a');

my_links.on('click', function(){
     console.log(this.data(info));
});

But then I get:

Uncaught TypeError: this.data is not a function

If I just do:

var my_links = $('#list').find('a');

my_links.on('click', function(){
  console.log(this);
});

I get the complete HTML code of each link, for example:

<a data-info="link1"> **** </a>

Why are both things happening, and how can I fix it?

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Ornitier
  • 171
  • 1
  • 1
  • 6
  • 1
    `this` in the context of the click event is an anchor tag. Anchor tags don't have a `.data()` function. You'll need to wrap it in the jQuery context `$(this)` to have access to the `.data()` function... – War10ck Aug 25 '15 at 19:05
  • 1
    Protip: inside the handler, at the end, write `debugger;`. Then open up the developer tools and trigger the event. When the JS evaluation pauses inspect the actual values (eg. in the console). Fix the problem using this information. – user2864740 Aug 25 '15 at 19:08

2 Answers2

47

data() is a jQuery method, not a method of native DOM objects.

this will be the <a> element that was clicked — a native DOM object (HTMLAnchorElement). Give it a jQuery wrapper to call jQuery methods:

my_links.on('click', function() {
  console.log( $(this).data('info') );
});

Alternatively, you can skip the jQuery wrapper and access the data attribute directly:

my_links.on('click', function() {
  console.log( this.dataset.info );
});

const my_links = $('#list a');

my_links.on('click', function() {
  console.log( 'jQuery: ' + $(this).data('info') );
  console.log( 'Vanilla JS: ' + this.dataset.info );
});
a {
  cursor: pointer;
  border-bottom: 1px solid blue;
}

li {
  line-height: 2em;
}
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul id="list">
    <li><a data-info="link1">link 1</a></li>
    <li><a data-info="link2">link 2</a></li>
    <li><a data-info="link3">link 3</a></li>
    <li><a data-info="link4">link 4</a> </li>
</ul>
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
3

Use $(this).data() instead of this.data().

var my_links = $('#list').find('a');
    my_links.on('click', function(){
        console.log($(this).data());
    });

Find more info on jQuery $(this) here: jQuery: What's the difference between '$(this)' and 'this'?

Community
  • 1
  • 1
robeau
  • 31
  • 1
  • 2