Search code examples
jqueryappendsmooth-scrolling

JS smooth scroll not working with append anchor


I've created this pen to show exactelly my problem but in short, I can't make a jQuery append anchor to work smoothly (with css-tricks snippet), when all HTML anchor work perfectly.

As you can see, the "JS button" jumps directly to the bottom of page, but the "HTML button" and "Back to top" do this smoothly.

I don't understand where the problem is. I searched for more than an hour without success so here I am :p

$(document).ready(function() {

    $(function() {  
        $('a[href*="#"]')
            .not('[href="#"]')
            .not('[href="#0"]')
            .click(function(event) {
                if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
                    var target = $(this.hash);
                    target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
                    if (target.length) {
                        event.preventDefault();
                        $('html, body').animate({
                            scrollTop: target.offset().top
                        }, 1000, function() {
                        var $target = $(target);
                        $target.focus();
                        if ($target.is(":focus")) {
                            return false;
                        } else {
                            $target.attr('tabindex','-1');
                            $target.focus();
                        };
                    });
                }
            }
        });
    });
  // My anchor
  $(function () {
            $('#link').append('<a href="#bottom">JS button</a>');
    });
  
  });
* {
  font-weight: bold;
}
span {
  display: block;
  margin: 20px 0;
}
a {
    color: dodgerblue;
    display: inline-block;
    margin: 8px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="link"><a href="#bottom">HTML button</a></div>
<div><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span><span>10</span><span>11</span><span>12</span><span>13</span><span>14</span><span>15</span><span>16</span><span>17</span><span>18</span><span>19</span><span>20</span><span>21</span><span>22</span><span>23</span><span>24</span><span>25</span><span>26</span><span>27</span><span>28</span><span>29</span><span>30</span><span>31</span><span>32</span><span>33</span><span>34</span><span>35</span><span>36</span><span>37</span><span>38</span><span>39</span><span>40</span><span>41</span><span>42</span><span>43</span><span>44</span><span>45</span><span>46</span><span>47</span><span>48</span><span>49</span><span>50</span></div>
<div><a href="#link" id="bottom">Back to top</a></div>


Solution

  • Just move the link embed code above the fade code. Like this:

    $(document).ready(function() {
       $(function () {
         $('#link').append('<a href="#bottom">JS button</a>');
       });
       ...
    });
    

    $(document).ready(function() {
    
    $(function () {
      $('#link').append('<a href="#bottom">JS button</a>');
    });
    
        $(function() {  
            $('a[href*="#"]')
                .not('[href="#"]')
                .not('[href="#0"]')
                .click(function(event) {
                    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
                        var target = $(this.hash);
                        target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
                        if (target.length) {
                            event.preventDefault();
                            $('html, body').animate({
                                scrollTop: target.offset().top
                            }, 1000, function() {
                            var $target = $(target);
                            $target.focus();
                            if ($target.is(":focus")) {
                                return false;
                            } else {
                                $target.attr('tabindex','-1');
                                $target.focus();
                            };
                        });
                    }
                }
            });
        }); 
      });
    * {
      font-weight: bold;
    }
    span {
      display: block;
      margin: 20px 0;
    }
    a {
        color: dodgerblue;
        display: inline-block;
        margin: 8px 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="link"><a href="#bottom">HTML button</a></div>
    <div><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span><span>10</span><span>11</span><span>12</span><span>13</span><span>14</span><span>15</span><span>16</span><span>17</span><span>18</span><span>19</span><span>20</span><span>21</span><span>22</span><span>23</span><span>24</span><span>25</span><span>26</span><span>27</span><span>28</span><span>29</span><span>30</span><span>31</span><span>32</span><span>33</span><span>34</span><span>35</span><span>36</span><span>37</span><span>38</span><span>39</span><span>40</span><span>41</span><span>42</span><span>43</span><span>44</span><span>45</span><span>46</span><span>47</span><span>48</span><span>49</span><span>50</span></div>
    <div><a href="#link" id="bottom">Back to top</a></div>