C.Schubert
C.Schubert

Reputation: 2064

Knockout click binding fires after second click

I have a knockout binding that scrolls to a part if the page on click with this function

scrollTo() {
    $("a.scroll").click(function(event) {
        event.preventDefault();
        $('body').animate({
            scrollTop: $(this.hash).offset().top
        }, 500);
    });
}

The html where i call the function

<a class="scroll icon-arrow-down" href="#part" data-bind="localizedText: { id: '4-anchor-1', html: true }, tap: controller.scrollTo.bind(controller)"></a>

The problem is that it fires after the second click and not the first. Also this happen when coming on the page when you click a button it does not fire click it again it fires and then it function normally on other button to.

Upvotes: 0

Views: 343

Answers (2)

Roy J
Roy J

Reputation: 43881

Since you're using Knockout, don't use the jQuery event bindings. Assuming you have defined a tap binding handler (which is to say, to call an event handler like click does), your HTML markup is fine. Just turn your scrollTo method into an event handler.

scrollTo(event) {
    event.preventDefault();
    $('body').animate({
        scrollTop: $(this.hash).offset().top
    }, 500);
}

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337560

The issue is because on the first click you call scrollTo() which binds the event. Then on the next and each successive click you add another click() handler as well as execute all previous click event handlers. You just need to remove the scrollTo() function and add the event on load:

<a class="scroll icon-arrow-down" href="#part" data-bind="localizedText: { id: '4-anchor-1', html: true }"></a>
$("a.scroll").click(function(event) {
    event.preventDefault();
    $('body').animate({
        scrollTop: $(this.hash).offset().top
    }, 500);
});

Alternatively, if the a element is appended to the DOM dynamically you would need to use a delegated event handler:

$(document).on('click', "a.scroll", function(event) {
    event.preventDefault();
    $('body').animate({
        scrollTop: $(this.hash).offset().top
    }, 500);
});

Upvotes: 3

Related Questions