您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
the OKX_exchange
// ==UserScript== // @name OKX_exchange // @namespace [email protected] // @version 1.0 // @description the OKX_exchange // @author [email protected] // @match *://www.okx.com // @match *://*.okx.com // @match *://www.okx.com/* // @match *://*.okx.com/* // @exclude *://www.12gm.com/* // @exclude *://*.12gm.com/* // @license AGPL License // @grant GM_download // @grant GM_openInTab // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant unsafeWindow // @grant GM_setClipboard // @grant GM_getResourceURL // @grant GM_getResourceText // @grant GM_info // @grant GM_registerMenuCommand // @grant GM_cookie // ==/UserScript== (function () { 'use strict'; class PublicFunc { base_url = `https://local.12gm.com` #stop_wait_value = false //是否停止等待查找元素 #stop_wait_ele = false #_get(URL, queryJSON, callback) { if (typeof queryJSON == 'function') { callback = queryJSON; queryJSON = {} } let xhr; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest() } else { xhr = new ActiveXObject("Microsoft.XMLHTTP") } xhr.onreadystatechange = function() { if (xhr.readyState == 4) { let data = null; if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { data = xhr.responseText } else { console.log(new Error("AJAX GET did not find the requested file")) } callback(data) } }; let querystring = this.#_json_query(queryJSON); let joiner; if (!URL.includes('?')) { joiner = "?" } else { joiner = "&" } if (querystring) { querystring = joiner + querystring } URL = URL + querystring; xhr.open("get", URL, true); xhr.send(null) } #_post(URL, queryJSON, callback) { let xhr; if (window.XMLHttpRequest) { xhr = new window.XMLHttpRequest() } else { xhr = new ActiveXObject("Microsoft.XMLHTTP") } xhr.onreadystatechange = function() { if (xhr.readyState == 4) { let data = null; if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { data = xhr.responseText } else { console.log(new Error("AJAX POST did not find the requested file")) } callback(data) } }; let querystring = this.#_json_query(queryJSON); xhr.open("post", URL, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(querystring) } #check_url(url) { let url_check = /^((https|http)\:|\/\/)/; if (url_check.test(url)) { return url } return this.remote_url(url) } #_json_query(json) { var arr = []; for (var k in json) { arr.push(k + "=" + encodeURIComponent(json[k])) } if (arr.length == 0) { return "" } return arr.join("&") } get(url_method, request_data) { url_method = this.#check_url(url_method); return new Promise((resolve, reject) => { console.log(url_method) this.#_get(url_method, request_data, (data) => { if (data) { data = this.to_json(data) } resolve(data) }) }) } post(url_method, data) { url_method = this.#check_url(url_method); return new Promise((resolve, reject) => { this.#_post(url_method, data, (data) => { if (data) { data = this.to_json(data) } resolve(data) }) }) } class_toggle(selector, class_toggle) { class_toggle = class_toggle.trim() let ele = document.querySelector(selector) let classes = ele.getAttribute('class') classes = classes.split(/\s+/) let index = classes.indexOf(class_toggle) if (index != -1) { classes[index] = "" } else { classes.push(class_toggle) } classes = classes.join(' ') ele.setAttribute('class', classes) } numeric(n) { let numbric = /^\d+$/ if (numbric.test(n)) { return true } return false } get_base_url(suffix = '') { let base_remote_url = `${this.base_url}/${suffix}` return base_remote_url } get_file(file) { let this_point = this return new Promise((resolve, reject) => { this_point.get('api:get_static_files', { file }).then((data) => { resolve(data) }) }); } to_json(value) { try { value = JSON.parse(value) } catch (e) { console.log(`value ${value}`) console.log(`to_json ${e}`) } return value } info(message) { let id = "#WordToNoteBookButton" let note = document.querySelector(id) if (note) { note.querySelector('span').innerHTML = message note.style.display = 'block' setTimeout(() => { note.style.display = 'none' }, 1500) } } is_mobile_browser() { let mobile_match = navigator.userAgent.match( /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i ) if (mobile_match) { this.get_trans_word_index = 2 this.mobile_browser = 1 } else { this.get_trans_word_index = 3 this.mobile_browser = 0 } } exclude() { let is_frame = (window.self === window.top) == false let is_exclude = false if (is_frame) { return true } let exclude_hosts = [ // "12gm.com", `127.0.0.1`, `localhost` ] let hostname = window.location.hostname exclude_hosts.forEach(exclude_host => { if (hostname.endsWith(exclude_host)) { is_exclude = true return } }) return is_exclude } date_totimestamp(time) { if (!time) { time = new Date() } else if (typeof time == 'string' || typeof time == 'number') { time = new Date(time) } let timesdamp = Date.parse(time) return timesdamp } timestamp_todate(time, format = 'Y-M-D h:m:s') { let date if (typeof time == 'object') { date = time } else { if (this.numeric(time)) { time = parseInt(time) } date = new Date(time) } let Y = date.getFullYear(); let M = this.fill_alphabet(date.getMonth() + 1, 2, '0'); let D = this.fill_alphabet(date.getDate(), 2, '0'); let h = this.fill_alphabet(date.getHours(), 2, '0'); let m = this.fill_alphabet(date.getMinutes(), 2, '0'); let s = this.fill_alphabet(date.getSeconds(), 2, '0'); format = format.replace('Y', Y) format = format.replace('M', M) format = format.replace('D', D) format = format.replace('h', h) format = format.replace('m', m) format = format.replace('s', s) return format } rate(price, comparison_price) { return (price - comparison_price) / comparison_price } keep_pointtostring(n, keep_point = 2) { n = (n + '').split('.') if (n.length > 1) { n[1] = n[1].substr(0, keep_point) } n = n.join('.') return n } create_time(format = 'Y-M-D h:m:s') { let time = this.timestamp_todate(new Date(), format) return time } fill_alphabet(s, l, fill_s = "0") { s = s + "" s = s.padStart(l, fill_s) return s } remove(selector) { let ele = document.querySelector(selector) if (ele) { ele.remove() } } split_html(html) { html = html.replaceAll(/<.+?>/g, '') return html } local_storage(key, value) { if (value) { localStorage.setItem(key, value) } else { return localStorage.getItem(key) } } remote_url(module_method) { module_method = module_method.split(":") if (module_method.length == 0) { module_method.unshift('translate') } let method = module_method[module_method.length - 1] let module_name = module_method[0] if (module_name != 'control') { module_name = `com_${module_name}` } let key = `9LrQN0~14,dSmoO^` let url = this.get_base_url(`api?method=${method}&key=${key}&module=${module_name}`) return url } //给添加的元素添加监听事件 listen(ele_selector, event, callback) { if (typeof ele_selector == 'string') { ele_selector = document.querySelector(ele_selector) } if (ele_selector) { ele_selector.addEventListener(event, () => { callback() }) } } toggle_action(ele) { ele = this.get_elements(ele) let toggle = ele.dataset.toggle if (toggle) { let key_default = ['textContent', `value`, `className`] let toggles = toggle.split('|') let toggle_object = {} toggles.forEach((val, index) => { let key if (val.indexOf('=') != -1) { let vals = val.split(`=`) val = vals.pop() key = vals[0] } else { if (index >= key_default.length) { return true } key = key_default[index] } key = key.trim() if (key == 'class') { key = 'className' } if (key == 'text' || key == 'html') { key = 'textContent' } val = val.trim() toggle_object[key] = val }) let keys = Object.keys(toggle_object) let backup_origin = {} keys.forEach((key) => { backup_origin[key] = ele[key] }) let toggle_value = toggle_object.value if (typeof toggle_value == 'string') { toggle_value = ['false', '', 'null'].indexOf(toggle_value.toLowerCase()) != -1 ? false : true; } toggle_value = !toggle_value backup_origin.value = toggle_value.toString() let backup_origintext = [] for (let key in backup_origin) { let val = backup_origin[key] backup_origintext.push(`${key}=${val}`) } for (let key in toggle_object) { let val = toggle_object[key] if (key != 'value') { ele[key] = val } } backup_origintext = backup_origintext.join("|") ele.setAttribute('data-toggle', backup_origintext) return toggle_value } return true } bind(Okx, parent_selectro = "", ...additional) { let panelasid = this.get_elements(`${parent_selectro} [id]`) panelasid.forEach((ele) => { let id = ele.getAttribute('id') if (id.startsWith('on-')) { let id_information = id.split('-') let event_name = id_information.pop() let event_entity = Okx[event_name] if (event_entity) { console.log(`bind of Okx of ${id}`, Okx) $$.listen(ele, 'click', () => { let toggle_object = this.toggle_action(ele) Okx[event_name](toggle_object) }) } else { console.log(`additional`, additional, event_name) additional.forEach((another) => { if (another[event_name]) { console.log(`bind at another of ${id}`, another) $$.listen(ele, 'click', () => { let toggle_object = this.toggle_action(ele) // console.log(`toggle_object ${toggle_object}`) another[event_name](toggle_object) }) } }) } } }) } wait_ele(ele_selector, callback, wait = 1000) { if (this.#stop_wait_ele == true) { this.#stop_wait_ele == false console.log(`wait_ele has stoped from ${ele_selector}`) return } let ele = document.querySelector(ele_selector) if (!ele) { console.log(`wait_ele ${ele_selector} loading ${wait / 1000}s`) setTimeout(() => { this.wait_ele(ele_selector, callback, wait) }, wait) } else { callback() } } wait_value(ele_selector, valuetype = 'innerHTML', expect = 'text', callback, wait = 1000) { if (this.#stop_wait_value == true) { this.#stop_wait_value == false console.log(`wait_value has stoped from ${ele_selector}`) return } let ele = document.querySelector(ele_selector) let reg = /.{1,}/ switch (expect) { case 'number': reg = /^\d+$/ break case 'float': reg = /^[\d\.]+$/ break } if (!ele || !reg.test(ele[valuetype])) { console.log(`wait_value ${ele_selector} loading ${wait / 1000}s`) setTimeout(() => { this.wait_value(ele_selector, valuetype, expect, callback, wait) }, wait) } else { callback() } } set_stop_wait_ele(val = false) { this.#stop_wait_ele = val } set_stop_wait_value(val = false) { this.#stop_wait_value = val } get_ele(ele_selector) { if (typeof ele_selector == 'string') { ele_selector = document.querySelector(ele_selector) } return ele_selector } get_elements(ele_selector) { if (typeof ele_selector == 'string') { ele_selector = document.querySelectorAll(ele_selector) } return ele_selector } create_ele(tag, types) { let ele = document.createElement(tag) for (let key in types) { let val = types[key] ele[key] = val } document.querySelector(`body`).insertAdjacentElement('beforeEnd', ele) } load_module(module_names) { let import_js = `` for (let key in module_names) { let val = module_names[key] import_js += `\nimport {${key}} from '${this.base_url}/static/core_js/${val}'\n` } // import_js += ` // okx_tampermonkey.initial() // ` let ele = document.createElement('script') ele.type = 'module' ele.innerHTML = import_js ele.textContent = import_js document.querySelector(`body`).insertAdjacentElement('afterEnd', ele) } initial() { if (this.exclude()) { return } //页面执行标记 document.$$executeToken = true let okx_jsurl = `static/core_js/okx.js` this.get_file(okx_jsurl).then((data) => { if (!data || !data.data || data.data.length == 0) { console.log(data) alert('okx_main 主文件请求不成功,请检查网络.') return } else { // console.log(`okx load success, url${okx_jsurl}, code length ${data.data.length}`, data) } let script = data.data[0] script = script.replaceAll("{{base_url}}", this.base_url) // console.log("script",script) this.create_ele('script', { type: 'module', innerHTML: script, // textContent: script }) }) } } const $$ = new PublicFunc() document.$$ = $$ $$.initial() })();