【问题标题】:Hide/Show "Scroll To Top" button based on WebView's scroll基于 WebView 的滚动隐藏/显示“滚动到顶部”按钮
【发布时间】:2017-09-29 00:43:48
【问题描述】:

我正在制作一个包含 WebView 的 UWP 应用程序,我想实现一个简单的“滚动到顶部”按钮,我已经在这个按钮后面制作了解码代码并且它可以工作:

        private async void ToTopButton_Click(object sender, RoutedEventArgs e)
        {
        var ScrollToTopString = @"var int = setInterval(function() { 
        window.scrollBy(0, -36);

        if( window.pageYOffset === 0 )
            clearInterval(int);
        }, 0.1);";
        await MyWebView.InvokeScriptAsync("eval", new string[] { ScrollToTopString });
        }

但现在我只想在用户需要时显示按钮,所以如果 WebView 滚动在顶部,则应该隐藏按钮,反之亦然......我已经研究过,但没有找到任何东西。任何人都可以帮助我吗?谢谢

【问题讨论】:

    标签: c# xaml webview uwp uwp-xaml


    【解决方案1】:

    我只想在用户需要时显示按钮,所以如果 WebView 滚动在顶部,则应该隐藏按钮,反之亦然。

    应用程序无法直接访问 WebView 的滚动条,因为它是嵌入式 Edge 浏览器视图的一部分。所以你可能需要使用脚本来监控onscroll event的滚动操作,也需要InvokeScriptAsync调用脚本。

    然后,如果滚动条位于顶部,您可能需要通知您的 uwp 应用程序。为此,您可能需要使用WebviewScriptNotify 事件。当页面调用 window.external.notify 并传递字符串参数时,托管的 HTML 页面可以在您的 Windows 应用商店应用中触发 ScriptNotify 事件。

    但是注意ScriptNotify的备注:

    为防止恶意脚本利用此事件,请务必仅对受信任的 URI 启用它。

    您必须在应用清单的 ApplicationContentUriRules 部分中包含页面的 URI。 (您可以在 Visual Studio 中 Package.appxmanifest 设计器的 Content URIs 选项卡上执行此操作。)此列表中的 URI 必须使用 HTTPS,并且可能包含子域通配符(例如,“https://.microsoft.com”),但它们不能包含域通配符(例如,“https://.com”和“https://.”)。

    这是完成的示例:

    <Button x:Name="ToTopButton" Content="to top" Click="ToTopButton_Click"></Button>
    <WebView x:Name="MyWebView"  Height="500" Width="400" Source="https://www.microsoft.com/en-sg/"  ScriptNotify="MyWebView_ScriptNotify" NavigationCompleted="MyWebView_NavigationCompleted"></WebView>
    

    后面的代码

    private async void ToTopButton_Click(object sender, RoutedEventArgs e)
    {
        var ScrollToTopString = @"var int = setInterval(function(){window.scrollBy(0, -36); if( window.pageYOffset === 0 ) clearInterval(int); }, 0.1);";
        await MyWebView.InvokeScriptAsync("eval", new string[] { ScrollToTopString });
    }
    
    private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
    {      
        var result = e.Value;
        if (result == "true")
        {
            ToTopButton.Visibility = Visibility.Collapsed;
        }
        else
        {
            ToTopButton.Visibility = Visibility.Visible;
        }
    } 
    
    private async void MyWebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
    {
        string addlistener = @"window.onscroll = function() {myFunction()};
                              function myFunction()
                              {if( window.pageYOffset === 0 )  window.external.notify('true'); else window.external.notify('false');} "; 
        await MyWebView.InvokeScriptAsync("eval", new string[] { addlistener });
        //first time check
        var firstnotify = "if( window.pageYOffset === 0 )  window.external.notify('true'); else window.external.notify('false')";
        await MyWebView.InvokeScriptAsync("eval", new string[] { firstnotify });
    }
    

    频繁通知可能会影响性能,因此除非您必须使用该功能,否则不建议这样做。

    【讨论】:

    • 谢谢!这对我有用,但我想知道这对应用的整体性能有多大影响。
    • @PabloJiménezPascual,我认为这取决于用户滚动的频率。如果只有少数页面使用它可能不会影响更多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多