【问题标题】:Adding contextmenu to WP8 browser control将上下文菜单添加到 WP8 浏览器控件
【发布时间】:2013-05-05 01:42:36
【问题描述】:

当用户在网页上的链接上执行按住手势时,我正在尝试附加上下文菜单。

我在网上搜索了一些建议HERE

if (webBrowser.IsScriptEnabled)
        {
            webBrowser.InvokeScript("execScript", "function eventListener(evt){ if (evt.type == 'MSPointerDown') { gestureHandler.addPointer(evt.pointerId); return; } if (evt.detail & evt.MSGESTURE_FLAG_END) {  window.external.notify(evt.srcElement.tagName);}}");
            webBrowser.InvokeScript("execScript","document.addEventListener('MSGestureHold', eventListener, false); document.addEventListener('MSPointerDown', eventListener, false);  gestureHandler = new MSGesture(); gestureHandler.target = document.body;");
        }

但是第二个 execScript 引发了这个错误

 System.SystemException was unhandled by user code
  HResult=-2146233087
  Message=An unknown error has occurred. Error: 80020101.
  Source=Microsoft.Phone.Interop
  StackTrace:
   at Microsoft.Phone.Controls.NativeMethods.ValidateHResult(Int32 hr)
   at Microsoft.Phone.Controls.WebBrowserInterop.InvokeScript(String scriptName, String[] args)
   at Microsoft.Phone.Controls.WebBrowser.InvokeScript(String scriptName, String[] args)
   at Tabbed_Browser.User_Controls.WebBrowser.AttachContextMenu()
   at Tabbed_Browser.User_Controls.WebBrowser.webBrowser_Loaded(Object sender, RoutedEventArgs e)
   at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
   at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
  InnerException: 

基于posting,我还尝试了以下方法。但显然它只适用于 WP7 手机,不适用于 WP8 或模拟器。

public void AttachContextMenu()
    {
        try
        {
            if (webBrowser.IsScriptEnabled)
            {
                webBrowser.InvokeScript("execScript", "function FindParentLink(item) \r\n{\r\n\tif (!item.parentNode)\r\n\t\treturn null;\r\n\tif (item.tagName.toLowerCase() == 'a') \r\n\t{\r\n\t\treturn item;\r\n\t} \r\n\telse \r\n\t{\r\n\t\treturn FindParentLink(item.parentNode);\r\n\t}\r\n}\r\n\r\nfunction FindParentImage(item) \r\n{\r\n\tif (!item.parentNode)\r\n\t\treturn null;\r\n\tif (item.tagName.toLowerCase() == 'img') \r\n\t{\r\n\t\treturn item;\r\n\t} \r\n\telse \r\n\t{\r\n\t\treturn FindParentImage(item.parentNode);\r\n\t}\r\n}\r\n\r\nfunction HandleContextMenu() \r\n{\r\n\tvar linkItem = FindParentLink(event.srcElement);\r\n    var imageItem = FindParentImage(event.srcElement);\r\n    var notifyOutput = '';\r\n    if (linkItem != null) if (linkItem.href != null) notifyOutput += linkItem.href;\r\n    if (imageItem != null) if (imageItem.src != null) notifyOutput += imageItem.src;\r\n    if (notifyOutput != '')\r\n        window.external.notify(notifyOutput);\r\n    else\r\n\t\twindow.external.notify('NOTLINKIMG');\r\n}");
                webBrowser.InvokeScript("execScript", "document.oncontextmenu = HandleContextMenu;");
            }
        }
        catch
        {
        }
    }

我通过ScriptNotify 监控结果,但它从未触发

    private void webBrowser_ScriptNotify(object sender, NotifyEventArgs e)
    {
        Debug.WriteLine(e.Value.ToString());
    }

有人知道如何在 WP8 浏览器控件中附加上下文菜单吗?

编辑

我发现window.navigator.msPointerEnabled 在 WebBrowser 控件上为假,在 Internet Explorer 应用程序上为真。那么这是否意味着我们无法在控件中正确实现触摸事件检测。我们可以将其设置为启用吗?

