Простой пользовательский скрипт медленный и иногда не работает правильно - PullRequest
2 голосов
/ 05 ноября 2019

просто как примечание: я новичок в JS, и это мой первый скрипт.

Я пишу небольшой скрипт, который должен позволить мне открывать самое большое доступное изображение на странице flickr в несфокусированном newtab с помощью сочетания клавиш.

В настоящее время я сталкиваюсь с двумя проблемами:

  1. Скрипт загружается медленно, это означает, что если я изменю изображение в слайд-шоу с помощью клавиш со стрелками, мне придется подождать 1 или 2 секунды, прежде чем нажимать сочетание клавиш, чтобы открыть изображениев newtab. Если я не буду ждать, он откроет одно из предыдущих изображений из слайд-шоу в новой вкладке в зависимости от того, как быстро я их пропускал. (Это всегда должно открывать изображение, которое я сейчас просматриваю, в новой вкладке)

  2. Я использую журнал (mainurl), чтобы напечатать текущее содержимое «mainurl», которое является ссылкой на самый большой доступныйразмер текущего открытого изображения. но по какой-то причине он всегда дает мне URL одного из предыдущих изображений, в зависимости от того, как быстро я пропускаю слайд-шоу (даже если правильное изображение открывается в новой вкладке).

Вот URL-адрес учетной записи Flickr, если вы хотите проверить скрипт. (он должен быть запущен в фотопотоке [режим слайд-шоу]) URL-адрес фотопотока flickr

Это код, который я написал

// ==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);

Большое спасибо за любую помощь!

1 Ответ

2 голосов
/ 05 ноября 2019

Лучше перехватывать существующий быстрый запрос, сделанный сайтом к его серверному 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);
  }
});
...