125论坛手机版优化

通过模拟小米10 Pro设备来优化125论坛移动端显示

  1. // ==UserScript==
  2. // @name 125论坛手机版优化
  3. // @namespace http://tampermonkey.net/
  4. // @version 4.8
  5. // @description 通过模拟小米10 Pro设备来优化125论坛移动端显示
  6. // @author Your name
  7. // @match https://bbs.125.la/*
  8. // @run-at document-start
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // 从localStorage加载配置
  15. const savedConfig = localStorage.getItem('deviceEmulatorConfig');
  16. // 默认设备配置
  17. let DEVICE_CONFIG = savedConfig ? JSON.parse(savedConfig) : {
  18. userAgent: 'Mozilla/5.0 (Linux; Android 11; Mi 10 Pro Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36',
  19. width: 393,
  20. height: 851,
  21. deviceScaleFactor: 1.5
  22. };
  23.  
  24. // 保存配置到localStorage
  25. function saveConfig() {
  26. localStorage.setItem('deviceEmulatorConfig', JSON.stringify(DEVICE_CONFIG));
  27. }
  28.  
  29. // 修改应用更改按钮的处理函数
  30. function applyChanges(content) {
  31. DEVICE_CONFIG.width = parseInt(content.querySelector('#deviceWidth').value);
  32. DEVICE_CONFIG.height = parseInt(content.querySelector('#deviceHeight').value);
  33. DEVICE_CONFIG.deviceScaleFactor = parseFloat(content.querySelector('#deviceScale').value);
  34. saveConfig(); // 保存配置
  35. initialize(); // 重新初始化
  36. }
  37.  
  38. // 创建悬浮窗
  39. function createControlPanel() {
  40. const panel = document.createElement('div');
  41. panel.id = 'deviceControlPanel';
  42. panel.style.cssText = `
  43. position: fixed;
  44. top: 20px;
  45. right: 20px;
  46. background: rgba(255, 255, 255, 0.95);
  47. padding: 8px;
  48. border-radius: 8px;
  49. box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  50. z-index: 9999;
  51. font-size: 14px;
  52. min-width: 40px;
  53. transition: all 0.3s;
  54. `;
  55.  
  56. // 修改标题和展开按钮
  57. const header = document.createElement('div');
  58. header.style.cssText = `
  59. display: flex;
  60. justify-content: space-between;
  61. align-items: center;
  62. cursor: move;
  63. `;
  64. header.innerHTML = `
  65. <span id="panelTitle" style="font-weight: bold; margin-right: 10px; display: none;">设备模拟控制面板</span>
  66. <button id="togglePanel" style="padding: 4px 8px; border: none; background: none; cursor: pointer;">⚙️</button>
  67. `;
  68. panel.appendChild(header);
  69.  
  70. // 更新设备预设
  71. const presets = {
  72. mi10pro: {
  73. name: "小米10 Pro",
  74. width: 393,
  75. height: 851,
  76. deviceScaleFactor: 1.5
  77. },
  78. mi12s: {
  79. name: "小米12S",
  80. width: 390,
  81. height: 844,
  82. deviceScaleFactor: 1.5
  83. },
  84. mi13: {
  85. name: "小米13",
  86. width: 412,
  87. height: 915,
  88. deviceScaleFactor: 1.5
  89. },
  90. iphone14pro: {
  91. name: "iPhone 14 Pro",
  92. width: 430,
  93. height: 932,
  94. deviceScaleFactor: 1.5
  95. },
  96. iphone13: {
  97. name: "iPhone 13",
  98. width: 390,
  99. height: 844,
  100. deviceScaleFactor: 1.5
  101. },
  102. pixel7: {
  103. name: "Pixel 7",
  104. width: 412,
  105. height: 915,
  106. deviceScaleFactor: 1.5
  107. },
  108. galaxys23: {
  109. name: "Galaxy S23",
  110. width: 360,
  111. height: 800,
  112. deviceScaleFactor: 1.5
  113. },
  114. huaweip60: {
  115. name: "华为 P60",
  116. width: 412,
  117. height: 915,
  118. deviceScaleFactor: 1.5
  119. },
  120. oppo_find_x6: {
  121. name: "OPPO Find X6",
  122. width: 412,
  123. height: 918,
  124. deviceScaleFactor: 1.5
  125. },
  126. vivo_x90: {
  127. name: "vivo X90",
  128. width: 393,
  129. height: 851,
  130. deviceScaleFactor: 1.5
  131. }
  132. };
  133.  
  134. // 创建内容区域
  135. const content = document.createElement('div');
  136. content.id = 'panelContent';
  137. content.style.display = 'none'; // 默认隐藏
  138. content.style.padding = '10px';
  139. content.innerHTML = `
  140. <div style="margin-bottom: 10px;">
  141. <label>宽度:</label>
  142. <input type="number" id="deviceWidth" value="${DEVICE_CONFIG.width}" style="width: 60px;">
  143. </div>
  144. <div style="margin-bottom: 10px;">
  145. <label>高度:</label>
  146. <input type="number" id="deviceHeight" value="${DEVICE_CONFIG.height}" style="width: 60px;">
  147. </div>
  148. <div style="margin-bottom: 10px;">
  149. <label>缩放比例:</label>
  150. <input type="number" id="deviceScale" value="${DEVICE_CONFIG.deviceScaleFactor}" step="0.1" style="width: 60px;">
  151. </div>
  152. <div style="margin-bottom: 10px;">
  153. <label>设备预设:</label>
  154. <select id="devicePreset" style="width: 120px;">
  155. <option value="custom">自定义</option>
  156. ${Object.entries(presets).map(([key, preset]) =>
  157. `<option value="${key}">${preset.name}</option>`
  158. ).join('')}
  159. </select>
  160. </div>
  161. <button id="applyChanges" style="width: 100%; padding: 5px;">应用更改</button>
  162. `;
  163. panel.appendChild(content);
  164.  
  165. // 修改最小化功能
  166. const toggleBtn = panel.querySelector('#togglePanel');
  167. const content_div = panel.querySelector('#panelContent');
  168. const panelTitle = panel.querySelector('#panelTitle');
  169. let isMinimized = true; // 默认收起
  170.  
  171. toggleBtn.addEventListener('click', () => {
  172. isMinimized = !isMinimized;
  173. content_div.style.display = isMinimized ? 'none' : 'block';
  174. panelTitle.style.display = isMinimized ? 'none' : 'block';
  175. toggleBtn.textContent = isMinimized ? '⚙️' : '×';
  176. panel.style.minWidth = isMinimized ? '40px' : '200px';
  177. panel.style.padding = isMinimized ? '8px' : '15px';
  178. });
  179.  
  180. // 添加拖动功能
  181. let isDragging = false;
  182. let currentX;
  183. let currentY;
  184. let initialX;
  185. let initialY;
  186.  
  187. header.addEventListener('mousedown', dragStart);
  188. document.addEventListener('mousemove', drag);
  189. document.addEventListener('mouseup', dragEnd);
  190.  
  191. function dragStart(e) {
  192. initialX = e.clientX - panel.offsetLeft;
  193. initialY = e.clientY - panel.offsetTop;
  194. isDragging = true;
  195. }
  196.  
  197. function drag(e) {
  198. if (isDragging) {
  199. e.preventDefault();
  200. currentX = e.clientX - initialX;
  201. currentY = e.clientY - initialY;
  202. panel.style.left = currentX + 'px';
  203. panel.style.top = currentY + 'px';
  204. panel.style.right = 'auto';
  205. }
  206. }
  207.  
  208. function dragEnd() {
  209. isDragging = false;
  210. }
  211.  
  212. // 添加设备预设
  213. const presetSelect = content.querySelector('#devicePreset');
  214. presetSelect.addEventListener('change', () => {
  215. const preset = presets[presetSelect.value];
  216. if (preset) {
  217. content.querySelector('#deviceWidth').value = preset.width;
  218. content.querySelector('#deviceHeight').value = preset.height;
  219. content.querySelector('#deviceScale').value = preset.deviceScaleFactor;
  220. }
  221. });
  222.  
  223. // 修改应用更改按钮的事件处理
  224. const applyBtn = content.querySelector('#applyChanges');
  225. applyBtn.addEventListener('click', () => {
  226. applyChanges(content);
  227. });
  228.  
  229. // 设置预设选择框的初始值
  230. let currentPreset = 'custom';
  231. for (const [key, preset] of Object.entries(presets)) {
  232. if (preset.width === DEVICE_CONFIG.width &&
  233. preset.height === DEVICE_CONFIG.height &&
  234. preset.deviceScaleFactor === DEVICE_CONFIG.deviceScaleFactor) {
  235. currentPreset = key;
  236. break;
  237. }
  238. }
  239. presetSelect.value = currentPreset;
  240.  
  241. document.body.appendChild(panel);
  242. }
  243.  
  244. // 防抖函数
  245. function debounce(func, wait) {
  246. let timeout;
  247. return function() {
  248. const context = this;
  249. const args = arguments;
  250. clearTimeout(timeout);
  251. timeout = setTimeout(() => func.apply(context, args), wait);
  252. };
  253. }
  254.  
  255. // 模拟设备特性
  256. function emulateDevice() {
  257. // 只在第一次执行时修改User-Agent
  258. if (!window._userAgentModified) {
  259. Object.defineProperty(navigator, 'userAgent', {
  260. get: function() { return DEVICE_CONFIG.userAgent; }
  261. });
  262. window._userAgentModified = true;
  263. }
  264.  
  265. // 修改设备属性
  266. try {
  267. Object.defineProperties(window.screen, {
  268. width: { value: DEVICE_CONFIG.width },
  269. height: { value: DEVICE_CONFIG.height },
  270. availWidth: { value: DEVICE_CONFIG.width },//减去10px
  271. availHeight: { value: DEVICE_CONFIG.height }
  272. });
  273. } catch(e) {
  274. console.log('Screen properties already defined');
  275. }
  276. }
  277.  
  278. // 设置viewport
  279. function setupViewport() {
  280. const existingViewport = document.querySelector('meta[name="viewport"]');
  281. // 修改viewport内容,使用固定宽度
  282. const viewportContent = `width=${DEVICE_CONFIG.width}, initial-scale=1.0, user-scalable=yes`;
  283.  
  284. if (existingViewport) {
  285. if (existingViewport.content !== viewportContent) {
  286. existingViewport.content = viewportContent;
  287. }
  288. } else {
  289. const viewport = document.createElement('meta');
  290. viewport.name = 'viewport';
  291. viewport.content = viewportContent;
  292. document.head.appendChild(viewport);
  293. }
  294. }
  295.  
  296. // 添加页面宽度限制的CSS
  297. function addPageStyles() {
  298. const styleSheet = document.createElement('style');
  299. styleSheet.textContent = `
  300. html {
  301. overflow-x: hidden !important;
  302. width: 100% !important;
  303. font-size: 16px !important;
  304. }
  305. body {
  306. overflow-x: hidden !important;
  307. width: 100% !important;
  308. min-width: 100% !important;
  309. max-width: 100% !important;
  310. position: relative !important;
  311. margin: 0 !important;
  312. padding: 0 !important;
  313. font-size: 16px !important;
  314. line-height: 1.6 !important;
  315. }
  316.  
  317. #wp, #ct, .wp, .ct {
  318. width: 100% !important;
  319. min-width: 100% !important;
  320. max-width: 100% !important;
  321. margin: 0 !important;
  322. padding: 0 !important;
  323. overflow-x: hidden !important;
  324. }
  325.  
  326. .container {
  327. width: 100% !important;
  328. min-width: 100% !important;
  329. max-width: 100% !important;
  330. margin: 0 !important;
  331. padding: 0 10px !important;
  332. box-sizing: border-box !important;
  333. }
  334.  
  335. /* 设置字体大小 */
  336. .thread_tit, h3 {
  337. font-size: 18px !important;
  338. line-height: 1.4 !important;
  339. margin: 10px 0 !important;
  340. }
  341.  
  342. p, div, span, a {
  343. font-size: 16px !important;
  344. line-height: 1.6 !important;
  345. }
  346.  
  347. .f_count, .sub_forum {
  348. font-size: 14px !important;
  349. }
  350.  
  351. img {
  352. max-width: 100% !important;
  353. height: auto !important;
  354. }
  355.  
  356. /* 防止字体自动调整大小 */
  357. * {
  358. -webkit-text-size-adjust: none !important;
  359. text-size-adjust: none !important;
  360. }
  361. `;
  362. document.head.appendChild(styleSheet);
  363. }
  364.  
  365. // 修改初始化逻辑
  366. function initialize() {
  367. emulateDevice();
  368. setupViewport();
  369. addPageStyles(); // 添加页面样式
  370. // 确保DOM加载完成后再创建控制面板
  371. if (document.readyState === 'complete') {
  372. if (!document.querySelector('#deviceControlPanel')) {
  373. setTimeout(createControlPanel, 500);
  374. }
  375. } else {
  376. window.addEventListener('load', () => {
  377. if (!document.querySelector('#deviceControlPanel')) {
  378. setTimeout(createControlPanel, 500);
  379. }
  380. });
  381. }
  382. }
  383.  
  384. // 初始执行
  385. initialize();
  386.  
  387. // 监听viewport变化
  388. const observer = new MutationObserver((mutations) => {
  389. let needsUpdate = false;
  390. mutations.forEach((mutation) => {
  391. if (mutation.type === 'childList') {
  392. needsUpdate = true;
  393. }
  394. });
  395. if (needsUpdate) {
  396. debouncedSetupViewport();
  397. }
  398. });
  399.  
  400. // 延迟启动观察器
  401. setTimeout(() => {
  402. observer.observe(document.head, {
  403. childList: true,
  404. subtree: true
  405. });
  406. }, 1000);
  407.  
  408. // 清理函数
  409. window.addEventListener('unload', () => {
  410. observer.disconnect();
  411. });
  412.  
  413. // 使用防抖处理viewport变化
  414. const debouncedSetupViewport = debounce(setupViewport, 100);
  415.  
  416. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址