问题描述
这里有人有开发 IE 扩展的经验吗?可以分享他们的知识吗?这将包括代码示例、优秀示例的链接、流程文档或任何内容.
Does anyone here have experience with/in developing IE extensions that can share their knowledge? This would include code samples, or links to good ones, or documentation on the process, or anything.
我真的很想这样做,但是我遇到了糟糕的文档,糟糕的代码/示例代码/缺乏的巨大墙壁.如果您能提供任何帮助/资源,我们将不胜感激.
I really want to do this, but I'm hitting a giant wall with lousy documentation, lousy code/example code/lack thereof. Any help/resources you could offer would be greatly appreciated.
具体来说,我想从如何从 IE 扩展中访问/操作 DOM 开始.
Specifically, I would like to start with how to get access to/manipulate the DOM from within a IE extension.
编辑,更多细节:
理想情况下,我想植入一个工具栏按钮,单击该按钮时,会弹出一个包含外部站点链接的菜单.我还想根据某些条件访问 DOM 并在页面上植入 JavaScript.
Ideally, I would like to plant a toolbar button that, when clicked, popped a menu up that contains links to external sites. I would also like to access the DOM and plant JavaScript on the page depending on some conditions.
在 IE 扩展中保存信息的最佳方式是什么?在 Firefox/Chrome/大多数现代浏览器中,您使用 window.localStorage
,但显然对于 IE8/IE7,这不是一个选项.也许是 SQLite DB 之类的?可以假设 .NET 4.0 将安装在用户的计算机上吗?
What is the best way to persist information in an IE extension? In Firefox/Chrome/Most modern browsers, you use window.localStorage
, but obviously with IE8/IE7, that's not an option. Maybe a SQLite DB or such? It is okay to assume that .NET 4.0 will be installed on a user's computer?
我不想使用 Spice IE,因为我想构建一个与 IE9 兼容的.我也在这个问题中添加了 C++ 标签,因为如果用 C++ 构建一个更好,我可以做到.
I don't want to use Spice IE as I want to build one that is compatible with IE9 as well. I've added the C++ tag to this question as well, because if it's better to build one in C++, I can do that.
推荐答案
[UPDATE] 我正在更新此答案以在 Windows 10 x64 中使用 Internet Explorer 11> 与 Visual Studio 2017 社区.此答案的先前版本(适用于 Internet Explorer 8,在 Windows 7 x64 和 Visual Studio 2010 中)位于此答案的底部.
[UPDATE] I'm updating this answer to work with Internet Explorer 11, in Windows 10 x64 with Visual Studio 2017 Community.The previous version of this answer (for Internet Explorer 8, in Windows 7 x64 and Visual Studio 2010) is at the bottom of this answer.
我使用的是 Visual Studio 2017 Community、C#、.Net Framework 4.6.1,因此其中一些步骤可能略有不同给你.
I am using Visual Studio 2017 Community, C#, .Net Framework 4.6.1, so some of these steps might be slightly different for you.
您需要以管理员身份打开 Visual Studio 来构建解决方案,以便构建后脚本可以注册 BHO(需要注册表访问权限).
You need to open Visual Studio as Administrator to build the solution, so that the post-build script can register the BHO (needs registry access).
首先创建一个类库.我打电话给我的InternetExplorerExtension.
Start by creating a class library.I called mine InternetExplorerExtension.
将这些引用添加到项目中:
Add these references to the project:
- Interop.SHDocVw:COM 选项卡/搜索
Microsoft Internet Controls"
- Microsoft.mshtml:程序集选项卡/搜索
"Microsoft.mshtml"
注意: 不知何故,MSHTML 没有在我的系统中注册,即使我可以在添加引用"窗口中找到.这导致构建时出错:
Note: Somehow MSHTML was not registered in my system, even though I could find in in the Add Reference window. This caused an error while building:
找不到类型库MSHTML"的包装程序集
可以在 http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html或者,您可以运行此批处理脚本:
The fix can be found at http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.htmlOr, you can run this batch script:
"%ProgramFiles(x86)%Microsoft Visual Studio2017CommunityCommon7ToolsVsDevCmd.bat"
cd "%ProgramFiles(x86)%Microsoft Visual Studio2017CommunityCommon7IDEPublicAssemblies"
regasm Microsoft.mshtml.dll
gacutil /i Microsoft.mshtml.dll
创建以下文件:
IEAddon.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
using mshtml;
using SHDocVw;
namespace InternetExplorerExtension
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("D40C654D-7C51-4EB3-95B2-1E23905C2A2D")]
[ProgId("MyBHO.WordHighlighter")]
public class WordHighlighterBHO : IObjectWithSite, IOleCommandTarget
{
const string DefaultTextToHighlight = "browser";
IWebBrowser2 browser;
private object site;
#region Highlight Text
void OnDocumentComplete(object pDisp, ref object URL)
{
try
{
// @Eric Stob: Thanks for this hint!
// This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
//if (pDisp != this.site)
// return;
var document2 = browser.Document as IHTMLDocument2;
var document3 = browser.Document as IHTMLDocument3;
var window = document2.parentWindow;
window.execScript(@"function FncAddedByAddon() { alert('Message added by addon.'); }");
Queue<IHTMLDOMNode> queue = new Queue<IHTMLDOMNode>();
foreach (IHTMLDOMNode eachChild in document3.childNodes)
queue.Enqueue(eachChild);
while (queue.Count > 0)
{
// replacing desired text with a highlighted version of it
var domNode = queue.Dequeue();
var textNode = domNode as IHTMLDOMTextNode;
if (textNode != null)
{
if (textNode.data.Contains(TextToHighlight))
{
var newText = textNode.data.Replace(TextToHighlight, "<span style='background-color: yellow; cursor: hand;' onclick='javascript:FncAddedByAddon()' title='Click to open script based alert window.'>" + TextToHighlight + "</span>");
var newNode = document2.createElement("span");
newNode.innerHTML = newText;
domNode.replaceNode((IHTMLDOMNode)newNode);
}
}
else
{
// adding children to collection
var x = (IHTMLDOMChildrenCollection)(domNode.childNodes);
foreach (IHTMLDOMNode eachChild in x)
{
if (eachChild is mshtml.IHTMLScriptElement)
continue;
if (eachChild is mshtml.IHTMLStyleElement)
continue;
queue.Enqueue(eachChild);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region Load and Save Data
static string TextToHighlight = DefaultTextToHighlight;
public static string RegData = "Software\MyIEExtension";
[DllImport("ieframe.dll")]
public static extern int IEGetWriteableHKCU(ref IntPtr phKey);
private static void SaveOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);
if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);
writeable_registry.Close();
}
private static void LoadOptions()
{
// In IE 7,8,9,(desktop)10 tabs run in Protected Mode
// which prohibits writes to HKLM, HKCU.
// Must ask IE for "Writable" registry section pointer
// which will be something like HKU/S-1-7***/Software/AppDataLow/
// In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
// where BHOs are not allowed to run, except in edge cases.
// see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
IntPtr phKey = new IntPtr();
var answer = IEGetWriteableHKCU(ref phKey);
RegistryKey writeable_registry = RegistryKey.FromHandle(
new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
);
RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);
if (registryKey == null)
registryKey = writeable_registry.CreateSubKey(RegData);
registryKey.SetValue("Data", TextToHighlight);
if (registryKey == null)
{
TextToHighlight = DefaultTextToHighlight;
}
else
{
TextToHighlight = (string)registryKey.GetValue("Data");
}
writeable_registry.Close();
}
#endregion
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
[InterfaceType(1)]
public interface IServiceProvider
{
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}
#region Implementation of IObjectWithSite
int IObjectWithSite.SetSite(object site)
{
this.site = site;
if (site != null)
{
LoadOptions();
var serviceProv = (IServiceProvider)this.site;
var guidIWebBrowserApp = Marshal.GenerateGuidForType(typeof(IWebBrowserApp)); // new Guid("0002DF05-0000-0000-C000-000000000046");
var guidIWebBrowser2 = Marshal.GenerateGuidForType(typeof(IWebBrowser2)); // new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
IntPtr intPtr;
serviceProv.QueryService(ref guidIWebBrowserApp, ref guidIWebBrowser2, out intPtr);
browser = (IWebBrowser2)Marshal.GetObjectForIUnknown(intPtr);
((DWebBrowserEvents2_Event)browser).DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}
else
{
((DWebBrowserEvents2_Event)browser).DocumentComplete -=
new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
browser = null;
}
return 0;
}
int IObjectWithSite.GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(browser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
Marshal.Release(punk);
return hr;
}
#endregion
#region Implementation of IOleCommandTarget
int IOleCommandTarget.QueryStatus(IntPtr pguidCmdGroup, uint cCmds, ref OLECMD prgCmds, IntPtr pCmdText)
{
return 0;
}
int IOleCommandTarget.Exec(IntPtr pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
try
{
// Accessing the document from the command-bar.
var document = browser.Document as IHTMLDocument2;
var window = document.parentWindow;
var result = window.execScript(@"alert('You will now be allowed to configure the text to highlight...');");
var form = new HighlighterOptionsForm();
form.InputText = TextToHighlight;
if (form.ShowDialog() != DialogResult.Cancel)
{
TextToHighlight = form.InputText;
SaveOptions();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return 0;
}
#endregion
#region Registering with regasm
public static string RegBHO = "Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects";
public static string RegCmd = "Software\Microsoft\Internet Explorer\Extensions";
[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
string guid = type.GUID.ToString("B");
// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegBHO);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("Alright", 1);
registryKey.Close();
key.Close();
}
// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(RegCmd);
RegistryKey key = registryKey.OpenSubKey(guid);
if (key == null)
key = registryKey.CreateSubKey(guid);
key.SetValue("ButtonText", "Highlighter options");
key.SetValue("CLSID", "{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}");
key.SetValue("ClsidExtension", guid);
key.SetValue("Icon", "");
key.SetValue("HotIcon", "");
key.SetValue("Default Visible", "Yes");
key.SetValue("MenuText", "&Highlighter options");
key.SetValue("ToolTip", "Highlighter options");
//key.SetValue("KeyPath", "no");
registryKey.Close();
key.Close();
}
}
[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
string guid = type.GUID.ToString("B");
// BHO
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
// Command
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
}
#endregion
}
}
Interop.cs
using System;
using System.Runtime.InteropServices;
namespace InternetExplorerExtension
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
[PreserveSig]
int GetSite(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)]out IntPtr ppvSite);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct OLECMDTEXT
{
public uint cmdtextf;
public uint cwActual;
public uint cwBuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public char rgwz;
}
[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
public uint cmdID;
public uint cmdf;
}
[ComImport(), ComVisible(true),
Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryStatus(
[In] IntPtr pguidCmdGroup,
[In, MarshalAs(UnmanagedType.U4)] uint cCmds,
[In, Out, MarshalAs(UnmanagedType.Struct)] ref OLECMD prgCmds,
//This parameter must be IntPtr, as it can be null
[In, Out] IntPtr pCmdText);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Exec(
//[In] ref Guid pguidCmdGroup,
//have to be IntPtr, since null values are unacceptable
//and null is used as default group!
[In] IntPtr pguidCmdGroup,
[In, MarshalAs(UnmanagedType.U4)] uint nCmdID,
[In, MarshalAs(UnmanagedType.U4)] uint nCmdexecopt,
[In] IntPtr pvaIn,
[In, Out] IntPtr pvaOut);
}
}
最后是一个表单,我们将用它来配置选项.在这个表单中放置一个 TextBox
和一个 Ok Button
.将按钮的 DialogResult 设置为 Ok.将此代码放在表单代码中:
and finally a form, that we will use to configure the options. In this form place a TextBox
and an Ok Button
. Set the DialogResult of the button to Ok. Place this code in the form code:
using System.Windows.Forms;
namespace InternetExplorerExtension
{
public partial class HighlighterOptionsForm : Form
{
public HighlighterOptionsForm()
{
InitializeComponent();
}
public string InputText
{
get { return this.textBox1.Text; }
set { this.textBox1.Text = value; }
}
}
}
在项目属性中,执行以下操作:
In the project properties, do the following:
- 使用强密钥对程序集进行签名;
- 在调试选项卡中,将启动外部程序设置为
C:Program Files (x86)Internet Exploreriexplore.exe
- 在调试"选项卡中,将命令行参数设置为
http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
莉> 在构建事件选项卡中,将构建后事件命令行设置为:
"%ProgramFiles(x86)%Microsoft SDKsWindowsv10.0AinNETFX 4.6.1 Toolsgacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
"%windir%Microsoft.NETFrameworkv4.0.30319RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
"%windir%Microsoft.NETFrameworkv4.0.30319RegAsm.exe" "$(TargetDir)$(TargetFileName)"
注意:即使我的电脑是 x64,我也使用了非 x64 gacutil.exe
的路径并且它有效...... x64 特定的一个是在:
Attention: even though my computer is x64, I used the path of the non-x64 gacutil.exe
and it worked... the one specific for x64 is at:
C:Program Files (x86)Microsoft SDKsWindowsv10.0AinNETFX 4.6.1 Toolsx64gacutil.exe
64 位 IE 需要 64 位编译和 64 位注册 BHO.虽然我只能使用 32 位 IE11 进行调试,但 32 位注册扩展也可以通过运行 64 位 IE11 来运行.
64bit IE Needs 64bit-compiled and 64bit-registered BHO. Though I could only debug using 32bit IE11, the 32bit registered extension also worked by running 64bit IE11.
这个答案似乎有一些关于这个的额外信息:https://stackoverflow.com/a/23004613/195417
This answer appears to have some additional info about this: https://stackoverflow.com/a/23004613/195417
如果需要,可以使用 64 位 regasm:
If you need to, you can use the 64bit regasm:
%windir%Microsoft.NETFramework64v4.0.30319RegAsm.exe
这个插件的工作原理
我没有改变附加组件的行为...请查看下面的 IE8 部分的说明.
I didn't change the behavior of the add-on... take a look at IE8 section bellow for description.
伙计……这工作量很大!我很好奇如何做到这一点,所以我自己做了.
Man... this has been a lot of work!I was so curious about how to do this, that I did it myself.
首先……功劳不全是我的.这是我在这些网站上发现的内容的汇编:
First of all... credit is not all mine. This is a compilation of what I found, on these sites:
- CodeProject 文章,如何制作 BHO;
- 15seconds,不过不是15秒,用了大概7个小时;
- 微软教程,有帮助我添加了命令按钮.
- 还有这个社交.msdn 主题,这帮助我确定程序集必须在 GAC 中.
- 这篇 MSDN 博客文章包含一个完整的示例
- 许多其他网站,在发现过程中......
- CodeProject article, how to make a BHO;
- 15seconds, but it was not 15 seconds, it took about 7 hours;
- Microsoft tutorial, helped me adding the command button.
- And this social.msdn topic, that helped me figure out that the assembly must be in the GAC.
- This MSDN blog post contains a fully-working example
- many other sites, in the discovery process...
当然,我希望我的答案具有您所要求的功能:
And of course, I wanted my answer to have the features you asked:
- DOM遍历找东西;
- 一个显示窗口的按钮(在我的例子中是设置)
- 保留配置(我将使用注册表)
- 最后执行 javascript.
我将逐步描述它,我是如何在 Windows 7 x64 中使用 Internet Explorer 8 做到这一点的...请注意,我无法测试在其他配置中.希望你明白=)
I will describe it step by step, how I managed to do it working with Internet Explorer 8, in Windows 7 x64... note that I could not test in other configurations. Hope you understand =)
我使用的是 Visual Studio 2010、C# 4、.Net Framework 4,因此其中一些步骤对您来说可能略有不同.
I am using Visual Studio 2010, C# 4, .Net Framework 4, so some of these steps might be slightly different for you.
创建了一个类库.我打电话给我的InternetExplorerExtension.
Created a class library. I called mine InternetExplorerExtension.
将这些引用添加到项目中:
Add these references to the project:
- 互操作.SHDocVw
- Microsoft.mshtml
注意:这些引用可能位于每台计算机的不同位置.
这是我在 csproj 中的参考部分包含的内容:
this is what my references section in csproj contains:
<Reference Include="Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=90ba9c70f846762e, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>C:Program Files (x86)Microsoft Visual Studio 9.0Common7IDEPrivateAssembliesInterop.SHDocVw.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.mshtml, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
以与更新的 IE11 文件相同的方式创建文件.
Create the files the same way as the updated IE11 files.
IEAddon.cs
您可以在 IE11 版本中取消注释以下行:
You can uncomment the following lines from IE11 version:
...
// @Eric Stob: Thanks for this hint!
// This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
if (pDisp != this.site)
return;
...
Interop.cs
与IE11版本相同.
最后是一个表单,我们将用它来配置选项.在这个表单中放置一个 TextBox
和一个 Ok Button
.将按钮的 DialogResult 设置为 Ok.IE11插件的代码相同.
and finally a form, that we will use to configure the options. In this form place a TextBox
and an Ok Button
. Set the DialogResult of the button to Ok. The code is the same for IE11 addon.
在项目属性中,执行以下操作:
In the project properties, do the following:
- 使用强密钥对程序集进行签名;
- 在调试选项卡中,将启动外部程序设置为
C:Program Files (x86)Internet Exploreriexplore.exe
- 在调试"选项卡中,将命令行参数设置为
http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
莉> 在构建事件选项卡中,将构建后事件命令行设置为:
"C:Program Files (x86)Microsoft SDKsWindowsv7.0ABinNETFX 4.0 Toolsx64gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
"C:WindowsMicrosoft.NETFrameworkv4.0.30319RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
"C:WindowsMicrosoft.NETFrameworkv4.0.30319RegAsm.exe" "$(TargetDir)$(TargetFileName)"
注意:因为我的电脑是 x64,所以在我的机器上 gacutil 可执行文件的路径中有一个特定的 x64,在你的机器上可能会有所不同.
Attention: as my computer is x64, there is a specific x64 inside the path of gacutil executable on my machine that may be different on yours.
64 位 IE 需要 64 位编译和 64 位注册 BHO.使用 64 位 RegAsm.exe(通常位于 C:WindowsMicrosoft.NETFramework64v4.0.30319RegAsm.exe)
64bit IE Needs 64bit-compiled and 64bit-registered BHO. Use 64bit RegAsm.exe (usually lives in C:WindowsMicrosoft.NETFramework64v4.0.30319RegAsm.exe)
这个插件的工作原理
它遍历所有 DOM 树,替换使用按钮配置的文本,本身带有黄色背景.如果您单击泛黄的文本,它会调用动态插入页面的 javascript 函数.默认词是浏览器",所以它匹配很多! 更改要突出显示的字符串后,必须单击 URL 框并按 Enter... F5 不起作用,我认为是因为 F5 被视为导航",并且它需要监听导航事件(可能).我稍后会尝试解决这个问题.
It traverses all DOM tree, replacing the text, configured using the button, by itself with a yellow background. If you click on the yellowed texts, it calls a javascript function that was inserted on the page dynamically. The default word is 'browser', so that it matches a lot of them! after changing the string to be highlighted, you must click the URL box and press Enter... F5 will not work, I think that it is because F5 is considered as 'navigation', and it would require to listen to navigate event (maybe). I'll try to fix that later.
现在,是时候离开了.我很累.随意提问...可能因为我要去旅行所以我无法回答...三天后我会回来,但我会尽量在此期间来这里.
Now, it is time to go. I am very tired.Feel free to ask questions... may be I will not be able to answer since I am going on a trip... in 3 days I'm back, but I'll try to come here in the meantime.
这篇关于如何开始开发 Internet Explorer 扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!