Javascript 仅使用JS确定WebView是否不可见

Javascript 仅使用JS确定WebView是否不可见,javascript,android,google-chrome,android-webview,alpha,Javascript,Android,Google Chrome,Android Webview,Alpha,我有一个Android测试应用程序,它的网络视图如下: <WebView android:alpha="0" android:id="@+id/myWebView" android:layout_width="match_parent" android:layout_height="match_parent" /> 我的应用程序上有一个按钮,可以将alpha值从0切换到1(显示/隐藏网络视图) 有没有“创造性”的方法来

我有一个Android测试应用程序,它的网络视图如下:

<WebView
        android:alpha="0"
        android:id="@+id/myWebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
我的应用程序上有一个按钮,可以将alpha值从0切换到1(显示/隐藏网络视图)

有没有“创造性”的方法来检测JS端的变化

我尝试过的事情:

  • 检查帧速率变化
更新:

澄清一下,我正在寻找一个只使用JS的解决方案,实际的JS代码是WebView环境中使用的SDK


我无法控制Android应用程序,完全控制WebView内容。

您可以将Android的
WebView
子类化,覆盖其
setAlpha
方法,并添加一些逻辑以让网页知道当前alpha值

以下是一个简化的示例:

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
        init();
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public MyWebView(Context context,
                     AttributeSet attrs,
                     int defStyleAttr,
                     int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void init() {
        getSettings().setJavaScriptEnabled(true);
    }

    @Override
    public void setAlpha(float alpha) {
        super.setAlpha(alpha);
        propagateAlphaToWebPage(alpha);
    }

    private void propagateAlphaToWebPage(float alpha) {
        // setWebViewAlpha is a JS function that should be defined in your html's js 
    String jssnippet = "setWebViewAlpha("+alpha+");";
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        evaluateJavascript(jssnippet, null);
    } else {
        loadUrl("javascript:"+jssnippet);
    }
}
}
您可能会发现其他相关问题很有帮助:


    • 下面是完整的代码,它将告诉
      JavaScript
      是否可见
      WebView

      步骤

    • 创建包含和的布局
    • 使用
      htmlWebView.loadUrl(“file:///android_asset/index.html");和相关代码
    • 创建一个函数
      onToggleButtonPressed()
      ,该函数将被称为切换按钮的
      onClick
    • onToggleButtonPressed()
      show/hide WebView中,同时使用
      htmlWebView.evaluateJavascript()
      方法将状态传递给JavaScript。将visibilityStatusFromAndroid()传递给JavaScript
    • 通过
      visibilityStatusFromAndroid()
      函数获取JavaScript中的状态
    • Android布局xml代码:

      <ToggleButton
          android:id="@+id/button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentTop="true"
          android:layout_centerHorizontal="true"
          android:background="@color/red"
          android:onClick="onToggleButtonPressed"
          android:text="Button1"
          android:textOn="Show"
          android:textOff="Hide"
          tools:ignore="MissingConstraints"
          tools:layout_editor_absoluteX="148dp"
          tools:layout_editor_absoluteY="0dp" />
      
      <WebView
          android:id="@+id/webView"
          android:layout_width="368dp"
          android:layout_height="447dp"
          android:layout_alignParentStart="true"
          android:layout_below="@+id/button"
          tools:ignore="MissingConstraints"
          tools:layout_editor_absoluteX="8dp"
          tools:layout_editor_absoluteY="56dp"
          android:layout_alignParentLeft="true" />
      
      JavaScript文件:

      function visibilityStatusFromAndroid(message) {
        if (message === "NOT VISIBLE") {
          console.log("webview is not visible");
          // do your stuff here
      
        } else if (message === "VISIBLE NOW") {
          console.log("webview is visible now");
          // do your stuff here
      
        }
      }
      
      就这样。你完了

      下面是工作代码的

      更新:

      您可以使用一个选项来检测可见性仅使用JavaScriptis,但如果屏幕上有任何EditText,并且用户将聚焦该EditText,则此选项将不起作用

      下面是可用于
      文档的代码。hasFocus()

      
      试验
      #消息{字体大小:粗体;}
      设置间隔(检查页面焦点,200);//您可以更改间隔时间以更频繁地检查
      函数checkPageFocus(){
      var info=document.getElementById(“消息”);
      if(document.hasFocus()){
      info.innerHTML=“文档可见。”;
      }否则{
      info.innerHTML=“文档不可见。”;
      }
      }
      JavaScript焦点示例
      等待用户操作
      
      目前没有唯一的JS解决方案。

      WebView的内容不应能够获取有关其环境的信息。
      唯一的例外是环境本身自愿提供的信息

      这将与基本沙箱相矛盾,并可能导致安全问题

      由于没有标准的API可以为您提供所需的信息,因此您必须自己更改环境以将其公开给WebView

      如果你不能改变环境,你所要求的(理论上)在当前的浏览器/android上是不可能的



      @Hack要找到一个实际的漏洞,我们可以利用它来获取alpha值,我们需要更多关于JS SDK、环境以及对应用程序的android/webview方面有多大影响的详细信息
      即使付出了很多努力,结果也很可能是一样的。

      谢谢你的回复,但是我正在寻找一个只使用JS的解决方案哈,是的,我不确定你只需要JS,因为你在问题中添加了android xml。Visibility API有一个非常可靠的例子,唯一的问题是android上的支持有点少,请参见>手机Visibility API在这里不起作用。我认为@RoniGadot应该看看浏览器对JS的调整,比如检查GPU内存。谢谢,但我需要一个只使用JS的解决方案,没有Java代码DownVoter,也没有提到downvote的原因。如果没有确凿的理由,请不要破坏别人的努力。如果你认为有一些地方需要改进,那么你可以在评论中提及,但如果你不能提及原因,请不要投反对票。同意,但是,我认为在用户单击内容时查找webView位置也是如此。可以使用屏幕X/Y位置、客户端X/Y和身体宽度高度来计算此信息。当实际的webView未呈现时,正在查找一些JS环境更改。为什么不能在webView的文档/正文元素上检查可见性或显示样式?VisibilityAPI有什么问题?也许你能找到一种方法从JS上截取WebView的屏幕,看看它是否有相同的颜色。
          WebView htmlWebView; // put it outside onCreate() to make it accessible in onToggleButtonPressed() 
      
          htmlWebView = (WebView)findViewById(R.id.webView);
          htmlWebView.setWebViewClient(new WebViewClient());
          htmlWebView.loadUrl("file:///android_asset/index.html");
          WebSettings webSetting = htmlWebView.getSettings();
          webSetting.setJavaScriptEnabled(true);
      
      public void onToggleButtonPressed(View view) {
      
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      
              boolean on = ((ToggleButton) view).isChecked();
              String visibility;
              if (on) {
                  htmlWebView.setVisibility(View.GONE);
                  visibility = "NOT VISIBLE";
                      htmlWebView.evaluateJavascript("javascript: " +
                              "visibilityStatusFromAndroid(\"" + visibility + "\")", null);
              } else {
                  htmlWebView.setVisibility(View.VISIBLE);
                  visibility = "VISIBLE NOW";
                  htmlWebView.evaluateJavascript("javascript: " +
                          "visibilityStatusFromAndroid(\"" + visibility + "\")", null);
      
              }
          }
      }
      
      function visibilityStatusFromAndroid(message) {
        if (message === "NOT VISIBLE") {
          console.log("webview is not visible");
          // do your stuff here
      
        } else if (message === "VISIBLE NOW") {
          console.log("webview is visible now");
          // do your stuff here
      
        }
      }
      
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8" />
      <title>TEST</title>
      <style>
      #message { font-weight: bold; }
      </style>
      <script>
      setInterval( checkPageFocus, 200 ); // you can change interval time to check more frequently
      
      function checkPageFocus() {
        var info = document.getElementById("message");
      
        if ( document.hasFocus() ) {
          info.innerHTML = "The document is VISIBLE.";
        } else {
          info.innerHTML = "The document is INVISIBLE.";
        }
      }
      
      </script>
      </head>
      <body>
        <h1>JavaScript hasFocus example</h1>
        <div id="message">Waiting for user action</div>
      </body>
      </html>