【问题标题】:Detect parents' and grandparents' links in Javascript在 Javascript 中检测父母和祖父母的链接
【发布时间】:2017-01-22 13:24:30
【问题描述】:

我正在用 C# 制作一个 Web 浏览器,并根据用户右键单击的元素显示自定义上下文菜单。我无法确定应将哪些元素视为链接?

if (el_tag == "a")
    showLinkMenu();

else if (el_tag == "img" && parent_tag == "a")
    showAdvancedMenu();

else if (el_tag == "img")
    showImgMenu();

第一枪:Google chrome detected this as a link

Shot2:Structurea > div > div > div > div > img

我应该怎么做才能检测到此类链接?

【问题讨论】:

  • 请考虑现有的网络浏览器不会那样做。相反,每个嵌套元素都会接收点击事件并根据自己的逻辑处理它,因此在您的示例中,a 和四个 div 以及图像都将接收该点击事件,从外部到内部(按顺序)。如果锚点有一个 href,逻辑上说它应该成为一个导航动作,因此会中断进一步的传播。
  • var p = el_tag; while (1) { p = p.parentElement.tagName; if (p == 'a' || p == 'body') { alert(p); break; } } 这个怎么样?
  • ?我以为你说你在用 C# 工作
  • 使用CefSharp并发送命令执行JS

标签: javascript c# jquery cefsharp


【解决方案1】:

如果其中任何一个是带有href 属性的<a>,您应该迭代父标签列表并将其称为链接。

【讨论】:

    【解决方案2】:

    我建议实现您自己的IContextMenuHandler 并使用内置的CefMenuCommandTypeFlag 来帮助您。有了这个,您可以根据已右键单击的元素添加或删除上下文菜单项。

    MenuHandler.cs

    internal class MenuHandler : IContextMenuHandler
    {
        private const int SaveImage = 26503;
        private const int OpenLinkNewTab = 26501;
    
        public event EventHandler OnSaveImage = delegate { };
    
        void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
        {
            if(parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents)
            {
                model.AddItem((CefMenuCommand)SaveImage, "Save image");
            }
            if(!string.IsNullOrEmpty(parameters.UnfilteredLinkUrl))
            {
                model.AddItem((CefMenuCommand)OpenLinkNewTab, "Open link in new tab");
            }
        }
    
         bool  IContextMenuHandler.OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
         {
            return false;
         }
    
        void IContextMenuHandler.OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
        {
            if ((int)commandId == SaveImage)
            {
                OnSaveImage?.Invoke(this, new ImageSaveEventArgs(parameters.SourceUrl)); //ImageSaveEventArgs is just a class with one property that houses the source url of the image to download.
            }
        }
    
        bool IContextMenuHandler.RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
        {
            return false;
        }
    }
    

    然后,无论您在哪里创建 ChromiumWebBrowser 实例,都可以执行以下操作:

    ChromiumWebBrowser browser = new ChromiumWebBrowser();
    MenuHandler menuHandler = new MenuHandler();
    menuHandler.OnSaveImage +=  Handler_OnSaveImage;
    browser.MenuHandler = menuHandler;
    
    private void Handler_OnSaveImage(object sender, EventArgs e)
    {
        DownloadImage(((ImageSaveEventArgs)e).SourceUrl);
    }
    

    注意,这只是使用内置IContextMenuHandler 获取用户右键单击的内容,然后处理我自己的事件以便实现所需行为的示例。在这种情况下,可以从 URL 下载文件。

    有关更多详细信息和其他示例,请参阅 CefSharp 的 GitHub 页面上的 MenuHandler.cs

    【讨论】:

    • 我的代码更简单,满足我的所有要求。无论如何谢谢!我的 C# 代码已经写好了,对 JavaScript 感到困惑。
    • @WorldBoss 够公平的。过去,我在使用 WebBrowser 控件 (stackoverflow.com/questions/36767938/…) 时尝试过自己的尝试,并且度过了一段非常痛苦的时光。当涉及到 HTML 文档时,有一百万零一个边缘情况,所以我更喜欢使用一个可能比以往更好地解决它的引擎。如果你有小要求并且你已经满足了,那么自己动手是很酷的! :-)
    • 感谢分享该链接!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    相关资源
    最近更新 更多