Search code examples
javascriptjqueryanimationscrolldata-annotations

Jquery Scroll to elements without Ids, only by data attributes


I want the page to scroll down to my "container"-li which wraps my current elements. The li doesn't have an id attribute and it can't have for HTML validation purposes. Each li has a data attribute named: data-commentid This attribute contains a GUID and is what i want to use when binding the scroll. How do i scroll to a element only by using it's data-attribute?

var container = $("body").find(".roomWall.commentBox.publicListing:first");
    var targets = $(container).find("li.commentInList.topLevelComment");
    if ($.cookie('scrollTarget')) {
        var cookieValue = $.cookie("scrollTarget").split('"');
        var splittedStr = cookieValue[1];

        $(targets).each(function () {
            var $self = $(this);

            if ($($self).attr("data-commentid") === splittedStr) {
                var target = $("#" + splittedStr);

                $($self).fadeOut("slow").hide().delay(500).queue(function (next) {
                    next();
                }).delay(1000).queue(function (next) {        
                    var $container = $("html,body");
                    $($container).animate({
                        scrollTop: $self.offset().top 
                    }, 1000);
                    next();
                }).delay(1000).queue(function () {
                    $($self).fadeIn(1000);
                    $(target).focus();
                });

                $.removeCookie("scrollTarget", { path: "/" });
            }


        });
    }

The cookie contains the GUID I want. Inside my li ($self) there's a textarea with id={Some Guid} which, in this case refers to my $target variable. Since I didn't managed to get it working with $self.offset().top I added $scrollTo and tried with that one, which didn't work either.

Regarding to the Markup, It's pretty complex so I will only show you the parts we need, to prevent confusion. A wrapping li with the data-commentId:

Further down the hierarchy we have:

Hope someone can find out where my code breaks.


Solution

  • I would recommend using jQuery's filter() instead of trying to concatenate it in. I also think the $("html,body") part is where it's bugging out for you. Otherwise your code is actually correct:

    var someGuid = "0003";
    
    var $scrollTo = $("li.commentInList.topLevelComment").filter(function(i){
        return $(this).data('commentid') === someGuid;
    });
    
    $(document.body).animate({
        scrollTop: $scrollTo.offset().top
    }, 1000);
    li {
        height: 10em;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <ul>
        <li class="commentInList topLevelComment" data-commentid="0001">Comment 1</li>
        <li class="commentInList topLevelComment" data-commentid="0002">Comment 2</li>
        <li class="commentInList topLevelComment" data-commentid="0003">Comment 3</li>
        <li class="commentInList topLevelComment" data-commentid="0004">Comment 4</li>
        <li class="commentInList topLevelComment" data-commentid="0005">Comment 5</li>
    </ul>