【问题标题】:Simple Userscript is slow and sometimes doesn't work correctly简单的用户脚本很慢,有时无法正常工作
【发布时间】:2019-11-05 13:26:09
【问题描述】:

顺便说一句,我是 JS 新手,这是我的第一个脚本。

我正在编写一个小脚本,它应该允许我使用键盘快捷键在未聚焦的新标签页中打开 flickr 页面中最大的可用图像。

我目前面临两个问题:

  1. 脚本加载速度很慢,这意味着如果我使用箭头键更改幻灯片中的图像,我需要等待 1 或 2 秒,然后才能按下键盘快捷键在新选项卡中打开图像。如果我不等待,它将根据我跳过它们的速度,在新标签中打开幻灯片中以前的图像之一。 (它应该始终在新标签中打开我当前正在查看的图像)

  2. 我使用 log(mainurl) 打印“mainurl”的当前内容,这是指向当前打开图像的最大可用尺寸的链接。但由于某种原因,它总是根据我跳过幻灯片的速度(即使在新标签页中打开了正确的图像),总是给我上一张图片的网址。

如果您想查看脚本,这里是指向 flickr 帐户的 URL。 (必须在照片流中运行[幻灯片模式])URL to flickr photostream

这是我写的代码

// ==UserScript==
// @name         Flickr Max NewTab
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Open Max sized flickr image in a new tab using key shorcut
// @author       Newbie
// @include     /flickr\.com/
// @grant       GM_openInTab
// @require     https://code.jquery.com/jquery-3.3.1.min.js
// ==/UserScript==

var page ='';
var sizes = [];
var links = [];
var length = 0;
var mainurl = '';

function geturl() { // function used to get the link of biggest image
    var action = function (sourceCode) {
        sizes = sourceCode.match(/modelExport: {.+?"sizes":{.+?}}/i); // extract the part of html that containes modelExport:
        links = sizes[0].match(/"displayUrl":"[^"]+"/ig); // extract the urls dictionary from the dictionary modelExport:
        length = links.length; //get the length of the dictionary "links"
        // extract the last(biggest) url from the links dictionary and put them in an array "links"
        mainurl = links[links.length-1].replace(/"displayUrl":"([^"]+)"/i, "$1").replace(/\\/g, "").replace(/(_[a-z])\.([a-z]{3,4})/i, '$1' + "." + '$2');
    }
    $.get(document.URL, action);
}

function log(x) {
    console.log(x);
}
// function used to get to run the url grabber everytime you change the image in slideshow using arrowkeys
function navigation (e) {
    if (e.keyCode == 37 || e.keyCode == 39) {
        geturl();
        log(mainurl);// log to check the current contents of mainurl
    }
}
// function used to open image in a newtab when "alt + Q" are pressed
function newtab (e) {
    if (e.altKey && e.keyCode == 81) {
        GM_openInTab(mainurl);
    }
}

geturl(); //run the function

document.addEventListener('keyup', navigation);
document.addEventListener('keydown', newtab);

非常感谢您的帮助!

【问题讨论】:

  • 我认为这个问题可能更适合 CodeReview.SE - 该网站专门用于审查初学者的简短代码示例,并且您的代码足够短,可以 100% 了解主题。
  • 谢谢@TomášZato 会去看看
  • 请注意,您的帖子根本不是题外话,只是对未来的建议。

标签: javascript jquery tampermonkey userscripts


【解决方案1】:

最好拦截站点向其服务器 API 发出的现有快速请求(您可以在 devtools 网络面板中检查它),而不是发出额外的慢速请求。

为此,我们将使用unsafeWindow 和挂钩XMLHttpRequest 原型。还要在document-start 处运行脚本,以便在页面发出请求之前附加拦截器。

// ==UserScript==
// @name        Flickr Max NewTab
// @match       https://www.flickr.com/*
// @grant       GM_openInTab
// @run-at      document-start
// ==/UserScript==

const xhrOpen = unsafeWindow.XMLHttpRequest.prototype.open;
unsafeWindow.XMLHttpRequest.prototype.open = function (method, url) {
  if (/method=[^&]*?(getPhotos|getInfo)/.test(url)) {
    this.addEventListener('load', onXhrLoad, {once: true});
  }
  return xhrOpen.apply(this, arguments);
};

const imgUrls = {};

function onXhrLoad() {
  const json = JSON.parse(this.response);
  const photos = json.photos ? json.photos.photo : [json.photo];
  for (const {id, url_o} of photos) {
    imgUrls[id] = url_o;
  }
}

document.addEventListener('keydown', e => {
  if (e.altKey && e.code === 'KeyQ' && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
    const id = location.pathname.split('/')[3];
    const url = imgUrls[id];
    if (url) GM_openInTab(url, true);
  }
});

【讨论】:

  • 想用脚本文本内容发布答案,但后来通过ajax实现了页面更新并得出了相同的结论。但是,您是否在 JSON 中找到了最大分辨率?我在任何请求中都找不到它。
  • @wOxxOm 代码在我给你的网址上运行良好,即使我不理解大部分代码,也必须仔细阅读。但是代码在不同的页面上不起作用,因为最大的图像并不总是以“_o”结尾,它可能有不同的后期修复“_6k”、“_5k”、“_l”..etc
  • @Vagabond 诀窍在于,每当 Flickr 应用程序尝试获取一些照片信息时,wOxxOm 的脚本也会获取该信息,而无需额外下载数据。您可以在“网络”面板下的开发工具中检查 Fickr 下载的数据(即那些具有 JSON 格式的数据)。
  • @TomášZato,我在网络中看不到任何 JSON,但我看到 XHR,虽然这是我更改图像时始终发送的那个
  • 您需要在打开 devtools 的情况下重新加载页面,一次会批量请求 20 张图片,并在 URL 中添加“per_page”字样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 2014-12-07
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多