jQuery element.closest(...).attr is not a function when using each

11,852

Solution 1

The closest() method that you are using is native JS method and which returns DOM element object since element refers DOM element object.


There are several options to get the attribute value, either get from dataset property :
$('.running').each (index, element) =>
    console.log element.closest('[data-id]').dataset.id


Or wrap element by jQuery and use data() method.
$('.running').each (index, element) =>
    console.log $(element.closest('[data-id]')).data('id')


Or wrap the element by jQuery and use jQuery closest() method.
$('.running').each (index, element) =>
    console.log $(element).closest('[data-id]').data('id')

Solution 2

Because they are DOM objects (as you rightly state) and not jquery objects, you can't apply jquery methods to DOM objects, you need to convert them to jquery objects.

$(element).closest...

Solution 3

The element contains a DOMElement, so you're calling the native closest() method, not the jQuery one. Hence the data() method does not exist on the returned object.

To fix this, wrap element in a jQuery object:

$('.running').each (index, element) =>
    console.log $(element).closest('[data-id]').data('id')

Solution 4

data() is a jQuery method so you should call it on jQuery object instead of a DOM oject, so it should be $(element) :

console.log $(element).closest('[data-id]').data('id')

Hope this helps.

Share:
11,852
The Whiz of Oz
Author by

The Whiz of Oz

_ _ /^\ /*\ .' \ / :.\ / \ | :: \ / /. \ / ::: | | |::. \ / :::'/ | / \::. | / :::'/ `--` \' `~~~ ':'/` / ( / 0 _ 0 \ \/ \_/ \/ -== '.' | '.' ==- /\ '-^-' /\ \ _ _ / .-`-((\o/))-`-. _ / //^\\ \ _ ."o".( , .:::. , )."o". |o o\\ \:::::/ //o o| \ \\ |:::::| // / \ \\__/:::::\__// / \ .:.\ `':::'` /.:. / \':: |_ _| ::'/ `---` `"""""` `---`knock knock Neo

Updated on June 09, 2022

Comments

  • The Whiz of Oz
    The Whiz of Oz almost 2 years

    When iterating over some DOM elements I found it impossible to use .data or .attr on them:

    $('.running').each (index, element) =>
        console.log element.closest('[data-id]')
    

    gets me

    <section class="job-block" data-id="240"></section>
    ...
    

    but

    $('.running').each (index, element) =>
        console.log element.closest('[data-id]').data('id')
    

    throws

    Uncaught TypeError: element.closest(...).data is not a function

  • The Whiz of Oz
    The Whiz of Oz over 7 years
    thanks!! It totally makes sense. Which one would be the fastest performing method on multiple elements in this case?
  • Pranav C Balan
    Pranav C Balan over 7 years
    @Denis : I think the fist one but it's(closest in JS) not widely supported.. So I would prefer the last one
  • freedomn-m
    freedomn-m over 7 years
    I recommend always using the variant that sticks with a single tech, in this case the last one as all calls are jquery. This helps remove any confusion whether you have a DOM element or jquery object and so improves maintainability.
  • freedomn-m
    freedomn-m over 7 years
    In this case you probably don't want to use the js closest: developer.mozilla.org/en-US/docs/Web/API/Element/…