Search code examples
jqueryjquery-selectorsparentdom-traversal

Cant traverse up correctly with jquery


I want to simply traverse upwards to find the parent element and wrap an a around it.

This is what I have so far:

$(".product_thumbnail a").each(function() {
    var hrefsrc = $(this).attr('href');
    console.log(hrefsrc);

    $(this).parent('.animate').wrap('<a href="'+hrefsrc+'"></a>');
});

And this is the HTML structure:

<ul id="someIDs">
<li class="animate">
    <div class="product_thumbnail_wrapper ">
        <div class="product_thumbnail ">
            <a href="url">
                <span class="product_thumbnail_background" style=""></span>
                <img width="300" height="300" src="url" />
            </a>
        </div>
</li>
</ul>

Cant figure out how to correctly trigger the right element. I tried the following methods:

closest()

parent()

parents()

parentsUntil shows that the wrapping is possible. I also read the jQUery traversing doc but that didnt help much.

Thanks for any help!


Solution

  • Because the li.animate element is not the direct parent of your a element you can't use parent and you need to use the parents function, however - not that it will give you all the parents up the DOM tree.

    If you don't have more than 1 it should be ok, but if you do it will not work as you want.

    Here is the fix to your code, but you should really change it so the final output would be a valid HTML structure.

    $(".product_thumbnail a").each(function() {
        var hrefsrc = $(this).attr('href');
        $(this).parents('.animate').wrap('<a href="'+hrefsrc+'"></a>');
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <ul id="someIDs">
      <li class="animate">
          <div class="product_thumbnail_wrapper ">
              <div class="product_thumbnail ">
                  <a href="url">
                      <span class="product_thumbnail_background" style=""></span>
                      <img width="300" height="300" src="url" />
                  </a>
              </div>
          </div>
      </li>
    </ul>

    Also important - note that <a> is an inline-block element and should not wrap blocking elements (such as <div>). Another issue is that <ul> elements should only have <li> child-elements (And not <a> - like what you are doing).

    What you can do instead is change the <a> element into onclick function on the li:

    $(".product_thumbnail a").each(function() {
        var hrefsrc = $(this).attr('href');
        $(this).parents('.animate').click(function() {
          window.location = hrefsrc;
        });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <ul id="someIDs">
      <li class="animate">
          <div class="product_thumbnail_wrapper ">
              <div class="product_thumbnail ">
                  <a href="url">
                      <span class="product_thumbnail_background" style=""></span>
                      <img width="300" height="300" src="url" />
                  </a>
              </div>
          </div>
      </li>
    </ul>

    It will work the same and the structure now is valid.