我正在尝试JXA,并试图“移植”一个小的脚本,该脚本解析网页中的曲目名称。该脚本当前正在用作Keyboard Maestro宏,并在当前的Safari窗口中执行:
var trackBlock = document.getElementsByClassName("track tracklist_track_title");
var trackList = [];
for (var a of trackBlock) {
trackList.push(a.innerText);
}
trackList.join("\n");
问题是,如果doJavaScript
返回单个字符串(变量trackName1
包含曲目标题),我的移植尝试在JXA中效果很好:
var sfr = Application("Safari");
var trackName1 = sfr.doJavaScript('document.getElementsByClassName("track tracklist_track_title")[1].innerText', { in: sfr.windows[0].currentTab });
trackName1 // contains track name
但是,如果我更改代码,使得doJavaScript
返回一个数组(与初始代码一样),则该变量为null。您能解释一下吗:我做错了什么?
var sfr = Application("Safari");
var trackBlock = sfr.doJavaScript('document.getElementsByClassName("track tracklist_track_title")', { in: sfr.windows[0].currentTab });
trackBlock[0].innerText; // null
谢谢!
答案 0 :(得分:0)
我认为问题是这样的:
trackList.join("\n");
将代码放在JXA脚本中时,需要转义\n
:
trackList.join("\\n");
这是我的脚本,有效:
'use strict';
(function myMain() { // function will auto-run when script is executed
var app = Application.currentApplication();
app.includeStandardAdditions = true;
/*
HOW TO USE:
1. Open Safari to this URL:
https://forum.keyboardmaestro.com/
2. Run this script
*/
var jsStr = `
(function myMain2() {
//debugger;
//return 'Just testing';
var elemCol = document.querySelectorAll('div.category-text-title');
var elemArr = Array.from(elemCol);
var titleArr = elemArr.map(e => {return e.innerText});
return titleArr.join('\\n');
})();
`
var safariApp = Application("Safari");
var oTab = safariApp.windows[0].currentTab();
var pageURL = oTab.url();
var pageTitle = oTab.name();
var jsScriptResults = safariApp.doJavaScript(jsStr, {in: oTab})
console.log(jsScriptResults);
return jsScriptResults;
})();
//-->RETURNS:
/* Questions & Suggestions
Macro Library
Plug In Actions
Tips & Tutorials
Wiki
Announcements
Status Menu Icons
Forum Admin
*/
答案 1 :(得分:0)
这是该问题的更清晰示例。这是代码:
var sfr = Application("Safari");
var scr2run = 'document.getElementsByClassName("tracklist_track_title")';
var scr2run1 = 'document.getElementsByClassName("tracklist_track_title")[0]';
var scr2run2 = 'document.getElementsByClassName("tracklist_track_title")[0].innerText';
var trackName = sfr.doJavaScript(scr2run, { in: sfr.windows[0].currentTab });
var trackName1 = sfr.doJavaScript(scr2run1, { in: sfr.windows[0].currentTab });
var trackName2 = sfr.doJavaScript(scr2run2, { in: sfr.windows[0].currentTab });
以下是输出:
app = Application("Safari")
app.doJavaScript("document.getElementsByClassName(\"tracklist_track_title\")", {in:app.windows.at(0).currentTab})
--> null
app.doJavaScript("document.getElementsByClassName(\"tracklist_track_title\")[0]", {in:app.windows.at(0).currentTab})
--> null
app.doJavaScript("document.getElementsByClassName(\"tracklist_track_title\")[0].innerText", {in:app.windows.at(0).currentTab})
--> "From What Is Said To When It's Read"
为什么前两个调用doJavaScript
返回null
,而第三个返回期望值?
答案 2 :(得分:0)
回答第二个问题:
为什么前两个doJavaScript调用返回null,但是第三个 返回期望值?
var scr2run = 'document.getElementsByClassName("tracklist_track_title")';
var scr2run1 = 'document.getElementsByClassName("tracklist_track_title")[0]';
var scr2run2 = 'document.getElementsByClassName("tracklist_track_title")[0].innerText';
第三个JavaScript返回一个文本值,而前两个不返回。他们返回一个元素集合和一个元素。