在浏览网页时,有的链接点开是在本页面打开,而有的链接会新建窗口 。
这就导致我在使用后退快捷键(鼠标侧键、Backspace、Alt+←键)操作时变得很不确定。
因为如果是新建窗口打开页面无法使用后退键关闭,而我不可能时时去关注是不是新窗口。
我希望浏览器有统一的操作逻辑,如果是新窗口打开的页面,也能用后退键直接关闭。
请问各位大佬,有没有类似的插件呢?
用autohotkey可以做到
全部代码见下一楼,主要是通过判断当前网页地址来实现
按下快捷键后,首先发送一个返回指令,如果500ms内,网页地址没有改变,再发送一个关闭当前标签的指令。
关键代码
#IfWinActive , ahk_exe msedge.exe
;这里以edge浏览器为例,修改msedge.exe为你的浏览器exe名即可
$Browser_Back::
;此处以浏览器后退键为例,鼠标侧键可改为xbutton1,退格键Backspace,Alt+←为!left
{
old_sURL := GetActiveBrowserURL()
Send,{Browser_Back}
Sleep,500
;此处为500ms,根据你的忍受范围设置,数字越大误杀网页几率越小
new_sURL := GetActiveBrowserURL()
if (old_sURL = new_sURL)
sendinput,^w
}
Return
全部代码
; AutoHotkey Version: AutoHotkey 1.1
; Language: English
; Platform: Win7 SP1 / Win8.1 / Win10
; Author: Antonio Bueno <user atnbueno of Google's popular e-mail service>
; Short description: Gets the URL of the current (active) browser tab for most modern browsers
; Last Mod: 2016-05-19
Menu, Tray, Icon, % A_WinDir "\system32\netshell.dll", 86 ; Shows a world icon in the system tray
ModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,MozillaWindowClass,Slimjet_WidgetWin_1"
LegacyBrowsers := "IEFrame,OperaWindowClass"
#IfWinActive , ahk_exe msedge.exe
$Browser_Back::
{
old_sURL := GetActiveBrowserURL()
Send,{Browser_Back}
Sleep,500
new_sURL := GetActiveBrowserURL()
if (old_sURL = new_sURL)
sendinput,^w
}
Return
GetActiveBrowserURL() {
global ModernBrowsers, LegacyBrowsers
WinGetClass, sClass, A
If sClass In % ModernBrowsers
Return GetBrowserURL_ACC(sClass)
Else If sClass In % LegacyBrowsers
Return GetBrowserURL_DDE(sClass) ; empty string if DDE not supported (or not a browser)
Else
Return ""
}
; "GetBrowserURL_DDE" adapted from DDE code by Sean, (AHK_L version by maraskan_user)
; Found at http://autohotkey.com/board/topic/17633-/?p=434518
GetBrowserURL_DDE(sClass) {
WinGet, sServer, ProcessName, % "ahk_class " sClass
StringTrimRight, sServer, sServer, 4
iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
DllCall("DdeUnaccessData", "UPtr", hData)
DllCall("DdeFreeDataHandle", "UPtr", hData)
DllCall("DdeDisconnect", "UPtr", hConv)
DllCall("DdeUninitialize", "UPtr", idInst)
csvWindowInfo := StrGet(&sData, "CP0")
StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
Return sWindowInfo2
}
GetBrowserURL_ACC(sClass) {
global nWindow, accAddressBar
If (nWindow != WinExist("ahk_class " sClass)) ; reuses accAddressBar if it's the same window
{
nWindow := WinExist("ahk_class " sClass)
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindow))
}
Try sURL := accAddressBar.accValue(0)
If (sURL == "") {
WinGet, nWindows, List, % "ahk_class " sClass ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
If (nWindows > 1) {
accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindows2))
Try sURL := accAddressBar.accValue(0)
}
}
If ((sURL != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
sURL := "http://" sURL
If (sURL == "")
nWindow := -1 ; Don't remember the window if there is no URL
Return sURL
}
; "GetAddressBar" based in code by uname
; Found at http://autohotkey.com/board/topic/103178-/?p=637687
GetAddressBar(accObj) {
Try If ((accObj.accRole(0) == 42) and IsURL(accObj.accValue(0)))
Return accObj
Try If ((accObj.accRole(0) == 42) and IsURL("http://" accObj.accValue(0))) ; Modern browsers omit "http://"
Return accObj
For nChild, accChild in Acc_Children(accObj)
If IsObject(accAddressBar := GetAddressBar(accChild))
Return accAddressBar
}
IsURL(sURL) {
Return RegExMatch(sURL, "^(?<Protocol>https?|ftp)://(?<Domain>(?:[\w-]+\.)+\w\w+)(?::(?<Port>\d+))?/?(?<Path>(?:[^:/?# ]*/?)+)(?:\?(?<Query>[^#]+)?)?(?:\#(?<Hash>.+)?)?$")
}
; The code below is part of the Acc.ahk Standard Library by Sean (updated by jethrow)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
Acc_Init()
{
static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObjEnwrap(9,pacc,1)
}
Acc_Query(Acc) {
Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Children(Acc) {
If ComObjType(Acc,"Name") != "IAccessible"
ErrorLevel := "Invalid IAccessible Object"
Else {
Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
If DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
Loop %cChildren%
i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
Return Children.MaxIndex()?Children:
} Else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
}
我觉得换一种思路可能体验比较好:
看看浏览器的返回按钮能不能按,或者js的history.length===1
,然后分情况调用真正的返回或者关闭。
不过这个难度可能会高一些。
虽然但是,为啥要用后退键啊,ctrl + w 不是就能关新标签页吗。
另外按住 ctrl 再点链接不是会在新标签页打开链吗。这样不就统一让链接打开到新标签了。
如果是个人习惯用退格当我没说。
可以考虑用锁定标签页的扩展,防止打开新标签页
有此类扩展推荐吗
@heretic43
建议打开新窗口用鼠标中键点击
建议关闭窗口用鼠标手势,设置鼠标手势按住右键+左键关闭窗口
会给你不一样的体验
对的,如果能识别返回按钮应该会是最好的方案
鼠标中键默认就是打开新窗口,但是在后台打开,还需要切换过去。Edge浏览器好像不能改成中键前台打开新窗口。鼠标手势确实好用
那就改用拖拽打开新链接
@LinkLi
是个办法
延伸一下,换个思路,有没有始终在当前页面打开链接的插件呢?这样后退键就能始终有效了
国外的网站大部分是当前页打开链接的。
国内好多网站是新建页面打开链接的,这个估计没法解决。
网站开发针对的用户习惯不同
这是脚本
浏览器扩展有
Always open in current tab
Link in Current Tab
https://chrome.google.com/webstore/detail/link-in-current-tab/cbkcdebbfbegnmbephalggnchfebihbl
我觉得楼主选择的解决方案可能不是最优。
如果想选择在新标签页还是在当前页面打开链接,推荐 target=“_blank”-toggler(这个扩展我用了很多年):
Firefox版: target="_blank"-toggler – Get this Extension for 🦊 Firefox (en-US)
Chromium版: target="_blank"-toggler - Chrome Web Store
点击“后退”以关闭标签并回到上一个激活标签页的扩展:
在Firefox上,Back to Close WE: Back to Close WE – Get this Extension for 🦊 Firefox (en-US)
在Chromium上,Close on Back: Close on Back - Chrome Web Store
我觉得上面这几个扩展可能和楼主的需求更贴切。
你可以考虑用 vimium 扩展,可用 x 键关闭网页,很顺手,用上就离不开了。
这是 Chrome 商店的地址。
类似的有 SurfingKeys
SurfingKeys: 一个更强的 Vimium 类 Chrome 插件