您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
아프리카TV의 사이드바 UI를 변경합니다.
当前为
// ==UserScript== // @name 아프리카TV - 사이드바 UI 변경 // @name:ko 아프리카TV - 사이드바 UI 변경 // @namespace https://www.afreecatv.com/ // @version 2024-01-25 // @description 아프리카TV의 사이드바 UI를 변경합니다. // @description:ko 아프리카TV의 사이드바 UI를 변경합니다. // @author You // @match https://afreecatv.com/ // @match https://afreecatv.com/?hash=* // @match https://www.afreecatv.com/ // @match https://www.afreecatv.com/?hash=* // @icon https://www.google.com/s2/favicons?sz=64&domain=afreecatv.com // @grant GM_addStyle // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function() { 'use strict'; const css_Darkmode = ` .users-section.myplus > .user.show-more { display: none; } .users-section.follow > .user.show-more { display: none; } #toggleButton, #toggleButton2 { padding:12px; color:#e5e5e5; } .left_navbar { display: flex; align-items: center; justify-content: flex-end; position: absolute; flex-direction: row-reverse; top: 0px; left: 160px; } .left_nav_button { font-family: Arial, Helvetica, sans-serif; position: relative; width: 70px; height: 70px; padding: 0; border: 0; border-radius: 50%; cursor: pointer; z-index: 3001; transition: all .2s; color: #e5e5e5; font-size: 15px; font-weight: 600; } .left_nav_button.active { color: #019BFE; } #sidebar { width: 240px; grid-area: sidebar; background-color: #1F1F23; color:white; margin-right:10px; padding-bottom:150px; } #sidebar .top-section { display: flex; align-items: center; justify-content: space-around; margin: 10px 0px; } #sidebar .top-section>span { text-transform: uppercase; font-weight: 550; font-size: 14px; margin-top: 6px; margin-bottom: 4px; } #sidebar .top-section>span>a { color:#FFFFFF; } #sidebar .twitch-message-section { margin: 0px 10px; margin-top: 10px; padding: 0 25px; background-color: #1F1F23; } #sidebar .twitch-message-section .title { margin: 0px; font-size: 1.5rem; font-weight: 500; } #sidebar .twitch-message-section .title>span { color: var(--primary-color); } #sidebar .twitch-message-section .description { margin: 8px 0px; line-height: 1.3rem; font-size: 0.9rem; color: #A1A1A1; } #sidebar .twitch-message-section .description>span { display: block; text-align: center; } .user { display: grid; grid-template-areas: "profile-picture username watchers" "profile-picture description blank"; grid-template-columns: 40px auto auto; padding: 6px 10px; } .user:hover { background-color: #26262c; cursor: pointer; } .user .profile-picture { grid-area: profile-picture; width: 32px; height: 32px; border-radius: 50%; } .user .username { grid-area: username; /*font-size: 0.9rem;*/ font-size: 15px; font-weight: 550; } .user .description { grid-area: description; /*font-size: 0.8rem;*/ font-size: 13px; color: #a1a1a1; /* font-weight: 500; */ letter-spacing: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user .watchers { grid-area: watchers; display: flex; align-items: center; justify-content: flex-end; /*font-size: 0.9rem;*/ font-size: 13px; color: #c0c0c0; margin-right: 2px; } .user .watchers .dot { font-size: 7px; margin-right: 5px; } #listMain #wrap #serviceHeader #afLogo { left: 30px; height: 72px; } .btn_flexible { display: none; } #innerLnb { display: none; } #list-container { height: 100vh; overflow-y: auto; } #sidebar { height: 100vh; overflow-y: auto; position: fixed; } #sidebar::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } .tooltip-container { z-index: 999; width: 320px; height: auto; position: fixed; background-color: #26262C; } .tooltip-container img { position: relative; z-index: 999; width: auto; height: auto; max-height:240px } .tooltiptext { position: relative; z-index: 999; width: 320px; height: 48px; background-color: #26262C; color: #fff; text-align: center; display: flex; align-items: center; /* 세로 가운데 정렬 */ justify-content: center; /* 가로 가운데 정렬 */ top:-4px; } `; const css_Whitemode = ` .users-section.myplus > .user.show-more { display: none; } .users-section.follow > .user.show-more { display: none; } #toggleButton, #toggleButton2 { padding:12px; color:black; } .left_navbar { display: flex; align-items: center; justify-content: flex-end; position: absolute; flex-direction: row-reverse; top: 0px; left: 160px; /* 변경된 부분: left 속성으로 수정 */ } .left_nav_button { font-family: Arial, Helvetica, sans-serif; /* 나눔고딕 대신 sans-serif 폰트 중 하나를 선택하여 적용 */ position: relative; width: 70px; height: 70px; padding: 0; border: 0; border-radius: 50%; cursor: pointer; z-index: 3001; transition: all .2s; color: black; font-size: 15px; font-weight: 600; } .left_nav_button.active { color: #0545B1; } #sidebar { width: 240px; grid-area: sidebar; background-color: #EFEFF1; color:black; padding-bottom:150px; } #sidebar .top-section { display: flex; align-items: center; justify-content: space-around; margin: 10px 0px; } #sidebar .top-section>span { text-transform: uppercase; font-weight: 600; font-size: 14px; margin-top: 6px; margin-bottom: 4px; } #sidebar .top-section>span>a { color:black; } #sidebar .twitch-message-section { margin: 0px 10px; margin-top: 10px; padding: 0 25px; background-color: #EFEFF1; } #sidebar .twitch-message-section .title { margin: 0px; font-size: 1.5rem; font-weight: 500; } #sidebar .twitch-message-section .title>span { color: var(--primary-color); } #sidebar .twitch-message-section .description { margin: 8px 0px; line-height: 1.3rem; font-size: 0.9rem; color: #53535F; } #sidebar .twitch-message-section .description>span { display: block; text-align: center; } .user { display: grid; grid-template-areas: "profile-picture username watchers" "profile-picture description blank"; grid-template-columns: 40px auto auto; padding: 6px 10px; } .user:hover { background-color: #E6E6EA; cursor: pointer; } .user .profile-picture { grid-area: profile-picture; width: 32px; height: 32px; border-radius: 50%; } .user .username { grid-area: username; font-size: 15px; font-weight: 600; } .user .description { grid-area: description; font-size: 13px; color: #53535F; letter-spacing: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user .watchers { grid-area: watchers; display: flex; align-items: center; justify-content: flex-end; font-size: 13px; color: black; margin-right: 2px; } .user .watchers .dot { font-size: 7px; margin-right: 5px; } #listMain #wrap #serviceHeader #afLogo { left: 30px; height: 72px; } .btn_flexible { display: none; } #innerLnb { display: none; } #list-container { height: 100vh; overflow-y: auto; } #sidebar { height: 100vh; overflow-y: auto; position: fixed; } #sidebar::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } .tooltip-container { z-index: 999; width: 320px; height: auto; position: fixed; background-color: #E6E6EA; } .tooltip-container img { position: relative; z-index: 999; width: auto; height: auto; max-height:240px } .tooltiptext { position: relative; z-index: 999; width: 320px; height: 48px; background-color: #E6E6EA; color: black; text-align: center; display: flex; align-items: center; /* 세로 가운데 정렬 */ justify-content: center; /* 가로 가운데 정렬 */ top:-4px; } `; function waitForElement(elementSelector, callBack) { const element = document.querySelector(elementSelector); if (element) { callBack(elementSelector, element); } else { setTimeout(function () { waitForElement(elementSelector, callBack); }, 200); } } function desc_order(selector){ // Get the container element const container = document.querySelector(selector); // Get all user elements const userElements = document.querySelectorAll(`${selector} >.user`); // Convert NodeList to Array for easier manipulation const userArray = Array.from(userElements); // Sort userArray based on the data-watchers attribute userArray.sort((a, b) => { const watchersA = parseInt(a.getAttribute('data-watchers') || '0'); const watchersB = parseInt(b.getAttribute('data-watchers') || '0'); return watchersB - watchersA; }); // Clear container and append sorted elements container.innerHTML = ''; userArray.forEach(user => { container.appendChild(user); }); } function addNumberSeparator(number) { // toLocaleString 메서드를 사용하여 숫자에 구분자 추가 number = Number(number); return number.toLocaleString(); } // 사용자 요소를 생성하는 함수 function createUserElement(channel) { const userElement = document.createElement('div'); const playerLink = "https://play.afreecatv.com/"+channel.user_id; const broad_thumnail = `https://liveimg.afreecatv.com/m/${channel.broad_no}`; userElement.classList.add('user'); userElement.setAttribute('onclick',`window.open('${playerLink}', '_blank')`); userElement.setAttribute('data-watchers',`${channel.total_view_cnt}`); userElement.setAttribute('broad_thumnail',`${broad_thumnail}`); userElement.setAttribute('tooltip',`${channel.broad_title}`); userElement.setAttribute('user_id',`${channel.user_id}`); const profilePicture = document.createElement('img'); const pp_webp="https://stimg.afreecatv.com/LOGO/"+channel.user_id.slice(0, 2)+"/"+channel.user_id+"/m/"+channel.user_id+".webp"; const pp_jpg="https://profile.img.afreecatv.com/LOGO/"+channel.user_id.slice(0, 2)+"/"+channel.user_id+"/m/"+channel.user_id+".jpg"; profilePicture.src = pp_webp; // 프로필사진 profilePicture.setAttribute('onerror', `this.onerror=null; this.src='${pp_jpg}'`); profilePicture.setAttribute('alt', `${channel.user_id}'`); profilePicture.setAttribute('onclick', `event.stopPropagation();window.open('https://bj.afreecatv.com/${channel.user_id}', '_blank');`); //profilePicture.onerror=`this.onerror=null; this.src='${pp_jpg}'`; profilePicture.classList.add('profile-picture'); const username = document.createElement('span'); username.classList.add('username'); username.textContent = channel.user_nick; //스트리머명 const cat_no = channel.broad_cate_no; const categoryList = oMainCategory.category_list; const filteredList = categoryList.filter(word => !["전체", "제한"].some(keyword => word.menu_name.includes(keyword))); const targetActionContent = cat_no; const regexPattern = new RegExp(targetActionContent.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i"); const matchedItem = filteredList.find(item => regexPattern.test(item.action_content)); // 일치하는 항목이 있다면 해당 항목의 menu_name 리턴, 없으면 null 리턴 let result = matchedItem ? matchedItem.menu_name : cat_no; if(result==="00040121"){ result = "종합게임"; } if(result==="00300000"){ result = "연령제한"; } if(result==="ADULT_BROAD_CATE"){ result = "연령제한"; } if(result==="LoL"){ result = "리그 오브 레전드"; } if(result==="스타"){ result = "스타크래프트"; } const description = document.createElement('span'); description.classList.add('description'); description.textContent = result; //카테고리 const watchers = document.createElement('span'); watchers.classList.add('watchers'); watchers.innerHTML = `<span class="dot" role="img" aria-label="Amount of people watching">🔴</span>${addNumberSeparator(channel.total_view_cnt)}</span>`; //시청자수 userElement.appendChild(profilePicture); userElement.appendChild(username); userElement.appendChild(description); userElement.appendChild(watchers); return userElement; } // 특정 HTML 삽입 const newHtml = ` <div id="sidebar"> </div> `; // #serviceLnb 하위에 HTML 삽입 const serviceLnbElement = document.getElementById('serviceLnb'); if (serviceLnbElement) { serviceLnbElement.insertAdjacentHTML('beforeend', newHtml); } function insertTopChannels(){ // 특정 HTML 삽입 const newHtml = ` <div class="top-section"> <span>인기 채널</span> </div> <div class="users-section top"> </div> `; // #serviceLnb 하위에 HTML 삽입 const serviceLnbElement = document.getElementById('sidebar'); if (serviceLnbElement) { serviceLnbElement.insertAdjacentHTML('beforeend', newHtml); } GM_xmlhttpRequest({ method: 'GET', url: 'https://live.afreecatv.com/api/main_broad_list_api.php?selectType=action&selectValue=myplus&orderType=view_cnt&pageNo=1&lang=ko_KR', headers: { 'Content-Type': 'application/json', }, onload: function(response) { try { // 응답을 JSON으로 파싱 const jsonResponse = JSON.parse(response.responseText); // 응답에서 필요한 정보 추출 const channels = jsonResponse.broad; // users-section에 동적으로 user 요소 추가 const usersSection = document.querySelector('.users-section.top'); channels.forEach(channel => { const userElement = createUserElement(channel); usersSection.appendChild(userElement); }); } catch (error) { console.error('Error parsing JSON:', error); } }, onerror: function(error) { console.error('Error:', error); } }); } function insertFavoriteChannels(response){ // 특정 HTML 삽입 const newHtml = ` <div class="top-section"> <span><a href="https://my.afreecatv.com/favorite">즐겨찾기 중인 채널</a></span> </div> <div class="users-section follow"> </div> `; // #serviceLnb 하위에 HTML 삽입 const serviceLnbElement = document.getElementById('sidebar'); if (serviceLnbElement) { serviceLnbElement.insertAdjacentHTML('beforeend', newHtml); } try { // 응답에서 필요한 정보 추출 const jsonData = response; // 데이터 배열을 순회하면서 각각의 객체에서 broad_info를 확인합니다. jsonData.data.forEach(item => { // broad_info가 비어있는지 확인합니다. if (item.broad_info.length === 0) { //비방 //console.log(`broad_info is empty for user ${item.user_nick}`); } else { //방송중 // broad_info가 비어있지 않은 경우, 여러가지 작업을 수행할 수 있습니다. //console.log(`broad_info is not empty for user ${item.user_nick}`); // users-section에 동적으로 user 요소 추가 const usersSection = document.querySelector('.users-section.follow'); const userElement = createUserElement(item.broad_info[0]); usersSection.appendChild(userElement); } }); } catch (error) { console.error('Error parsing JSON:', error); } } function insertMyplusChannels(){ // 특정 HTML 삽입 const newHtml = ` <div class="top-section"> <span>MY+ 추천 채널</span> </div> <div class="twitch-message-section myplus"> <div class="description"><span>추천 채널이 없습니다</span></div> </div> <div class="users-section myplus"> </div> `; // #serviceLnb 하위에 HTML 삽입 const serviceLnbElement = document.getElementById('sidebar'); if (serviceLnbElement) { serviceLnbElement.insertAdjacentHTML('beforeend', newHtml); } GM_xmlhttpRequest({ method: 'GET', url: 'https://live.afreecatv.com/api/myplus/preferbjLiveVodController.php?nInitCnt=6&szRelationType=C', headers: { 'Content-Type': 'application/json', }, onload: function(response) { try { // 응답을 JSON으로 파싱 const jsonResponse = JSON.parse(response.responseText); // 응답에서 필요한 정보 추출 const channels = jsonResponse.DATA.live_list; if(channels.length!==0){ const noti = document.querySelector('.twitch-message-section.myplus'); noti.style.display = 'none'; } // users-section에 동적으로 user 요소 추가 const usersSection = document.querySelector('.users-section.myplus'); channels.forEach(channel => { const userElement = createUserElement(channel); usersSection.appendChild(userElement); }); } catch (error) { console.error('Error parsing JSON:', error); } }, onerror: function(error) { console.error('Error:', error); } }); } function makethumbnailtooltip(){ // HTMLCollection을 가져옴 const elements = document.getElementsByClassName('user'); const tooltipcontainer = document.getElementsByClassName('tooltip-container')[0]; // 각 요소에 대해 반복하면서 이벤트 리스너 추가 for (const element of elements) { element.addEventListener('mouseenter', function() { const rect = this.getBoundingClientRect(); const elementX = rect.left + 240; // 요소의 X 좌표 const elementY = rect.top; // 요소의 Y 좌표 //console.log(elementX,elementY); // 각 툴팁에 대해 위치 설정 const imgSrc = this.getAttribute('broad_thumnail'); const broad_title = this.getAttribute('tooltip'); // 새로운 div 요소를 생성하고 스타일과 내용을 설정 tooltipcontainer.style.left = `${elementX}px`; tooltipcontainer.style.top = `${elementY}px`; tooltipcontainer.innerHTML = `<img src="${imgSrc}"><div class="tooltiptext">${broad_title}</div>`; tooltipcontainer.style.display = 'block'; }); element.addEventListener('mouseleave', function() { tooltipcontainer.style.display = 'none'; }); } } function showMore_myplus(){ const userContainer = document.querySelector('.users-section.myplus'); const users = userContainer.querySelectorAll('.user'); if (users.length < 7){ return false; } users.forEach((user, index) => { if (index >= 6) { user.classList.add('show-more'); } }); // 동적으로 버튼 생성 및 삽입 const toggleButton = document.createElement('button'); toggleButton.textContent = `더 보기 (${users.length - 6})`; toggleButton.id = 'toggleButton'; userContainer.appendChild(toggleButton); const toggle_button = document.getElementById('toggleButton'); toggle_button.addEventListener('click', function () { const users = userContainer.querySelectorAll('.user'); const hiddenUsers = users.length - 6; // 숨겨진 요소의 개수 계산 const lastUser = users[users.length - 1]; if (lastUser.classList.contains('show-more')) { // 더 보기를 눌렀을 때 toggleButton.textContent = `접기`; users.forEach((user, index) => { if (index >= 6) { user.classList.remove('show-more'); } }); } else { // 접기를 눌렀을 때 toggleButton.textContent = `더 보기 (${hiddenUsers})`; users.forEach((user, index) => { if (index >= 6) { user.classList.add('show-more'); } }); } }); } function showMore_follow(){ const userContainer = document.querySelector('.users-section.follow'); const users = userContainer.querySelectorAll('.user'); if (users.length < 7){ return false; } users.forEach((user, index) => { if (index >= 6) { user.classList.add('show-more'); } }); // 동적으로 버튼 생성 및 삽입 const toggleButton = document.createElement('button'); toggleButton.textContent = `더 보기 (${users.length - 6})`; toggleButton.id = 'toggleButton2'; userContainer.appendChild(toggleButton); const toggle_button = document.getElementById('toggleButton2'); toggle_button.addEventListener('click', function () { const users = userContainer.querySelectorAll('.user'); const hiddenUsers = users.length - 6; // 숨겨진 요소의 개수 계산 const lastUser = users[users.length - 1]; if (lastUser.classList.contains('show-more')) { // 더 보기를 눌렀을 때 toggleButton.textContent = `접기`; users.forEach((user, index) => { if (index >= 6) { user.classList.remove('show-more'); } }); } else { // 접기를 눌렀을 때 toggleButton.textContent = `더 보기 (${hiddenUsers})`; users.forEach((user, index) => { if (index >= 6) { user.classList.add('show-more'); } }); } }); } function removeDuplicates(){ if(document.querySelectorAll('.users-section.follow > .user').length ===0){ return false; } // .users-section.follow > .user 모든 요소 반복 document.querySelectorAll('.users-section.follow > .user').forEach(followUser => { const followUserId = followUser.getAttribute('user_id'); // .users-section.myplus > .user 모든 요소 반복 document.querySelectorAll('.users-section.myplus > .user').forEach(myplusUser => { const myplusUserId = myplusUser.getAttribute('user_id'); // user_id 일치 여부 확인 if (followUserId === myplusUserId) { // 일치할 경우 .user 요소 제거 myplusUser.remove(); } }); }); } // HTML 요소를 가져옵니다. const htmlElement = document.querySelector('html'); // dark 속성의 값을 확인합니다. const isDarkMode = htmlElement.getAttribute('dark') === 'true'; if(isDarkMode){ GM_addStyle(css_Darkmode); } else { GM_addStyle(css_Whitemode); } var listsection = document.querySelector('#list-section'); // .left_navbar를 찾거나 생성 var leftNavbar = document.querySelector('.left_navbar'); if (!leftNavbar) { leftNavbar = document.createElement('div'); leftNavbar.className = 'left_navbar'; // 페이지의 적절한 위치에 추가 var targetElement = document.body; // 원하는 위치에 따라 수정 targetElement.insertBefore(leftNavbar, targetElement.firstChild); } // 새로운 버튼을 만들기 var newButton = document.createElement('a'); newButton.href = 'https://www.afreecatv.com/?hash=all'; newButton.innerHTML = '<button type="button" class="left_nav_button">전체</button>'; var newButton2 = document.createElement('a'); newButton2.href = 'https://www.afreecatv.com/?hash=game'; newButton2.innerHTML = '<button type="button" class="left_nav_button">게임</button>'; var newButton3 = document.createElement('a'); newButton3.href = 'https://www.afreecatv.com/?hash=bora'; newButton3.innerHTML = '<button type="button" class="left_nav_button">보.라</button>'; var newButton4 = document.createElement('a'); newButton4.href = 'https://www.afreecatv.com/?hash=sports'; newButton4.innerHTML = '<button type="button" class="left_nav_button">스포츠</button>'; var tooltipContainer = document.createElement('div'); tooltipContainer.classList.add('tooltip-container'); // .left_navbar에 버튼 삽입 listsection.appendChild(tooltipContainer); leftNavbar.appendChild(newButton4); leftNavbar.appendChild(newButton3); leftNavbar.appendChild(newButton2); leftNavbar.appendChild(newButton); waitForElement('.left_nav_button', function (elementSelector, element) { // Get the current page URL const currentPage = window.location.href; // Get all navigation links const navLinks = document.querySelectorAll('.left_nav_button'); // Loop through each link and check if it matches the current page navLinks.forEach(link => { var parentLink = link.parentElement; if (parentLink.href === currentPage) { link.classList.add('active'); // Add the 'active' class if it matches } }); }); GM_xmlhttpRequest({ method: 'GET', url: 'https://myapi.afreecatv.com/api/favorite', headers: { 'Content-Type': 'application/json', }, onload: function(response) { // 응답 수정 response = response.responseText; response = JSON.parse(response); //console.log(response); // if 문으로 code 값 확인 if (response.code === -10000) { //console.log('로그인 상태가 아닙니다.'); insertTopChannels(); waitForElement('.users-section.top > .user', function (elementSelector, element) { makethumbnailtooltip(); }); return false; } let hasNonEmptyBroadInfo = false; // "data" 배열의 각 요소를 확인하는 반복문 for (const item of response.data) { // "broad_info"가 비어 있지 않은 경우 if (item.broad_info.length > 0) { hasNonEmptyBroadInfo = true; // 여기에 해당 요소에 대한 추가 동작을 수행할 수 있습니다. break; // 만약 하나라도 비어 있지 않은 경우에 중단하려면 이 부분을 사용합니다. } } if (response.data.length === 0) { //console.log('즐찾이 없습니다.'); insertMyplusChannels(); insertTopChannels(); waitForElement('.users-section.myplus > .user', function (elementSelector, element) { waitForElement('.users-section.top > .user', function (elementSelector, element) { desc_order('.users-section.myplus'); showMore_myplus(); makethumbnailtooltip(); }); }); } else if (hasNonEmptyBroadInfo) { // 즐찾 중 방송중인 스트리머가 한 명 이상 insertFavoriteChannels(response); insertMyplusChannels(); insertTopChannels(); waitForElement('.users-section.follow > .user', function (elementSelector, element) { waitForElement('.users-section.myplus > .user', function (elementSelector, element) { waitForElement('.users-section.top > .user', function (elementSelector, element) { desc_order('.users-section.follow'); desc_order('.users-section.myplus'); removeDuplicates(); showMore_follow(); showMore_myplus(); makethumbnailtooltip(); }); }); }); } else { // 즐찾은 있지만 전부 비방 const newHtml = ` <div class="top-section"> <span><a href="https://my.afreecatv.com/favorite">즐겨찾기 중인 채널</a></span> </div> <div class="twitch-message-section"> <div class="description"><span>방송 중인 채널이 없습니다</span></div> </div> `; const serviceLnbElement = document.getElementById('sidebar'); if (serviceLnbElement) { serviceLnbElement.insertAdjacentHTML('beforeend', newHtml); } insertMyplusChannels(); insertTopChannels(); waitForElement('.users-section.myplus > .user', function (elementSelector, element) { waitForElement('.users-section.top > .user', function (elementSelector, element) { desc_order('.users-section.myplus'); showMore_myplus(); makethumbnailtooltip(); }); }); } }, onerror: function(error) { console.error('Error:', error); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址