【问题讨论】:

    标签: c# javascript browser windows-phone-8 contextmenu


    【解决方案1】:

    以下代码有效,但即使您点击任何图像或链接,它也会触发。由于无法附加,我们可能不得不添加某种计时器。

    编辑:

    我想通了!以下代码在 WP8 中有效,并且只检测到按住,而不是点击。

    public void AttachScripts()
        {
            try
            {
                if (GINternet.IsScriptEnabled)
                {
                    var scriptsText = @"function ReplaceBadXmlChars(str) {
                                                var stri = str.split('&').join('&');
                                                stri = stri.split('<').join('&lt;');
                                                stri = stri.split('>').join('&gt;');
                                                stri = stri.split(""'"").join('&apos;');
                                                stri = stri.split('""""').join('&quot;');
                                                return stri;
                                }
    
                                function FindParentLink(item) {
                                if (!item.parentNode)
                                    return null;
                                if (item.tagName.toLowerCase() == 'a') {
                                    return item;
                                } else {
                                    return FindParentLink(item.parentNode);
                                }}
    
                                function FindParentImage(item) {
                                if (!item.parentNode)
                                    return null;
                                if (item.tagName.toLowerCase() == 'img') { 
                                    return item;
                                } else {
                                    return FindParentImage(item.parentNode);
                                }}
    
                                var currGNetMouseTimer;
                                window.document.body.addEventListener('pointerdown', function (evt) {
                                                                evt = evt || window.event;
    
                                                                var linkItem = FindParentLink(evt.srcElement);
                                                                var imageItem = FindParentImage(evt.srcElement);
    
                                                                currGNetMouseTimer = window.setTimeout(function() {
                                                                                var notifyMsg = '';
    
                                                                                if (linkItem != null && linkItem.href != null) {
                                                                                    notifyMsg += ReplaceBadXmlChars(linkItem.href);
                                                                                }
    
                                                                                if (imageItem != null && imageItem.src != null) {
                                                                                    notifyMsg += ReplaceBadXmlChars(imageItem.src);
                                                                                }
    
                                                                                if (notifyMsg != '') {
                                                                                    window.external.notify(notifyMsg);
                                                                                } else {
                                                                                    window.external.notify('NOTLINKIMG');
                                                                                }
                                                                }, 750);
                                },false);
    
                                window.document.body.addEventListener('pointermove', function (evt) {
                                                window.clearTimeout(currGNetMouseTimer);
                                },false); 
    
                                window.document.body.addEventListener('pointerup', function (evt) {
                                                window.clearTimeout(currGNetMouseTimer);
                                },false); 
    
                                window.document.body.addEventListener('pointerout', function (evt) {
                                                window.clearTimeout(currGNetMouseTimer);
                                },false);";
    
    
    
                    GINternet.InvokeScript("execScript", new string[] { scriptsText });
                }
            }
            catch
            {
            }
        }
    
        private void GINternet_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            //REQUIRED FOR WINDOWS PHONE 8
            AttachScripts();
    }
    

    【讨论】:

      【解决方案2】:

      这是我的解决方案。它适用于 Windows Phone 8

      <phone:WebBrowser
                      x:Name="WebBrowser"
                      IsHitTestVisible="True"
                      IsScriptEnabled="True"
                      LoadCompleted="WebBrowser_LoadCompleted"
                                                                      ScriptNotify="WebBrowser_ScriptNotify">
                                
      </phone:WebBrowser>
       
      private void WebBrowser_LoadCompleted(object sender, NavigationEventArgs e)
      {
                      if (WebBrowser.IsScriptEnabled)
                      {
                                      var JavaScriptText =
                                                      @"function ReplaceBadXmlChars(str) {
                                                      var stri = str.split('&').join('&amp;');
                                                      stri = stri.split('<').join('&lt;');
                                                      stri = stri.split('>').join('&gt;');
                                                      stri = stri.split("'").join('&apos;');
                                                      stri = stri.split('"').join('&quot;');
                                                      return stri;
                                      }
       
                                      function FindParentByTag(item, tag) {
                                                      if (!item.parentNode) return null;
                                                      if (item.tagName.toLowerCase() == tag.toLowerCase()) {
                                                                      return item;
                                                      } else {
                                                                      return FindParentByTag(item.parentNode, tag);
                                                      }
                                      }
       
                                      function OnClick() {
                                                      var linkItem = FindParentByTag(event.srcElement, 'a');
                                                      var imageItem = FindParentByTag(event.srcElement, 'img');
       
                                                      var zoom = screen.deviceXDPI / screen.logicalXDPI;
                                                      var valid = false;
                                                      var notifyMsg = '<Click ';
                                                      {
                                                                      notifyMsg += 'pos="' + parseInt(event.clientX * zoom) + ',' + parseInt(event.clientY * zoom) + '" ';
                                                                      if (linkItem != null && linkItem.href != null && !linkItem.href.startsWith("javascript")) {
                                                                                      notifyMsg += 'url="' + ReplaceBadXmlChars(linkItem.href) + '" ';
                                                                                      valid = true;
                                                                      }
       
                                                                      if (imageItem != null && imageItem.href != null && !linkItem.href.startsWith("javascript")) {
                                                                                      notifyMsg += 'img="' + ReplaceBadXmlChars(imageItem.src) + '" ';
                                                                                      valid = true;
                                                                      }
                                                      }
                                                      notifyMsg += '/>';
                                                      if (valid) {
                                                                      window.external.notify(notifyMsg);
                                                                      return false;
                                                      }
                                      }
       
       
                                      function RegisterClickNotification() {
                                                      window.document.onclick = OnClick;
       
                                                      window.document.body.addEventListener('MSPointerDown', function(evt) {
                                                                      evt = evt || window.event;
       
                                                                      var linkItem = FindParentByTag(evt.srcElement, 'a');
                                                                      var imageItem = FindParentByTag(evt.srcElement, 'img');
       
                                                                      window.devicePixelRatio = window.screen.deviceXDPI / window.screen.logicalXDPI;
                                                                      var doc = window.document.documentElement;
                                                                      var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
                                                                      var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
       
                                                                      var timerId = window.setTimeout(function() {
                                                                                      var notifyMsg = 'pos="' + parseInt((evt.clientX - left)) + ',' + parseInt((evt.clientY - top)) + '" ';
       
                                                                                      if (linkItem != null && linkItem.href != null) {
                                                                                                      notifyMsg += 'url="' + ReplaceBadXmlChars(linkItem.href) + '" ';
                                                                                      }
       
                                                                                      if (imageItem != null && imageItem.href != null) {
                                                                                                      notifyMsg += 'img="' + ReplaceBadXmlChars(imageItem.src) + '" ';
                                                                                      }
       
                                                                                      window.external.notify('<Hold ' + notifyMsg + '/>');
                                                                      }, 500);
                                                                      StopLoading();
                                                                      evt.target.data = timerId;
                                                      });
                                      }
       
                                      window.document.body.addEventListener('MSPointerUp', function (evt) {
                                                      window.clearTimeout(evt.target.data);
                                      });
       
                                      window.document.body.addEventListener('MSPointerMove', function (evt) {   
                                                      window.clearTimeout(evt.target.data);   
                                      });
       
                                      window.document.body.addEventListener('MSPointerOut', function (evt) {
                                                      window.clearTimeout(evt.target.data);
                                      });
       
                                      window.document.body.addEventListener('pointerup', function (evt) {
                                       
                                      });"
       
                                      WebBrowser.InvokeScript("eval", new string[] { JavaScriptText });
                                      WebBrowser.InvokeScript("RegisterClickNotification");
                                      WebBrowser.InvokeScript("execScript", new string[] {
                                      "function eventListener(evt) {if (evt.type == 'MSPointerDown'){ gestureHandler.addPointer(evt.pointerId); return; } if (evt.detail & evt.MSGESTURE_FLAG_END) {  window.external.notify(evt.srcElement.tagName);}}" });
                                      WebBrowser.InvokeScript("execScript", new string[] { "document.addEventListener('MSGestureHold', eventListener, false); document.addEventListener('MSPointerDown', eventListener, false);  gestureHandler = new MSGesture(); gestureHandler.target = document.body;" });
                      }
      }
      

      【讨论】:

        【解决方案3】:

        在尝试让 WP8 网络浏览器控件做一些技巧之后,这里有一些观察。

        ...

        System.SystemException
        Message=发生未知错误。错误:80020101。

        ... 通常意味着您的 javascript 未正确解析。通常是语法错误。

        我发现删除 CR、LF 和 TAB 字符可以减少噪音,并使在 VisualStudio JavaScript 编辑器窗口中查找语法错误更容易一些。 String.Replace() 是你的朋友。

        我只是成功地使用 InvokeScript() 来执行匿名函数。这个模式已经成功了:(注意标点)

        webBrowser.InvokeScript("eval", "(function (param1) { window.external.notify(param1); })('this is your message');");
        

        在您的具体情况下,我看到定义了三个函数,但是是什么导致它们被执行?也许这解释了异常。

        盖尔

        【讨论】:

          【解决方案4】:

          如果window.navigator.msPointerEnabled为false,可以使用onmousedown和onmouseup进行监控

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-05-25
            • 2015-01-09
            • 2017-06-29
            • 1970-01-01
            • 2013-10-28
            • 2012-01-24
            • 2015-07-11
            • 1970-01-01
            相关资源
            最近更新 更多