1/** 2 * 微信/QQå ç½®æµè§å¨æ¦æªå¼¹çª 3 * èªå¨æ£æµç¯å¢ï¼è¥å¨å¾®ä¿¡æQQå ç½®æµè§å¨ä¸ï¼åæ¾ç¤ºå ¨å±é®ç½©ï¼å¼å¯¼ç¨æ·å¤å¶é¾æ¥æä½¿ç¨æµè§å¨æå¼ã 4 * ç¨æ³ï¼å¨HTMLä¸å¼å ¥ <script src="wechat-qq-blocker.js"></script> å³å¯ï¼æ éå ¶ä»æä½ã 5 */ 6(function() { 7 'use strict'; 8 9 // ---------- é ç½®ï¼å¯æéä¿®æ¹ï¼ ---------- 10 var CONFIG = { 11 title: '温馨æç¤º', 12 description: 'æ£æµå°æ¨å¨ <strong>微信</strong> æ <strong>QQ</strong> å ç½®æµè§å¨ä¸æå¼ï¼é¨ååè½å¯è½åéã', 13 guideSteps: [ 14 'ç¹å»å³ä¸è§ <span class="menu-icon">···</span> èåï¼éæ©ã卿µè§å¨ä¸æå¼ã', 15 'æ <strong>ç¹å»ä¸æ¹æé®</strong> å¤å¶é¾æ¥ï¼æå¨æå¼æµè§å¨ç²è´´è®¿é®' 16 ], 17 copyButtonText: 'ð å¤å¶ç½é¡µé¾æ¥', 18 copyButtonSub: 'ç¹å»å³å¯å¤å¶', 19 toastSuccess: 'â 龿¥å·²å¤å¶ï¼è¯·å徿µè§å¨æå¼', 20 toastError: 'â ï¸ å¤å¶å¤±è´¥ï¼è¯·æå¨å¤å¶é¾æ¥', 21 // å¤å¶æååçåè°ï¼å¯éï¼ 22 onCopy: null 23 }; 24 25 // ---------- æ£æµç¯å¢ ---------- 26 function isWechatOrQQ() { 27 var ua = navigator.userAgent.toLowerCase(); 28 return ua.indexOf('micromessenger') !== -1 || 29 ua.indexOf('qq/') !== -1 || 30 ua.indexOf('mqqbrowser') !== -1; 31 } 32 33 // è¥ä¸å¨å¾®ä¿¡/QQä¸ï¼ç´æ¥éåº 34 if (!isWechatOrQQ()) { 35 return; 36 } 37 38 // ---------- é¿å é夿³¨å ¥ ---------- 39 if (document.getElementById('wechat-qq-blocker-overlay')) { 40 return; 41 } 42 43 // ---------- åå»ºæ ·å¼ ---------- 44 var style = document.createElement('style'); 45 style.id = 'wechat-qq-blocker-style'; 46 style.textContent = ` 47 /* é®ç½©å± */ 48 #wechat-qq-blocker-overlay { 49 position: fixed; 50 top: 0; 51 left: 0; 52 width: 100vw; 53 height: 100vh; 54 background: rgba(0, 0, 0, 0.72); 55 z-index: 999999; 56 display: flex; 57 justify-content: center; 58 align-items: center; 59 overflow: hidden; 60 pointer-events: auto; 61 touch-action: none; 62 animation: wqb-overlay-fade-in 0.35s ease-out; 63 } 64 @keyframes wqb-overlay-fade-in { 65 0% { opacity: 0; } 66 100% { opacity: 1; } 67 } 68 69 /* å¼¹çªå¡ç */ 70 #wechat-qq-blocker-modal { 71 position: relative; 72 width: 88%; 73 max-width: 380px; 74 background: #ffffff; 75 border-radius: 20px; 76 padding: 32px 26px 28px; 77 box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45); 78 text-align: center; 79 pointer-events: auto; 80 touch-action: auto; 81 user-select: text; 82 -webkit-user-select: text; 83 animation: wqb-modal-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); 84 } 85 @keyframes wqb-modal-pop { 86 0% { transform: scale(0.85) translateY(30px); opacity: 0; } 87 100% { transform: scale(1) translateY(0); opacity: 1; } 88 } 89 90 #wechat-qq-blocker-modal .wqb-icon { 91 display: inline-block; 92 width: 56px; 93 height: 56px; 94 background: #ff6b35; 95 border-radius: 50%; 96 color: #fff; 97 font-size: 30px; 98 line-height: 56px; 99 text-align: center; 100 font-weight: 700; 101 margin-bottom: 14px; 102 box-shadow: 0 6px 20px rgba(255, 107, 53, 0.35); 103 } 104 #wechat-qq-blocker-modal h2 { 105 font-size: 22px; 106 font-weight: 700; 107 color: #1a1a2e; 108 margin-bottom: 10px; 109 letter-spacing: 0.5px; 110 } 111 #wechat-qq-blocker-modal .wqb-desc { 112 font-size: 15px; 113 line-height: 1.7; 114 color: #3d3d4e; 115 margin-bottom: 18px; 116 padding: 0 4px; 117 } 118 #wechat-qq-blocker-modal .wqb-desc strong { 119 color: #e84118; 120 font-weight: 600; 121 } 122 123 #wechat-qq-blocker-modal .wqb-guide { 124 background: #f8f9fc; 125 border-radius: 12px; 126 padding: 14px 16px; 127 margin: 12px 0 20px; 128 text-align: left; 129 font-size: 14px; 130 color: #2d3436; 131 border-left: 4px solid #ff6b35; 132 } 133 #wechat-qq-blocker-modal .wqb-guide .wqb-step { 134 display: flex; 135 align-items: flex-start; 136 gap: 10px; 137 padding: 4px 0; 138 } 139 #wechat-qq-blocker-modal .wqb-guide .wqb-step .wqb-num { 140 display: inline-flex; 141 justify-content: center; 142 align-items: center; 143 width: 22px; 144 height: 22px; 145 background: #ff6b35; 146 color: #fff; 147 border-radius: 50%; 148 font-size: 12px; 149 font-weight: 700; 150 flex-shrink: 0;
151 margin-top: 1px; 152 } 153 #wechat-qq-blocker-modal .wqb-guide .wqb-step .wqb-text { 154 line-height: 1.6; 155 } 156 #wechat-qq-blocker-modal .wqb-guide .wqb-step .wqb-text .menu-icon { 157 display: inline-block; 158 background: #e0e4ea; 159 padding: 0 10px; 160 border-radius: 4px; 161 font-size: 13px; 162 font-weight: 500; 163 color: #2d3436; 164 } 165 166 #wechat-qq-blocker-modal .wqb-copy-area { 167 margin-top: 8px; 168 padding: 12px 0 4px; 169 border-top: 1px dashed #e0e4ea; 170 } 171 #wechat-qq-blocker-modal .wqb-copy-btn { 172 display: inline-block; 173 width: 100%; 174 padding: 14px 0; 175 background: linear-gradient(135deg, #ff6b35, #f53b2c); 176 color: #fff; 177 font-size: 18px; 178 font-weight: 700; 179 border: none; 180 border-radius: 14px; 181 cursor: pointer; 182 letter-spacing: 1px; 183 box-shadow: 0 6px 24px rgba(255, 107, 53, 0.38); 184 transition: all 0.2s ease; 185 touch-action: manipulation; 186 -webkit-tap-highlight-color: transparent; 187 } 188 #wechat-qq-blocker-modal .wqb-copy-btn:active { 189 transform: scale(0.96); 190 box-shadow: 0 3px 12px rgba(255, 107, 53, 0.25); 191 } 192 #wechat-qq-blocker-modal .wqb-copy-btn .wqb-sub { 193 display: block; 194 font-size: 13px; 195 font-weight: 400; 196 opacity: 0.85; 197 margin-top: 2px; 198 letter-spacing: 0.3px; 199 } 200 #wechat-qq-blocker-modal .wqb-footer-tip { 201 margin-top: 14px; 202 font-size: 12px; 203 color: #999; 204 letter-spacing: 0.3px; 205 } 206 207 /* Toast */ 208 #wechat-qq-blocker-toast { 209 position: fixed; 210 bottom: 15%; 211 left: 50%; 212 transform: translateX(-50%) scale(0.9); 213 background: rgba(0, 0, 0, 0.78); 214 color: #fff; 215 padding: 14px 32px; 216 border-radius: 12px; 217 font-size: 16px; 218 font-weight: 500; 219 z-index: 1000000; 220 opacity: 0; 221 transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); 222 pointer-events: none; 223 backdrop-filter: blur(4px); 224 -webkit-backdrop-filter: blur(4px); 225 white-space: nowrap; 226 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35); 227 } 228 #wechat-qq-blocker-toast.wqb-show { 229 opacity: 1; 230 transform: translateX(-50%) scale(1); 231 } 232 233 /* ååºå¼ */ 234 @media (max-width: 420px) { 235 #wechat-qq-blocker-modal { 236 padding: 24px 18px 22px; 237 width: 92%; 238 } 239 #wechat-qq-blocker-modal h2 { 240 font-size: 20px; 241 } 242 #wechat-qq-blocker-modal .wqb-desc { 243 font-size: 14px; 244 } 245 #wechat-qq-blocker-modal .wqb-copy-btn { 246 font-size: 17px; 247 padding: 13px 0; 248 } 249 #wechat-qq-blocker-modal .wqb-guide { 250 font-size: 13px; 251 padding: 12px 14px; 252 } 253 #wechat-qq-blocker-modal .wqb-icon { 254 width: 48px; 255 height: 48px; 256 font-size: 26px; 257 line-height: 48px; 258 } 259 } 260 @media (max-width: 350px) { 261 #wechat-qq-blocker-modal { 262 padding: 18px 14px 18px; 263 } 264 #wechat-qq-blocker-modal h2 { 265 font-size: 17px; 266 } 267 #wechat-qq-blocker-modal .wqb-desc { 268 font-size: 13px; 269 } 270 #wechat-qq-blocker-modal .wqb-copy-btn { 271 font-size: 15px; 272 padding: 11px 0; 273 } 274 } 275 `; 276 document.head.appendChild(style); 277 278 // ---------- å建 HTML ç»æ ---------- 279 var overlay = document.createElement('div'); 280 overlay.id = 'wechat-qq-blocker-overlay'; 281 282 // æå»ºå¼å¯¼æ¥éª¤ 283 var stepsHtml = CONFIG.guideSteps.map(function(step, index) { 284 return '<div class="wqb-step"><span class="wqb-num">' + (index + 1) + '</span><span class="wqb-text">' + step + '</span></div>'; 285 }).join(''); 286 287 overlay.innerHTML = ` 288 <div id="wechat-qq-blocker-modal"> 289 <div class="wqb-icon">â </div> 290 <h2>${CONFIG.title}</h2> 291 <p class="wqb-desc">${CONFIG.description}</p> 292 <div class="wqb-guide">${stepsHtml}</div> 293 <div class="wqb-copy-area" id="wqb-copy-trigger"> 294 <button class="wqb-copy-btn" id="wqb-copy-btn"> 295 ${CONFIG.copyButtonText}
296 <span class="wqb-sub">${CONFIG.copyButtonSub}</span> 297 </button> 298 </div> 299 <p class="wqb-footer-tip">â ç¹å»æé®æå±å¹ä»»æä½ç½®åå¯å¤å¶ â</p> 300 </div> 301 `; 302 303 document.body.appendChild(overlay); 304 305 // ---------- Toast å ç´ ---------- 306 var toast = document.createElement('div'); 307 toast.id = 'wechat-qq-blocker-toast'; 308 document.body.appendChild(toast); 309 310 // ---------- éå®é¡µé¢ ---------- 311 document.body.style.overflow = 'hidden'; 312 document.body.style.position = 'fixed'; 313 document.body.style.width = '100%'; 314 document.body.style.height = '100%'; 315 document.body.style.webkitOverflowScrolling = 'none'; 316 317 // ---------- 黿¢é®ç½©ä¸çæ»å¨åäºä»¶ ---------- 318 overlay.addEventListener('touchmove', function(e) { 319 e.preventDefault(); 320 }, { passive: false }); 321 overlay.addEventListener('wheel', function(e) { 322 e.preventDefault(); 323 }, { passive: false }); 324 325 document.addEventListener('keydown', function(e) { 326 if (e.key === 'Escape' || e.key === 'Esc') { 327 e.preventDefault(); 328 e.stopPropagation(); 329 } 330 }, true); 331 document.addEventListener('contextmenu', function(e) { 332 e.preventDefault(); 333 }, true); 334 335 // ---------- å¤å¶åè½ ---------- 336 var currentUrl = window.location.href; 337 var toastTimer = null; 338 339 function showToast(msg, isError) { 340 toast.textContent = msg; 341 toast.style.background = isError ? 'rgba(200,50,50,0.88)' : 'rgba(0,0,0,0.78)'; 342 toast.classList.add('wqb-show'); 343 if (toastTimer) clearTimeout(toastTimer); 344 toastTimer = setTimeout(function() { 345 toast.classList.remove('wqb-show'); 346 }, 2200); 347 } 348 349 function copyLink() { 350 if (navigator.clipboard && navigator.clipboard.writeText) { 351 navigator.clipboard.writeText(currentUrl).then(function() { 352 showToast(CONFIG.toastSuccess); 353 if (typeof CONFIG.onCopy === 'function') CONFIG.onCopy(true); 354 }).catch(function() { 355 fallbackCopy(currentUrl); 356 }); 357 } else { 358 fallbackCopy(currentUrl); 359 } 360 } 361 362 function fallbackCopy(text) { 363 var textarea = document.createElement('textarea'); 364 textarea.value = text; 365 textarea.style.position = 'fixed'; 366 textarea.style.opacity = '0'; 367 textarea.style.left = '-9999px'; 368 textarea.style.top = '-9999px'; 369 document.body.appendChild(textarea); 370 textarea.select(); 371 try { 372 var success = document.execCommand('copy'); 373 if (success) { 374 showToast(CONFIG.toastSuccess); 375 if (typeof CONFIG.onCopy === 'function') CONFIG.onCopy(true); 376 } else { 377 showToast(CONFIG.toastError, true); 378 if (typeof CONFIG.onCopy === 'function') CONFIG.onCopy(false); 379 } 380 } catch (e) { 381 showToast(CONFIG.toastError, true); 382 if (typeof CONFIG.onCopy === 'function') CONFIG.onCopy(false); 383 } 384 document.body.removeChild(textarea); 385 } 386 387 // ---------- ç»å®äºä»¶ ---------- 388 var modal = document.getElementById('wechat-qq-blocker-modal'); 389 var copyBtn = document.getElementById('wqb-copy-btn'); 390 var copyTrigger = document.getElementById('wqb-copy-trigger'); 391 392 // ç¹å»å¤å¶æé® 393 copyBtn.addEventListener('click', function(e) { 394 e.stopPropagation(); 395 copyLink(); 396 }); 397 398 // ç¹å»å¤å¶åºå 399 copyTrigger.addEventListener('click', function(e) { 400 e.stopPropagation(); 401 copyLink(); 402 }); 403 404 // ç¹å»å¼¹çªå¡çï¼é¤æé®/åºåå¤ï¼ 405 modal.addEventListener('click', function(e) { 406 if (e.target.closest('#wqb-copy-btn') || e.target.closest('#wqb-copy-trigger')) { 407 return; 408 } 409 copyLink(); 410 }); 411 412 // ç¹å»é®ç½©èæ¯ 413 overlay.addEventListener('click', function(e) { 414 if (e.target.closest('#wechat-qq-blocker-modal')) { 415 return; 416 } 417 copyLink(); 418 }); 419 420 // 黿¢äºä»¶å泡å°ä¸å± 421 overlay.addEventListener('click', function(e) { 422 if (e.target.closest('#wechat-qq-blocker-modal')) { 423 return; 424 } 425 e.stopPropagation(); 426 }, true); 427 428 overlay.addEventListener('touchstart', function(e) { 429 if (e.target.closest('#wechat-qq-blocker-modal')) { 430 return; 431 } 432 e.preventDefault(); 433 e.stopPropagation(); 434 }, { passive: false }); 435 436 // å è®¸ç¨æ·é ç½®æ©å±ï¼æ´é²å ¨å±å¯¹è±¡ï¼ 437 window.WechatQQBlocker = { 438 config: CONFIG, 439 // 坿å¨è°ç¨å¤å¶ 440 copyLink: copyLink, 441 // 坿´æ°é ç½®ï¼ééæ°çæï¼ä½ç®åèµ·è§ï¼åªæ´é²ï¼ 442 updateConfig: function(newConfig) { 443 Object.assign(CONFIG, newConfig); 444 } 445 }; 446 447 console.log('[WechatQQBlocker] å·²æ¦æªå¾®ä¿¡/QQå ç½®æµè§å¨ï¼å¼¹çªå·²å¯å¨ã'); 448 449})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.