Mic*_*orn 5 javascript google-chrome-extension reactjs
我正在尝试存储与一个人在特定选项卡/URL 上停留多长时间相关的信息。
使用 chrome API - https://developer.chrome.com/docs/extensions/reference/tabs/#type-Tab - 我可以跟踪选项卡的活动信息和突出显示的信息来执行此操作。
我目前正在使用我的扩展程序跟踪几个不同的数据点,如下所示,并且希望能够跟踪我在特定选项卡上停留的时间(具体来说,我在该选项卡上停留的时间)以及我使用的频率正在选项卡之间移动或创建新选项卡。
export type TAB_USAGE = {
tabId: number;
index?: number;
highlighted: boolean;
url: string;
startTime: string;
endTime?: string;
startFocus?: string;
endFocus?: string;
};
const getHostname = (url: string) => {
// use URL constructor and return hostname
return new URL(url).hostname;
};
export function enableTabListener(
socket: any,
currentPages: TAB_USAGE[],
visitedPages: Partial<TAB_USAGE>[]
) {
chrome.tabs.onUpdated.addListener(
});
setInterval(async () => {
console.log('sent tab data:', visitedPages);
}, 50000);
}
Run Code Online (Sandbox Code Playgroud)
我不是 100% 确定这里的最佳方法 - 我在想,检查一下旧数据是否处于活动状态,而新数据是否处于活动状态?
所以像
if (tabExisting.highlighted != tab.highlighted) {
//set endFocus?
}
Run Code Online (Sandbox Code Playgroud)
当执行这种方法时,它似乎不起作用,tabExisting 基本上很多时候都显示为 null。
或者使用另一个侦听器 API,以便当突出显示更改时,在某个地方每小时设置一个计数器?我很想看看有多少个选项卡,我在它们之间切换的频率,停留在其中一个选项卡上,实际上是每小时一次,试图找出一种好方法来做到这一点。
喜欢这里的一些反馈 - 我的大脑因为盯着这个文档而有点焦躁,并且希望得到一些指导。
你的做法有些正确。但是,您想要跟踪的活动类型我会将类型更改TAB_USAGE为:
export type FocusPeriod = {
startTime: string,
endTime: string
}
export type TAB_USAGE = {
tabId: number;
index?: number;
active?: boolean; //we're using active instead of highlighted
url?: string; //notice url is now optional
startTime: string;
endTime?: string;
focus?: Array<FocusPeriod>; //storing multiple focus events of a tab
};
Run Code Online (Sandbox Code Playgroud)
因为人们会在选项卡之间频繁切换,并且特定选项卡会有多个焦点时段。另请注意,url现在这是可选的,因为我们将监听回调中可能不可用的.onActivated事件。url
现在,为了跟踪选项卡之间的切换,我将使用.onActivated事件而不是.onHighlighted事件。active请注意选项卡和选项卡之间的区别highlighted。
活动选项卡始终突出显示。每个窗口只有一个活动选项卡。您可以在同一窗口中拥有多个突出显示的选项卡。但随后所有突出显示的选项卡均不处于活动状态。示例:选择一个选项卡,按住 Shift 键,然后选择另一个选项卡。最后单击的选项卡将成为该窗口的活动选项卡,但它们之间的所有选项卡(包括两个限制选项卡)现在都会突出显示。
.onActivated可以像这样添加事件监听器:
chrome.tabs.onActivated.addListener(
(activeInfo: object) => {
const previousActiveTabIndex = currentPages.findIndex((page) => page.active);
if(previousActiveTabIndex !== -1) {
currentPages[previousActiveTabIndex].active = false;
const focusLength = currentPages[previousActiveTabIndex].focus.length;
currentPages[previousActiveTabIndex].focus[focusLength - 1].endTime = new Date().toISOString();
}
const newActiveTabIndex = currentPages.findIndex((page) => page.tabId === activeInfo.tabId);
if(newActiveTabIndex > 0) {
currentPages[newActiveTabIndex].active = true;
currentPages[newActiveTabIndex].focus.push({
startTime: new Date().toISOString(),
endTime: ''
});
}
else {
currentPages = [
..currentPages,
{
tabId: activeInfo.tabId;
active: true;
startTime: new Date().toISOString();
focus: [{ startTime: new Date().toISOString(), endTime: '' }];
}
]
}
}
)
Run Code Online (Sandbox Code Playgroud)
如果您只对跟踪用户实际访问的选项卡感兴趣,则上述代码应该适合您。尽管在某些情况下,我们这样做Cmd+Click或Ctrl+Click在新选项卡中打开网址不会使新创建的选项卡处于活动状态。如果用户从未选择该选项卡,即使用户由于这种情况关闭该选项卡,您也将无法跟踪它:if (tabExists)在您的.onRemoved事件处理函数中。对于这些情况,我们应该添加.onCreated事件处理程序。
chrome.tabs.onCreated.addListener(
(tab: Tab) => {
const tabIndex = currentPages.findIndex((page) => page.tabId === tab.id);
if(tabIndex === -1) {
currentPages = [
..currentPages,
{
tabId: tab.id;
startTime: new Date().toISOString();
focus: [];
}
]
}
}
)
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。我们添加了上面提到的事件处理程序。.onActivated但在或事件被触发时.onCreated,并不能保证会有一个 url。因此,当选项卡的 url 更新时,.onUpdated会触发该事件。这就是为什么我们需要稍微更改一下代码。visitedPages我们仅在存在时添加一个条目tabExisting.url(不为空、未定义或“”);
最后,为了在安装扩展时从所有窗口获取所有选项卡(初始化),我们应该添加另一个事件处理程序,如下所示:
chrome.runtime.onInstalled.addListener((details) => {
if(['install', 'chrome_update'].includes(details.reason)) {
chrome.windows.getAll((windows: Window[]) => {
windows.forEach(window => {
chrome.tabs.getAllInWindow(window.id, (tabs: Tab[]) => {
tabs.forEach(tab => {
currentPages = [
..currentPages,
{
tabId: tab.id;
startTime: new Date().toISOString();
focus: [];
url: tab.url;
}
]
});
});
chrome.tabs.query({active: true, windowId: window.id}, (tab: Tab) => {
const tabIndex = currentPages.findIndex((page) => page.tabId === tab.id);
if(tabIndex > 0) {
currentPages[tabIndex - 1].active = true;
}
});
});
});
}
else if(details.reason == 'update') {
//do whatever necessary
}
});
Run Code Online (Sandbox Code Playgroud)
可以有许多正确的方法来实现这一目标。我想我会这样做。如果有什么不清楚的地方请评论。
| 归档时间: |
|
| 查看次数: |
686 次 |
| 最近记录: |