list fragment identifiers on a webpage (hash that jumps to point)

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

list fragment identifiers on a webpage (hash that jumps to point)

12 Feb 2017, 10:52

Sometimes I want to add a fragment identifier to a url,
to jump to a point on a webpage.
e.g.
https://autohotkey.com/docs/misc/RegEx- ... tm#Options
https://autohotkey.com/docs/Variables.htm#Operators
https://autohotkey.com/docs/Variables.htm#ternary
I wondered if anyone had any ideas that could improve the script below.
Basically I look for these things in the html:

href="#
id="
name="

For example on the Ask For Help forum, I would like
to be able to skip to 'Topics',
the best I can do so far is to skip to 'Announcements':
https://autohotkey.com/boards/viewforum ... rum-search

I couldn't find any really good reference material on fragment identifiers,
can you skip to a specific line number for example, are there other bits of html
that can define a fragment identifier.

Code: Select all

;WBGet:
;Basic Webpage Controls with JavaScript / COM - Tutorial - Tutorials - AutoHotkey Community
;https://autohotkey.com/board/topic/47052-basic-webpage-controls-with-javascript-com-tutorial/

q::
vNeedle1 = href="#
vNeedle2 = id="
vNeedle3 = name="

WinGet, hWnd, ID, ahk_class IEFrame
;oWB := JEE_WBGet("ahk_id " hWnd)
oWB := WBGet("ahk_id " hWnd)
vText := oWB.document.documentElement.innerHTML
oWB := ""
vOutput := ""
VarSetCapacity(vOutput, StrLen(vText)*2)
vText := StrReplace(vText, "`r`n", "`n")
vText := StrReplace(vText, ">", "`n>")
vText := StrReplace(vText, " ", "`n")
vText := StrReplace(vText, vNeedle1, "`n" vNeedle1)
vText := StrReplace(vText, "<" vNeedle2, "<`n" vNeedle2)
vText := StrReplace(vText, " " vNeedle2, " `n" vNeedle2)
vText := StrReplace(vText, "<" vNeedle3, "<`n" vNeedle3)
vText := StrReplace(vText, " " vNeedle3, " `n" vNeedle3)
vNeedleRegEx := "^(" vNeedle1 "|" vNeedle2 "|" vNeedle3 ")"
Loop, Parse, vText, `n
if RegExMatch(A_LoopField, vNeedleRegEx)
if !(A_LoopField = vNeedle1 """")
vOutput .= A_LoopField "`r`n"
Clipboard := vOutput
MsgBox % "done"
Return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
enter8
Posts: 102
Joined: 05 May 2016, 16:48

Re: list fragment identifiers on a webpage (hash that jumps to point)

12 Feb 2017, 14:54

If you don't have elements in the source that you can use as identifiers, how about adding them? On the page where you're trying to jump to 'topics':

https://autohotkey.com/boards/viewforum.php?f=5

if you run this javascript:

document.getElementsByClassName("list-inner")[6].id = "newanchor"

then

<div class="list-inner">Topics</div>

becomes

<div id="newanchor" class="list-inner">Topics</div>

which then allows this to work:

https://autohotkey.com/boards/viewforum ... #newanchor

I guess what I'm saying is that, rather than figuring out where the page is willing to let you link to, link to where ever you please by inserting IDs where you wish.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list fragment identifiers on a webpage (hash that jumps to point)

12 Feb 2017, 15:40

Thank you, that's an interesting technique.
This method also jumps to an element:

Code: Select all

;e.g. jump to 'Topics' header:
;Ask For Help - AutoHotkey Community
;https://autohotkey.com/boards/viewforum.php?f=5
q:: ;jump to element
WinGet, hWnd, ID, A
;oWB := JEE_WBGet("ahk_id " hWnd)
oWB := WBGet("ahk_id " hWnd)
;oElt := oWB.document.getElementsByClassName("header").item[2]
oElt := oWB.document.getElementsByClassName("header").item[3]
vPosY := oElt.getBoundingClientRect().top
oWB.document.parentWindow.scrollBy(0, vPosY)
oWB := ""
JEE_RetX()
I have a script for opening files/urls, I add in custom code when needed for some items,
but prefer to avoid that when possible.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
enter8
Posts: 102
Joined: 05 May 2016, 16:48

Re: list fragment identifiers on a webpage (hash that jumps to point)

12 Feb 2017, 16:16

Fair enough. I found this for getting all the IDs from a page

http://stackoverflow.com/a/7115033/6362846

Code: Select all

var allElements = document.getElementsByTagName("*");
var allIds = [];
for (var i = 0, n = allElements.length; i < n; ++i) {
  var el = allElements[i];
  if (el.id) { allIds.push(el.id); }
}
The poster also talks about adding names as well

else if (el.name) { allIds.push(el.name); }

hrefs would use another line using the same syntax. Once you have the list of hrefs, you can loop through and pull everything with a #.

At the end of the day, it might be 6 of one, half dozen of another, but this way feels a bit more concise than the StrReplace route
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list fragment identifiers on a webpage (hash that jumps to point)

12 Feb 2017, 17:20

Actually yes, looping through the elements, I hadn't really thought of that.
Sometimes I have the html already downloaded to a file so that's one reason for the string approach I took.
A key question is if my approach is fundamentally missing any fragment identifiers (or getting items that aren't FIs, although that's not a big problem).

Omg, I did not know it was possible to do oElt.href (albeit a 'try' is required), I kept parsing oElt.innerHTML to get the href.
Well this knowledge is going to transform some of my scripts!
(Plus oWB.document.title versus oWB.LocationName that I learnt recently.)

Code: Select all

;q:: ;internet explorer - get fragment identifiers from active tab
WinGet, hWnd, ID, ahk_class IEFrame
;oWB := JEE_WBGet("ahk_id " hWnd)
oWB := WBGet("ahk_id " hWnd)
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)

Loop, % oWB.document.all.length
{
oElt := oWB.document.all[A_Index-1]

if !(oElt.id = "")
vOutput .= (A_Index-1) "`tid`t" oElt.id "`r`n"

vName := ""
try vName := oElt.name
if !(vName = "")
vOutput .= (A_Index-1) "`tname`t" vName "`r`n"

vHref := ""
try vHref := oElt.href
if !(vHref = "") && InStr(vHref, "#")
vOutput .= (A_Index-1) "`thref`t" vHref "`r`n"
}

Clipboard := vOutput
MsgBox % "done"
Return
Well this has taken me down some interesting avenues.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Askeron52 and 124 guests