├── src ├── legacy │ ├── vk-console-new-tab.js │ ├── vk-console-download-txt.js │ ├── vk-console.js │ └── vk.user.js └── vk.user.js └── README.md /src/legacy/vk-console-new-tab.js: -------------------------------------------------------------------------------- 1 | var delay = 50; 2 | var scrollDirection = 200; 3 | 4 | function pageScroll() { 5 | setTimeout(function () { 6 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 7 | setTimeout(function () { 8 | let length = document.getElementsByClassName("audio_row__performers").length; 9 | if (length > 0) { 10 | var artist = document.getElementsByClassName("audio_row__performers"); 11 | var song = document.getElementsByClassName("audio_row__title_inner"); 12 | list = []; 13 | 14 | for (var i = 0; i < artist.length; i++) { 15 | list[i] = artist[i].firstElementChild.innerText + ' - ' + song[i].innerText; 16 | } 17 | 18 | window.open().document.write(list.join('
')); 19 | } else { alert("На этой странице не найдено песен") } 20 | }, 500); 21 | 22 | return false; 23 | } 24 | 25 | window.scrollBy(0, scrollDirection); 26 | scrolldelay = setTimeout(pageScroll(), 1); 27 | }, delay) 28 | } 29 | 30 | pageScroll(); -------------------------------------------------------------------------------- /src/legacy/vk-console-download-txt.js: -------------------------------------------------------------------------------- 1 | var delay = 50; 2 | var scrollDirection = 200; 3 | 4 | function download(filename, list) { 5 | var downloadBtn = document.createElement('a'); 6 | downloadBtn.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(list.join("\n"))); 7 | downloadBtn.setAttribute('download', filename); 8 | downloadBtn.style.display = 'none'; 9 | document.body.appendChild(downloadBtn); 10 | downloadBtn.click(); 11 | document.body.removeChild(downloadBtn); 12 | } 13 | 14 | function pageScroll() { 15 | setTimeout(function () { 16 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 17 | setTimeout(function () { 18 | let length = document.getElementsByClassName("audio_row__performers").length; 19 | if (length > 0) { 20 | var artist = document.getElementsByClassName("audio_row__performers"); 21 | var song = document.getElementsByClassName("audio_row__title_inner"); 22 | list = []; 23 | 24 | for (var i = 0; i < artist.length; i++) { 25 | list[i] = artist[i].firstElementChild.innerText + ' - ' + song[i].innerText; 26 | } 27 | 28 | download('VK Music ' + Date() + '.txt', list); 29 | } else { alert("На этой странице не найдено песен") } 30 | }, 500); 31 | 32 | return false; 33 | } 34 | 35 | window.scrollBy(0, scrollDirection); 36 | scrolldelay = setTimeout(pageScroll(), 1); 37 | }, delay) 38 | } 39 | 40 | pageScroll(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Export VK music 2 | ## Usage 3 | 1. Install one of the Userscript browser extensions such as Greasemonkey, Violentmonkey, Tampermonkey, etc. 4 | 2. Install [this userscript](https://github.com/anddea/export-vk-music/raw/main/src/vk.user.js). 5 | 3. Open any music section: your music, your playlsts, user playlists, autogenerated playlists, etc. 6 | 4. Double tap Alt key.

7 | 8 | ## Инструкция 9 | > [!NOTE] 10 | > Данное ПО автоматически прокручивает страницу и собирает все треки на странице. После чего показывает кнопки скопировать все песни, скачать текстовый файл и открыть список треков в новой вкладке. 11 | 12 | > [!WARNING] 13 | > - Если страница не прокрутилась до конца и/или не показала кнопки для экспорта, то повторите запуск (может даже несколько раз), не перезагружая страницу. 14 | > - Если на странице несколько секций с музыкой, то скрипт может собрать не только те треки, которые нужны. 15 | > - Плейлисты, альбомы нужно открывать в новой вкладке, а не поверх основной страницы, т е. не модальное окно. 16 | 17 | 1. **Установитe одно из расширений пользовательских скриптов в браузер**: Tampermonkey, Greasemonkey, Violentmonkey и др. 18 | 2. **Установитe [скрипт](https://github.com/anddea/export-vk-music/raw/main/src/vk.user.js)**. 19 | 3. **Откройте список треков**, которые хотите перенести 20 | - своя музыка, 21 | - музыка друзей, 22 | - альбомы исполнителей, 23 | - музыка из плейлистов, 24 | - плейлисты, которые сгенерированы самим ВК, например Daily Playlist, Weekly Playlist и др. 25 | 4. Нажать дважды клавишу `Alt` непрерывно (в течение 200 мс). 26 | 27 |
28 | Дополнительная информация 29 | 30 | Для изменения клавиши, замените значение KEY в скрипте на любую удобную клавишу 31 | ```js 32 | const KEY = "Alt"; // control, meta, shift, a, b, c 33 | ``` 34 | Чтобы импортировать в другие сервисы, воспользуйтесь любыми сервисами переноса музыки: [TuneMyMusic](https://www.tunemymusic.com/ru/), [Soundiiz](https://soundiiz.com/ru/) и др. 35 | 36 | Предыдущие версии скрипта находятся в папке [legacy](https://github.com/anddea/export-vk-music/tree/main/src/legacy). 37 |
38 | -------------------------------------------------------------------------------- /src/legacy/vk-console.js: -------------------------------------------------------------------------------- 1 | var delay = 50; 2 | var scrollDirection = 200; 3 | 4 | function fallbackCopyTextToClipboard(text) { 5 | var textArea = document.createElement("textarea"); 6 | textArea.value = text; 7 | 8 | textArea.style.display = "none"; 9 | 10 | document.body.appendChild(textArea); 11 | textArea.focus(); 12 | textArea.select(); 13 | 14 | try { 15 | var successful = document.execCommand('copy'); 16 | var msg = successful ? 'успешно' : 'с ошибкой'; 17 | console.log('F: Скопировано ' + msg); 18 | copyBtn.innerText = "Скопировано"; 19 | } catch (err) { 20 | console.error('F: Ошибка: ', err); 21 | } 22 | 23 | document.body.removeChild(textArea); 24 | } 25 | 26 | function copyTextToClipboard(text) { 27 | if (!navigator.clipboard) { 28 | fallbackCopyTextToClipboard(text); 29 | return; 30 | } 31 | navigator.clipboard.writeText(text).then(function () { 32 | copyBtn.innerText = "Скопировано"; 33 | console.log('A: Скопировано'); 34 | }, function (err) { 35 | console.error('A: Ошибка: ', err); 36 | }); 37 | } 38 | 39 | function scrapeTracks() { 40 | var artist = document.getElementsByClassName("audio_row__performers"); 41 | var song = document.getElementsByClassName("audio_row__title_inner"); 42 | list = []; 43 | 44 | for (var i = 0; i < artist.length; i++) { 45 | list[i] = artist[i].firstElementChild.innerText + ' - ' + song[i].innerText; 46 | } 47 | 48 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 49 | createButtons(artist); 50 | } 51 | } 52 | 53 | function createButtons(artist) { 54 | if (document.getElementsByClassName("AudioPlaylistSnippet__body").length > 0) { 55 | performersParent = [...document.querySelectorAll(".audio_row__performers")].at(-1).parentNode.parentNode.parentNode.parentNode.parentNode; 56 | } else { 57 | performersParent = [...document.querySelectorAll(".audio_row__performers")].at(-1).parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode; 58 | } 59 | 60 | if (document.getElementById("info")) { 61 | document.getElementById("info").remove(); 62 | document.getElementById("copyBtn").remove(); 63 | document.getElementById("downloadBtn").remove(); 64 | document.getElementById("openBtn").remove(); 65 | } 66 | 67 | var info = document.createElement('div'); 68 | info.id = "info"; 69 | info.style.width = "70%"; 70 | info.innerHTML = "Количество треков на странице: " + artist.length + "
Если на странице есть несколько секций, то в список могут попасть не только те треки, которые нужны."; 71 | info.style.margin = "1rem 0 .2rem"; 72 | performersParent.append(info); 73 | 74 | // Copy 75 | var copyBtn = document.createElement('a'); 76 | copyBtn.id = "copyBtn"; 77 | copyBtn.innerText = "Скопировать"; 78 | copyBtn.style.margin = ".2rem 0"; 79 | copyBtn.style.marginRight = "1rem"; 80 | copyBtn.style.display = "inline-block"; 81 | performersParent.append(copyBtn); 82 | 83 | copyBtn.addEventListener('click', function (event) { 84 | copyTextToClipboard(list.join('\n')); 85 | 86 | setTimeout(function () { 87 | copyBtn.innerText = "Скопировать"; 88 | }, 2000); 89 | }); 90 | 91 | // Download 92 | var downloadBtn = document.createElement('a'); 93 | downloadBtn.id = "downloadBtn"; 94 | downloadBtn.innerText = "Скачать "; 95 | downloadBtn.style.margin = ".2rem 0"; 96 | downloadBtn.style.marginRight = "1rem"; 97 | downloadBtn.style.display = "inline-block"; 98 | downloadBtn.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(list.join('\n'))); 99 | downloadBtn.setAttribute('download', 'VK Music ' + Date() + '.txt'); 100 | performersParent.append(downloadBtn); 101 | 102 | // Open in new tab 103 | var openBtn = document.createElement('a'); 104 | openBtn.id = "openBtn"; 105 | openBtn.innerText = "Открыть"; 106 | openBtn.style.margin = ".2rem 0"; 107 | openBtn.style.marginRight = "1rem"; 108 | openBtn.style.display = "inline-block"; 109 | performersParent.append(openBtn); 110 | 111 | openBtn.addEventListener('click', function (event) { 112 | window.open().document.write(list.join('
')) 113 | }); 114 | 115 | document.getElementById("copyBtn").scrollIntoView({ block: "center", behavior: "smooth" }); 116 | 117 | document.getElementById("info").onmouseover = function () { 118 | showTooltip(this, { text: 'Если на странице есть несколько секций, то в список могут попасть не только те треки, которые нужны', black: 1, noZIndex: true, needLeft: false }); 119 | }; 120 | 121 | document.getElementById("copyBtn").onmouseover = function () { 122 | showTooltip(this, { text: 'Скопировать список треков в буфер обмена', black: 1, noZIndex: true, needLeft: false }); 123 | }; 124 | 125 | document.getElementById("downloadBtn").onmouseover = function () { 126 | showTooltip(this, { text: 'Скачать список треков в текстовом файле', black: 1, noZIndex: true, needLeft: false }); 127 | }; 128 | 129 | document.getElementById("openBtn").onmouseover = function () { 130 | showTooltip(this, { text: 'Открыть список треков в новой вкладке', black: 1, noZIndex: true, needLeft: false }); 131 | }; 132 | } 133 | 134 | function pageScroll() { 135 | setTimeout(function () { 136 | if (document.getElementsByClassName("ui_tab")) { 137 | for (var i = 0; i < document.getElementsByClassName("ui_tab").length; i++) { 138 | document.getElementsByClassName("ui_tab")[i].setAttribute("target", "_blank"); 139 | } 140 | } 141 | 142 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 143 | setTimeout(function () { 144 | let length = document.getElementsByClassName("audio_row__performers").length; 145 | if (length > 0) { 146 | scrapeTracks(); 147 | } else { alert("На этой странице не найдено песен") } 148 | }, 500); 149 | 150 | return false; 151 | } 152 | 153 | window.scrollBy(0, scrollDirection); 154 | scrolldelay = setTimeout(pageScroll(), 1); 155 | }, delay) 156 | } 157 | 158 | pageScroll(); -------------------------------------------------------------------------------- /src/vk.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Export VK Music 3 | // @version 3.2 4 | // @description Userscript for exporting VK music to text 5 | // @author Aaron Veil 6 | // @match *://vk.com/* 7 | // @icon https://vk.com/favicon.ico 8 | // @homepageURL https://github.com/anddea/export-vk-music 9 | // @supportURL https://github.com/anddea/export-vk-music/issues 10 | // @updateURL https://raw.githubusercontent.com/anddea/export-vk-music/main/src/vk.user.js 11 | // @downloadURL https://raw.githubusercontent.com/anddea/export-vk-music/main/src/vk.user.js 12 | // @grant none 13 | // ==/UserScript== 14 | 15 | (() => { 16 | 'use strict'; 17 | 18 | // VARIABLES 19 | // Constants 20 | const KEY = 'Alt'; 21 | const DELAY = 200; 22 | 23 | // State variables 24 | let last, list = []; 25 | 26 | const tooltips = { 27 | copyBtn: 'Скопировать список треков в буфер обмена', 28 | downloadBtn: 'Скачать список треков в текстовом файле', 29 | openBtn: 'Открыть список треков в новой вкладке', 30 | }; 31 | 32 | // FUNCTIONS 33 | const fallbackCopyTextToClipboard = text => { 34 | const textArea = document.body.appendChild(document.createElement('textarea')); 35 | textArea.value = text; 36 | textArea.style = 'display:none'; 37 | textArea.select(); 38 | 39 | try { 40 | document.execCommand('copy') && (copyBtn.innerText = 'Скопировано'); 41 | } catch (err) { 42 | console.error('F: Ошибка: ', err); 43 | } finally { 44 | document.body.removeChild(textArea); 45 | } 46 | }; 47 | 48 | const copyTextToClipboard = text => 49 | navigator.clipboard 50 | ? navigator.clipboard 51 | .writeText(text) 52 | .then(() => (copyBtn.innerText = 'Скопировано')) 53 | .catch((err) => console.error('A: Ошибка: ', err)) 54 | : fallbackCopyTextToClipboard(text); 55 | 56 | const createButton = (id, text, onClick) => { 57 | const button = document.createElement('a'); 58 | button.id = id; 59 | button.innerText = text; 60 | button.style.cssText = 'margin:.2rem 0;margin-right:1rem;display:inline-block'; 61 | button.addEventListener('click', onClick); 62 | // performersParent.appendChild(button); 63 | return button; 64 | }; 65 | 66 | const getLastParent = (element, levels) => levels >= 0 ? Array.from({ length: levels + 1 }).reduce((parent, _) => parent?.parentNode, element) : null; 67 | 68 | const appendButtons = artist => { 69 | const performersParent = document.getElementsByClassName('AudioPlaylistSnippet__body').length > 0 70 | ? getLastParent([...document.querySelectorAll('.audio_row__performers')].at(-1), 4) 71 | : getLastParent([...document.querySelectorAll('.audio_row__performers')].at(-1), 8); 72 | 73 | ['info', 'copyBtn', 'downloadBtn', 'openBtn'].forEach(id => document.getElementById(id)?.remove()); 74 | 75 | const info = document.createElement('div'); 76 | info.id = 'info'; 77 | info.style.cssText = 'width:70%;margin:1rem 0 .2rem'; 78 | info.innerHTML = `Количество треков на странице: ${artist.length}
Если на странице есть несколько секций, то в список могут попасть не только те треки, которые нужны.`; 79 | 80 | const copyBtn = createButton('copyBtn', 'Скопировать', () => { 81 | copyTextToClipboard(list.join('\n')); 82 | setTimeout(() => copyBtn.innerText = 'Скопировать', 2000); 83 | }); 84 | 85 | const downloadBtn = createButton('downloadBtn', 'Скачать', () => { 86 | downloadBtn.href = `data:text/plain;charset=utf-8,${encodeURIComponent(list.join('\n'))}`; 87 | downloadBtn.download = `VK Music ${new Date()}.txt`; 88 | }); 89 | 90 | const openBtn = createButton('openBtn', 'Открыть', () => window.open().document.write(list.join('
'))); 91 | 92 | performersParent.appendChild(info); 93 | performersParent.appendChild(copyBtn); 94 | performersParent.appendChild(downloadBtn); 95 | performersParent.appendChild(openBtn); 96 | 97 | document.getElementById('info').scrollIntoView({ block: 'center', behavior: 'smooth' }); 98 | 99 | ['copyBtn', 'downloadBtn', 'openBtn'].forEach(id => document.getElementById(id)?.addEventListener('mouseover', () => 100 | showTooltip(document.getElementById(id), { text: tooltips[id], black: 1, noZIndex: true, needLeft: false }) 101 | )); 102 | }; 103 | 104 | const scrapeTracks = () => { 105 | const artist = document.getElementsByClassName('audio_row__performers'); 106 | const song = document.getElementsByClassName('audio_row__title_inner'); 107 | list = Array.from(artist).map( 108 | (el, i) => `${el.firstElementChild.innerText} - ${song[i].innerText}` 109 | ); 110 | 111 | appendButtons(artist) 112 | }; 113 | 114 | let scrape = false; 115 | const pageScroll = () => setTimeout(() => { 116 | Array.from(document.getElementsByClassName('ui_tab')).forEach(el => el.setAttribute('target', '_blank')); 117 | 118 | const autoListLoader = document.querySelector('.CatalogBlock__autoListLoader'); 119 | const hasAutoListLoader = !!autoListLoader; 120 | 121 | window.scrollTo(0, document.body.scrollHeight); 122 | 123 | if (!scrape) { 124 | if (hasAutoListLoader && autoListLoader.style.display !== 'none') { 125 | pageScroll(); 126 | 127 | setTimeout(() => { 128 | if (hasAutoListLoader && autoListLoader.style.display === 'none') { 129 | scrape = true; 130 | scrapeTracksIfAny(); 131 | } 132 | }, 500); 133 | } else if (!hasAutoListLoader && (window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 134 | scrape = true; 135 | scrapeTracksIfAny(); 136 | } else { 137 | pageScroll(); 138 | } 139 | } 140 | }, DELAY); 141 | 142 | 143 | const scrapeTracksIfAny = () => { 144 | const hasTracks = document.getElementsByClassName('audio_row__performers').length > 0; 145 | hasTracks ? scrapeTracks() : alert('На этой странице не найдено песен'); 146 | }; 147 | 148 | document.addEventListener('keydown', (e) => { 149 | if (e.key.toLowerCase() === KEY.toLowerCase()) { 150 | last = e.key === last ? confirm('Данная страница прокрутится в самый низ и создаст кнопки для экспорта треков. \n\nЕсли страница не прокрутилась до конца, запустите ещё раз. \n\nПродолжить?') && pageScroll() : e.key; 151 | setTimeout(() => (last = 'none'), 200); 152 | } 153 | }); 154 | })(); -------------------------------------------------------------------------------- /src/legacy/vk.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Export VK Music 3 | // @match https://vk.com/* 4 | // @grant none 5 | // @version 2022.08.26 (2) 6 | // @author - 7 | // @description Userscript for exporting VK music to text 8 | // ==/UserScript== 9 | 10 | const key = "alt" // control, meta, shift, a, b, c 11 | var last; 12 | 13 | var delay = 50; 14 | var scrollDirection = 200; 15 | 16 | document.addEventListener('keydown', function (e) { 17 | if (e.key.toLowerCase() == key) { 18 | if (e.key == last) { 19 | if (confirm("Данная страница прокрутиться в самый низ и создаст кнопки для эксопрта треков.\n\nПродолжить?") == true) { 20 | pageScroll(); 21 | } 22 | last = "none"; 23 | } else { 24 | last = e.key; 25 | setTimeout(function () { last = "none"; }, 200); 26 | } 27 | } 28 | }); 29 | 30 | function fallbackCopyTextToClipboard(text) { 31 | var textArea = document.createElement("textarea"); 32 | textArea.value = text; 33 | 34 | textArea.style.display = "none"; 35 | 36 | document.body.appendChild(textArea); 37 | textArea.focus(); 38 | textArea.select(); 39 | 40 | try { 41 | var successful = document.execCommand('copy'); 42 | var msg = successful ? 'успешно' : 'с ошибкой'; 43 | console.log('F: Скопировано ' + msg); 44 | copyBtn.innerText = "Скопировано"; 45 | } catch (err) { 46 | console.error('F: Ошибка: ', err); 47 | } 48 | 49 | document.body.removeChild(textArea); 50 | } 51 | 52 | function copyTextToClipboard(text) { 53 | if (!navigator.clipboard) { 54 | fallbackCopyTextToClipboard(text); 55 | return; 56 | } 57 | navigator.clipboard.writeText(text).then(function () { 58 | copyBtn.innerText = "Скопировано"; 59 | console.log('A: Скопировано'); 60 | }, function (err) { 61 | console.error('A: Ошибка: ', err); 62 | }); 63 | } 64 | 65 | function scrapeTracks() { 66 | var artist = document.getElementsByClassName("audio_row__performers"); 67 | var song = document.getElementsByClassName("audio_row__title_inner"); 68 | list = []; 69 | 70 | for (var i = 0; i < artist.length; i++) { 71 | list[i] = artist[i].firstElementChild.innerText + ' - ' + song[i].innerText; 72 | } 73 | 74 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 75 | createButtons(artist); 76 | } 77 | } 78 | 79 | function createButtons(artist) { 80 | if (document.getElementsByClassName("AudioPlaylistSnippet__body").length > 0) { 81 | performersParent = [...document.querySelectorAll(".audio_row__performers")].at(-1).parentNode.parentNode.parentNode.parentNode.parentNode; 82 | } else { 83 | performersParent = [...document.querySelectorAll(".audio_row__performers")].at(-1).parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode; 84 | } 85 | 86 | if (document.getElementById("info")) { 87 | document.getElementById("info").remove(); 88 | document.getElementById("copyBtn").remove(); 89 | document.getElementById("downloadBtn").remove(); 90 | document.getElementById("openBtn").remove(); 91 | } 92 | 93 | var info = document.createElement('div'); 94 | info.id = "info"; 95 | info.style.width = "70%"; 96 | info.innerHTML = "Количество треков на странице: " + artist.length + "
Если на странице есть несколько секций, то в список могут попасть не только те треки, которые нужны."; 97 | info.style.margin = "1rem 0 .2rem"; 98 | performersParent.append(info); 99 | 100 | // Copy 101 | var copyBtn = document.createElement('a'); 102 | copyBtn.id = "copyBtn"; 103 | copyBtn.innerText = "Скопировать"; 104 | copyBtn.style.margin = ".2rem 0"; 105 | copyBtn.style.marginRight = "1rem"; 106 | copyBtn.style.display = "inline-block"; 107 | performersParent.append(copyBtn); 108 | 109 | copyBtn.addEventListener('click', function (event) { 110 | copyTextToClipboard(list.join('\n')); 111 | 112 | setTimeout(function () { 113 | copyBtn.innerText = "Скопировать"; 114 | }, 2000); 115 | }); 116 | 117 | // Download 118 | var downloadBtn = document.createElement('a'); 119 | downloadBtn.id = "downloadBtn"; 120 | downloadBtn.innerText = "Скачать "; 121 | downloadBtn.style.margin = ".2rem 0"; 122 | downloadBtn.style.marginRight = "1rem"; 123 | downloadBtn.style.display = "inline-block"; 124 | downloadBtn.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(list.join('\n'))); 125 | downloadBtn.setAttribute('download', 'VK Music ' + Date() + '.txt'); 126 | performersParent.append(downloadBtn); 127 | 128 | // Open in new tab 129 | var openBtn = document.createElement('a'); 130 | openBtn.id = "openBtn"; 131 | openBtn.innerText = "Открыть"; 132 | openBtn.style.margin = ".2rem 0"; 133 | openBtn.style.marginRight = "1rem"; 134 | openBtn.style.display = "inline-block"; 135 | performersParent.append(openBtn); 136 | 137 | openBtn.addEventListener('click', function (event) { 138 | window.open().document.write(list.join('
')) 139 | }); 140 | 141 | document.getElementById("copyBtn").scrollIntoView({ block: "center", behavior: "smooth" }); 142 | 143 | document.getElementById("info").onmouseover = function () { 144 | showTooltip(this, { text: 'Если на странице есть несколько секций, то в список могут попасть не только те треки, которые нужны', black: 1, noZIndex: true, needLeft: false }); 145 | }; 146 | 147 | document.getElementById("copyBtn").onmouseover = function () { 148 | showTooltip(this, { text: 'Скопировать список треков в буфер обмена', black: 1, noZIndex: true, needLeft: false }); 149 | }; 150 | 151 | document.getElementById("downloadBtn").onmouseover = function () { 152 | showTooltip(this, { text: 'Скачать список треков в текстовом файле', black: 1, noZIndex: true, needLeft: false }); 153 | }; 154 | 155 | document.getElementById("openBtn").onmouseover = function () { 156 | showTooltip(this, { text: 'Открыть список треков в новой вкладке', black: 1, noZIndex: true, needLeft: false }); 157 | }; 158 | } 159 | 160 | function pageScroll() { 161 | setTimeout(function () { 162 | if (document.getElementsByClassName("ui_tab")) { 163 | for (var i = 0; i < document.getElementsByClassName("ui_tab").length; i++) { 164 | document.getElementsByClassName("ui_tab")[i].setAttribute("target", "_blank"); 165 | } 166 | } 167 | 168 | if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 169 | setTimeout(function () { 170 | let length = document.getElementsByClassName("audio_row__performers").length; 171 | if (length > 0) { 172 | scrapeTracks(); 173 | } else { alert("На этой странице не найдено песен") } 174 | }, 500); 175 | 176 | return false; 177 | } 178 | 179 | window.scrollBy(0, scrollDirection); 180 | scrolldelay = setTimeout(pageScroll(), 1); 181 | }, delay) 182 | } 183 | --------------------------------------------------------------------------------