Skip to content

What is this bar called?

Solved Customisation
  • Hello @phenomlab

    I find a bug 🙂

    For example, I’m on the home page and I scroll down.
    The button at the bottom right appears.
    If I then go directly to the chat for example, the button remains and interferes with navigation/chat

    Same for all notifications page

    We need a function to deactivate the button depending on the page/URL (chats, notifications, user) like you did for the reading meter bar

    blink2.gif

    My code :

    // Scroll to top function / Reading Meter Bar / 
    // Scroll to top function
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
            var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
            var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
            var scrolled = (winScroll / height) * 100;
     
            document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
            $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
     
            // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
            if ($('#pageUp').is(':focus')) {
            event.preventDefault();
            }
        }
     
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
     
            // Check the URL and composer visibility separately from the scroll event
            $(window).scroll(function() {
                var thisURL = window.location.href;
                var checkURL = ["topic", "notifications", "user"];
                var isFound = false;
                for (var i = 0, len = checkURL.length; i < len; i++) {
                    if (thisURL.indexOf(checkURL[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                if (isFound) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            });
     
            // Scroll to top when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                const firstTopic = $('[component="category/topic"][data-index="0"]');
                if (firstTopic.length) {
                    $("html").animate({
                        scrollTop: 0
                    }, '300');
                    return false;
                } else {
                    ajaxify.refresh();
                }
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        });
    });
    
  • @DownPW thanks for reporting. Let me see if I can reproduce this.

  • @DownPW Can you replace your function with this one and let me know?

    // Scroll to top function
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
            var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
            var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
            var scrolled = (winScroll / height) * 100;
    
            document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
            $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
            // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
            if ($('#pageUp').is(':focus')) {
            event.preventDefault();
            }
        }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Check the URL and composer visibility separately from the scroll event
            $(window).scroll(function() {
                var thisURL = window.location.href;
                var checkURL = ["topic", "notifications", "user"];
                var isFound = false;
                for (var i = 0, len = checkURL.length; i < len; i++) {
                    if (thisURL.indexOf(checkURL[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                if (isFound) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            });
    
            // Scroll to top when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                const firstTopic = $('[component="category/topic"][data-index="0"]');
                if (firstTopic.length) {
                    $("html").animate({
                        scrollTop: 0
                    }, '300');
                    return false;
                } else {
                    ajaxify.refresh();
                }
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        });
    });
    
    
    
    /*
    Set pages where the progress bar should not be shown - see examples
    in below array, and ensure you follow the same syntax for any you need to 
    add
    */
    
    $(window).on('action:ajaxify.end', function(data) {
        $(document).ready(function() {
            var bar = $('.reading-meter');
            var thisURL = window.location.href;
            var checkURL = new Array("user", "notifications");
            var isFound = false;
            for (var i = 0, len = checkURL.length; i < len; i++) {
                if (thisURL.indexOf(checkURL[i]) > -1) {
                    isFound = true;
                    break;
                }
            }
            if (isFound) {
                //console.log("Page '" + checkURL[i] + "' is in URL - hide progress bar");
                bar.removeClass('show');
            }
        });
    });
    

    @cagatay reported something similar a while back IIRC and this was the solution.

    Thanks

  • nope sorry, same things

  • @DownPW hmm. Odd. I’ll have to take a look at that. Not seeing that here and I think that’s the same for @cagatay

  • @DownPW Can you try with this code?

    // Scroll to top function
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
                var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                var scrolled = (winScroll / height) * 100;
    
                document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
                $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
                // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
                if ($('#pageUp').is(':focus')) {
                    event.preventDefault();
                }
            }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Check the URL and composer visibility separately from the scroll event
            function checkURL() {
                var thisURL = window.location.href;
                var checkArray = ["topic", "notifications", "user"];
                var isFound = false;
                
                for (var i = 0, len = checkArray.length; i < len; i++) {
                    if (thisURL.indexOf(checkArray[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                
                return isFound;
            }
    
            // Function to update visibility based on URL and composer
            function updateVisibility() {
                if (checkURL()) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            }
    
            // Call updateVisibility initially
            updateVisibility();
    
            // Bind updateVisibility function to the window's scroll event
            $(window).scroll(function() {
                updateVisibility();
            });
        });
    });
    
    
  • seems to be good my friend 🙂

  • @DownPW not sure if you’ve noticed, but (at least for me) the scroll to top function no longer works?

    EDIT - there is a bug in the above code. Please use this updated version

    // Scroll to top function
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
                var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                var scrolled = (winScroll / height) * 100;
    
                document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
                $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
                // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
                if ($('#pageUp').is(':focus')) {
                    event.preventDefault();
                }
            }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Check the URL and composer visibility separately from the scroll event
            function checkURL() {
                var thisURL = window.location.href;
                var checkArray = ["topic", "notifications", "user"];
                var isFound = false;
                
                for (var i = 0, len = checkArray.length; i < len; i++) {
                    if (thisURL.indexOf(checkArray[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                
                return isFound;
            }
    
            // Function to update visibility based on URL and composer
            function updateVisibility() {
                if (checkURL()) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            }
    
            // Call updateVisibility initially
            updateVisibility();
    
            // Bind updateVisibility function to the window's scroll event
            $(window).scroll(function() {
                updateVisibility();
            });
    
    
            // Scroll to top when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                const firstTopic = $('[component="category/topic"][data-index="0"]');
                if (firstTopic.length) {
                    $("html").animate({
                        scrollTop: 0
                    }, '300');
                    return false;
                } else {
                    ajaxify.refresh();
                }
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        });
    });
    
    
    
  • It’s funny I just realized it and I was going to share it here and I see your message!!
    Thanks you Mark @phenomlab 😉

    On the other hand, I have never been careful but I have the impression that the page is reloaded when you click on the button.
    I don’t know if it’s me but before, (on v2 perhaps?) we saw the page scroll from bottom to top after pressing the button

    I find this strange. I’ve never seen this on other sites using the same type of scroll to top

  • @DownPW you are right - it used to scroll to the top but I changed it because “scroll top” actually only applied to what was in the DOM at the time meaning that as data was being added, the “top” position was no longer a true representation and so the button had to be clicked multiple times to reach the “real” top.

  • Ok, thanks to confirm 🙂
    so I have no possibility of modifying it to display the same effect as on v2?

  • @DownPW it can easily be reverted, but I don’t want to maintain two sets of code. I’ll defer to others here for that final decision as I know it did cause some confusion.

  • no problem dude @phenomlab 🙂
    I put a modification here that seems to work as a reminder if you don’t mind.

    –> If yes, you can delete it.

    use $('html, body').animate({ scrollTop: 0 }, '300'); to smoothly scroll the page to the top when the #pageUp button is clicked. This code will provide a smooth scrolling effect from the bottom to the top of the page without reloading it.

    What do you think of this?

    // Scroll to top function
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
                var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                var scrolled = (winScroll / height) * 100;
    
                document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
                $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
                // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
                if ($('#pageUp').is(':focus')) {
                    event.preventDefault();
                }
            }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Check the URL and composer visibility separately from the scroll event
            function checkURL() {
                var thisURL = window.location.href;
                var checkArray = ["topic", "notifications", "user"];
                var isFound = false;
                
                for (var i = 0, len = checkArray.length; i < len; i++) {
                    if (thisURL.indexOf(checkArray[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                
                return isFound;
            }
    
            // Function to update visibility based on URL and composer
            function updateVisibility() {
                if (checkURL()) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            }
    
            // Call updateVisibility initially
            updateVisibility();
    
            // Bind updateVisibility function to the window's scroll event
            $(window).scroll(function() {
                updateVisibility();
            });
    
            // Scroll to top when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                $('html, body').animate({ scrollTop: 0 }, '300'); // Animate scrolling to top
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        });
    });
    
  • @DownPW looks good to me.

  • @DownPW Just to circle back to this, the decision to reload the page instead of multiple scrolling / clicking was based on this discussion, which I’m including here for brevity

    https://community.nodebb.org/topic/17395/scroll-top-function?_=1695115491466

  • @phenomlab said in What is this bar called?:

    @DownPW you are right - it used to scroll to the top but I changed it because “scroll top” actually only applied to what was in the DOM at the time meaning that as data was being added, the “top” position was no longer a true representation and so the button had to be clicked multiple times to reach the “real” top.

    you are right @phenomlab the code I gave yesterday works but does the same thing as you described.

    here a mix of the 2 (scroll to top & scroll to top with refresh)

    // Scroll to top function (classic scroll to top)
    $(window).on('action:ajaxify.end', function(data) {
        var matched = false;
        $(document).ready(function() {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
            
            // Main progressbar function
            function pageScroller() {
                var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                var scrolled = (winScroll / height) * 100;
    
                document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
                $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
                // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
                if ($('#pageUp').is(':focus')) {
                    event.preventDefault();
                }
            }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Check the URL and composer visibility separately from the scroll event
            function checkURL() {
                var thisURL = window.location.href;
                var checkArray = ["topic", "notifications", "user"];
                var isFound = false;
                
                for (var i = 0, len = checkArray.length; i < len; i++) {
                    if (thisURL.indexOf(checkArray[i]) > -1) {
                        isFound = true;
                        break;
                    }
                }
                
                return isFound;
            }
    
            // Function to update visibility based on URL and composer
            function updateVisibility() {
                if (checkURL()) {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                } else {
                    // Exception here is that we don't want the scroll bar to show when the composer is active
                    if ($(window).scrollTop() > 0 && (!$('[component="composer"]').is(":visible"))) {
                        bar.addClass('show');
                        pageUp.addClass('show');
                    } else {
                        bar.removeClass('show');
                        pageUp.removeClass('show');
                    }
                }
            }
    
            // Call updateVisibility initially
            updateVisibility();
    
            // Bind updateVisibility function to the window's scroll event
            $(window).scroll(function() {
                updateVisibility();
            });
    
            // Scroll to top when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                $('html, body').animate({ scrollTop: 0 }, '300'); // Animate scrolling to top
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        });
    });
    
    // Scroll to refresh function (for specific URLs)
    $(window).on('action:ajaxify.end', function(data) {
        var refreshRoutes = ['/recent', '/unread', '/popular', '/top', '/solved', '/unsolved'];
        var currentRoute = ajaxify.data.url;
    
        if (refreshRoutes.includes(currentRoute)) {
            var pageUp = $('#pageUp');
            var bar = $('.reading-meter');
            var perWidth = $('.reading-meter').width();
    
            // Main progressbar function
            function pageScroller() {
                var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
                var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
                var scrolled = (winScroll / height) * 100;
    
                document.getElementById("progress-bar").style.width = parseFloat(scrolled).toFixed(0) + "%";
                $('#percentage').val(parseFloat(scrolled).toFixed(0) + "%");
    
                // Prevent the mouse scroll wheel from scrolling down after the pageUp button is clicked
                if ($('#pageUp').is(':focus')) {
                    event.preventDefault();
                }
            }
    
            // Bind the pageScroller function to the window's scroll event
            $(window).scroll(function() {
                pageScroller();
            });
    
            // Function to update visibility based on URL and composer
            function updateVisibility() {
                // No need to check composer visibility for these routes
                if ($(window).scrollTop() > 0) {
                    bar.addClass('show');
                    pageUp.addClass('show');
                } else {
                    bar.removeClass('show');
                    pageUp.removeClass('show');
                }
            }
    
            // Call updateVisibility initially
            updateVisibility();
    
            // Bind updateVisibility function to the window's scroll event
            $(window).scroll(function() {
                updateVisibility();
            });
    
            // Scroll to refresh when #pageUp is clicked
            $(document).on("click", "#pageUp", function(e) {
                ajaxify.refresh();
                $('#progress-bar').width(0);
                pageUp.removeClass('show');
            });
        }
    });
    

    I found it interesting to keep the scroll effect on the home page

    The scroll to top with refresh is applied on the routes indicated in the script (/recent, /unread, etc.). The classic scroll to top applies to other pages and the scroll to top is disabled in chat, etc…

    For the previous script, I used the code from your v2 and doing myself but I’m not being a good JS developer, so this time I asked to ChatGPT to help me, sorry !

    I tested the code and it seems to work correctly without any bugs but could you check @phenomlab if this seems correct to you even if the code works?

    A machine will not replace humans in this regard. At least for now 🙂

  • @DownPW 🙂 Love it - let me try this out!

    EDIT - Tried it, and there’s a couple of bugs. For example, if you use a custom page, scroll to the bottom, then use the back to top button, you have to scroll the mouse wheel down 16 times (if you do it quickly - depending on intervals it can be much less) before it’ll work properly. This is animation jitter as far as I can see where the animation does not complete on time and is therefore stuck in a loop.

    Have a look yourself here and see if you get the same experience

    https://sudonix.org/journey

  • Seems you can fix this by using e.preventDefault() see below

        // Scroll to top when #pageUp is clicked
        $(document).on("click", "#pageUp", function(e) {
            e.preventDefault(); // Prevent default behavior
            $('html, body').animate({ scrollTop: 0 }, '300'); // Animate scrolling to top
            $('#progress-bar').width(0);
            pageUp.removeClass('show');
        });
    
  • Not test on custom page. Test ASAP


