Kevin
Kevin

Reputation: 1106

AppleScript: loop in javascript

How can I loop this code to repeat and set a different variable for every occurrence of the class 'auto-date-time' ?

tell application "Safari"
        set myValue to do JavaScript "document.getElementsByClassName('auto-date-time')[0].innerHTML;" in current tab of window 1
    end tell

e.g : myValue1 document.getElementsByClassName('auto-date-time')[1] MyValue2 document.getElementsByClassName('auto-date-time')[2] MyValue3 document.getElementsByClassName('auto-date-time')[3

I know this work fine

tell application "Safari"
    set myValue to do JavaScript "var outPut=[]; var arr=document.getElementsByClassName('sortable fraudScoringTransactionCCSummary');for (var i in arr) {outPut.push(arr[i].innerHTML)};outPut;" in current tab of window 1
end tell

But I'm trying to do it different, can that be done?

I tried this which is working but obviously seems pretty bad + that wouldn't fix the issue of the variable

     repeat with counter from 1 to 10
    tell application "Safari"
        set myValue to do JavaScript "document.getElementsByClassName('auto-date-time')[" & counter & "].innerHTML;" in current tab of window 1
    end tell

    if myValue = missing value then
        exit repeat
    end if
end repeat

Upvotes: 1

Views: 415

Answers (2)

CJK
CJK

Reputation: 6102

I would say that the cleanest and most efficient way to obtain an AppleScript list of innerHTML property values for a collection of HTML elements is this:

tell application "Safari" to tell ¬
    the front document to set ¬
    myList to do JavaScript ¬
    "Array.from(
        document.getElementsByClassName('auto-date-time'),
        x => x.innerHTML
    );"

EDIT (2019-04-02):

Addressing a comment below where you reported no return value, and in lieu of you providing the console return value for the JavaScript above, here's an alternative method that you can try:

tell application "Safari" to tell document 1 to set myList to ¬
    do JavaScript "[...document.getElementsByClassName('auto-date-time')]
                   .map( x => x.innerText );"

The two differences are the use of property innerText instead of innerHTML (which you can also apply to the first JavaScript), and method used to construct the array (although, assuming you're running the latest version of Safari, shouldn't make a difference).


A note on error-catching

Try to get out of the habit of using try blocks in the manner that you tend to do. They shouldn't be used if its purpose is to prevent a script from terminating through an error that you weren't expecting to occur or don't understand why the error occurs. They are used to catch errors you predict will arise in specific situations, knowing why it happens, and allowing you to use it to your advantage. Otherwise, all you are doing is stopping an unexpected error from alerting you to a flaw in your script, and where/when it's arising.

Upvotes: 1

Kevin
Kevin

Reputation: 1106

Find it :

I need to use repeat / plus list, although pretty sure that's still not the right way to do it.

set myList to {}

try
    repeat with counter from 1 to 1000
        tell application "Safari"
            set myValue to do JavaScript "document.getElementsByClassName('auto-date-time')[" & counter & "].innerHTML;" in current tab of window 1
        end tell

        if myValue = missing value then
            exit repeat

        else if myValue is not equal to "" then
            set the myList to the myList & myValue
        end if

    end repeat

on error
    --
end try


return myList

Upvotes: 0

Related Questions