您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Provides jump buttons to the next lesson for leveling up (based on minirock / oltodosel autoScroller).
当前为
// ==UserScript== // @name Duolingo LevelJumper // @description Provides jump buttons to the next lesson for leveling up (based on minirock / oltodosel autoScroller). // @version 2.4 // @namespace esh // @match https://*.duolingo.com/* // ==/UserScript== // 2.4: take into concern if there are different levels in one row // TODO: fix bug clickable before jumpMark ready // 2.3: find a better solution to move to the first lesson of this level // 2.4: better jumpMark more satisfying // TODO: fix if jumpMark is the very first lesson new MutationObserver(checkJumpMark).observe(document.body, { childList: true, subtree: true }); window.onload = function () { //let lessons = document.querySelectorAll('img[src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"]'); //lessons[lessons.length-1].scrollIntoView(); //document.body.addEventListener('pageshow', addJumpMarks()); //addJumpMarks(); }; function checkJumpMark() { if (document.querySelectorAll('.GkDDe').length!=0) { if (document.querySelector('#jumpMark')===null) { if (document.querySelector('._3yqw1')!=null) addJumpMarks(); } } } function getAnchorElement(elem) { // whole lesson element let lesson = elem[elem.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode; let row; // if it is not the last lesson in the row, anchor has to be on the previous row // it it is the last lesson, anchor has to be in the same row to focus on the following row if(lesson.nextSibling) { row = lesson.parentNode.previousSibling; } else { row = lesson.parentNode; } return row; } function addJumpMarks() { // let notDone = document.querySelectorAll('img[src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"]'); // notDone[notDone.length-1].id = 'notDone'; let level = document.querySelectorAll('.GkDDe'); let level1 = new Array(); let level2 = new Array(); let level3 = new Array(); let level4 = new Array(); let level5 = new Array(); for (let i=0;i<level.length;i++) { switch(level[i].innerHTML) { case '1': level1.push(level[i]); // if there is no level 2 the first level 1 should be selected for becoming 2 //if(level2[0]===null) level2[0] = level[i]; break; case '2': level2.push(level[i]); //if(level3[0]===null) level3[0] = level[i]; break; case '3': level3.push(level[i]); //if(level4[0]===null) level4[0] = level[i]; break; case '4': level4.push(level[i]); //if(level5[0]===null) level5[0] = level[i]; break; case '5': //level5.push(level[i]); //if(level5[0]===null) level5[0] = level[i]; break; } } // have a lesson for the highest level, too if(level5.length == 0 && level4.length != 0) level5[0] = level4[0]; if(level4.length == 0 && level3.length != 0) level4[0] = level3[0]; if(level3.length == 0 && level2.length != 0) level3[0] = level2[0]; if(level2.length == 0 && level1.length != 0) level2[0] = level1[0]; // freaky selecting the previous row if(level1.length!=0) level1 = [getAnchorElement(level1)];//[level1[level1.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling]; if(level2.length!=0) level2 = [getAnchorElement(level2)];//[level2[level2.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling]; if(level3.length!=0) level3 = [getAnchorElement(level3)];//[level3[level3.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling]; if(level4.length!=0) level4 = [getAnchorElement(level4)];//[level4[level4.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling]; if(level5.length!=0) level5 = [getAnchorElement(level5)];//[level5[level5.length-1].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling]; let insertElement = document.querySelector('._3yqw1'); let jumpMark = document.createElement('div'); jumpMark.setAttribute('class','_3yqw1 np6Tv'); jumpMark.setAttribute('style','padding-top: 0.6rem; padding-right: 0.6rem; top: 148px;'); jumpMark.innerHTML = '<div id="jumpMark"/>'; if(level1.length!=0) { level1[level1.length-1].id = 'notDone'; jumpMark.innerHTML += /* `<a href="#notDone"><img src="//d35aaqx5ub95lt.cloudfront.net/images/fafe27c9c1efa486f49f87a3d691a66e.svg"/></a> */ `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#notDone"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/fafe27c9c1efa486f49f87a3d691a66e.svg"> </a> </div>`; } if(level2.length!=0) { level2[level2.length-1].id = 'level1'; jumpMark.innerHTML += `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#level1"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"> <div class="GkDDe" data-test="level-crown">1</div> </a> </div>`; } if(level3.length!=0) { level3[level3.length-1].id = 'level2'; jumpMark.innerHTML += `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#level2"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"> <div class="GkDDe" data-test="level-crown">2</div> </a> </div>`; } if(level4.length!=0) { level4[level4.length-1].id = 'level3'; jumpMark.innerHTML += `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#level3"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"> <div class="GkDDe" data-test="level-crown">3</div> </a> </div>`; } if(level5.length!=0) { level5[level5.length-1].id = 'level4'; jumpMark.innerHTML += `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#level4"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"> <div class="GkDDe" data-test="level-crown">4</div> </a> </div>`; } /* if(level5.length!=0) { level5[level5.length-1].id = 'level5'; jumpMark.innerHTML += `<div class="_2-dXY _1swBH" style="font-size: 14.84px;"> <a href="#level5"> <img alt="crown" class="_18sNN" src="//d35aaqx5ub95lt.cloudfront.net/images/b3ede3d53c932ee30d981064671c8032.svg"> <div class="GkDDe" data-test="level-crown">5</div> </a> </div>`; } */ insertElement.insertAdjacentElement('afterend',jumpMark); }