Did this solution help you?
Did you find the suggested solution useful? Why not buy me a coffee? It's a nice gesture, and a great way to show your appreciation 💗

  • 1 Votes
    10 Posts
    309 Views

    @Panda because there is no match for the DNS entry specified. The receiving web server parses the headers looking for a destination hostname to match, and anything the web server is unable to resolve will be sent back to the root.

  • Nodebb 3.2.0

    Bugs
    20
    2 Votes
    20 Posts
    524 Views

    @crazycells yes, I’m aware of that. Need to fix

    EDIT- fixed. Caused by the same CSS that is used to absolutely position the “verified” group badge in the posts view. Amended this CSS so that is specifically targets the post stream as below

    li[component="post"] a[href*="/groups/verified"] { position: absolute !important; left: 8px; z-index: 2; margin-top: 1px; border-radius: 999px !important; line-height: 14px; display: block; height: 22px; margin-left: 0px !important; }
  • 2 Votes
    26 Posts
    1k Views

    @Panda said in Interesting Widget code, but can’t fetch API:

    How did you drop that widget into the post there?
    I hadnt seen this BSgenerator anywhere on sudonix site, do you use it somewhere already?

    Yes, here

    https://sudonix.org/topic/414/corporate-bullshit-generator?_=1687774393044

    It’s not a “post” or “topic” in the common sense. It is actually a page in it’s own right and leverages nodebb-plugin-custom-pages. This in turn creates a new “route” which behaves like a page, meaning it is then exposed for widgets.

    @Panda said in Interesting Widget code, but can’t fetch API:

    Also can you explain more what you mean by calling the code externally. In my API call example, how would I go about doing that?

    By this, I mean create all the required code in an external JS file that is reachable by the NodeBB instance - so, in “public” for example - or in my case /public/js. The widget then “calls” that file and because it runs outside of the scope of NodeBB, you just need to return the values to the widget.

    Hope this makes sense?

  • 5 Votes
    16 Posts
    447 Views

    @DownPW Yes, it is. It’s set far too low meaning other elements with a higher preference will sit over the top of it.

  • Issues with Progress Bar on v3

    Solved Customisation
    48
    14 Votes
    48 Posts
    3k Views

    @Panda You could use the below

    .page-topic .pagination-block.ready { display: none; }
  • nodebb loading emojis

    Solved Configure
    16
    1 Votes
    16 Posts
    466 Views

    @DownPW sure. Let me have a look at this in more detail. I know nginx plus has extensive support for this, but it’s not impossible to get somewhere near acceptable with the standard version.

    You might be better off handling this at the Cloudflare level given that it sits in between the requesting client and your server.

  • Gettin Erors NodeBB

    Solved Configure
    7
    0 Votes
    7 Posts
    328 Views

    @phenomlab no forum is working goods.
    there is no eror message since yestarday.

  • 10 Votes
    23 Posts
    1k Views

    @DownPW sounds good.