地址https://www.wjx.cn/vm/tzzn4o3.aspx需將vm改成vj
1 // ==UserScript== 2 // @name 問卷星自動隨機答題 3 // @version 0.4 4 // @description 全自動填寫問卷星的問卷,支持自定義填空答案,平均兩三秒填寫一份問卷,可多開幾個標簽同時刷 5 // 已適配題型 6 // 表格 7 // - 單選 8 // - 多選 9 // 單選 10 // 多選 11 // 星星 12 // 下拉 13 // 拉條 14 // 填空 默認為空 15 // 排序 16 // 圖片 17 // @author ZainCheung 18 // @include https://www.wjx.cn/jq/*.aspx 19 // @include https://www.wjx.cn/vj/*.aspx 20 // @include https://www.wjx.cn/hj/*.aspx 21 // @include https://www.wjx.cn/wjx/join/complete.aspx* 22 // @grant none 23 // @namespace http://tampermonkey.net/ 24 // ==/UserScript== 25 26 (function() { 27 'use strict'; 28 29 // 配置填空的答案項,如果不配置,默認填無 30 var config = [ 31 { 32 id: 1,//第一題:您的性別? 33 answer: ["男","女"]//隨機選出一個答案 34 }, 35 { 36 id: 2,//第二題:您的年齡? 37 answer: ["25歲以下","25~35歲","35~50歲","50歲以上"] 38 }, 39 { 40 id:3,//第三題:您的職業? 41 answer: ["學生","上班族","個體戶","其他"] 42 }, 43 { 44 id: 4,//第四題:您旅游時會購買文創用品(旅游紀念品)嗎? 45 answer: ["會","不會"] 46 }, 47 { 48 id: 5,//第五題:您了解文創用品(旅游紀念品)嗎? 49 answer: ["了解","一般","聽說過","不了解"] 50 }, 51 { 52 id: 6,//第六題:您一般會花費多少錢購買文創用品? 53 answer: ["100元以下","100~200","200~300","300元以上"] 54 }, 55 { 56 id: 7,//第七題:您傾向於在哪里購買文創用品(旅游紀念品)?[多選題] 57 answer: ["文具店","禮品店","創意生活館","小商品市場","夜市等","淘寶等","其他"] 58 }, 59 { 60 id: 8,//第八題:影響您購買的主要因素? [ 多選題] 61 answer: ["實用性","外觀","創意","價格","潮流","其他"] 62 }, 63 { 64 id: 9,//第九題:您比較喜歡什么質感的文創用品(旅游紀念 品) ? [多選題] 65 answer: ["陶瓷","塑料木質","玻璃","布藝","其他"] 66 }, 67 { 68 id: 10,//第十題:您購買文創用品(旅游紀念品)重點考慮的因素 69 answer: ["價格","造型","功能","其他"] 70 } 71 ]; 72 73 74 75 //答題結束,則打開新的問卷 76 (function openNew() { 77 var currentURL = window.location.href; 78 var pat = /complete\.aspx\?activityid=(\d+)/; 79 var obj = pat.exec(currentURL); 80 if (obj) { 81 window.location.href = "https://www.wjx.cn/jq/" + obj[1] + ".aspx"; 82 } else { 83 console.log("not pat", obj); 84 } 85 })(); 86 87 88 var currentURL = window.location.href; 89 //自動轉為電腦網頁版 90 (function redirect() { 91 try { 92 var pat = /(https:\/\/www\.wjx\.cn\/)(jq|m)(.*)/g; 93 var obj = pat.exec(currentURL); 94 if (obj[2] == "m") { 95 console.log("redirect now"); 96 window.location.href = obj[1] + "jq" + obj[3]; 97 } else { 98 console.log("do!"); 99 } 100 } catch (error) {} 101 })(); 102 103 104 /** 105 * 106 * 107 * @param {int} min The minimum value in the range 108 * @param {int} max The maxmum value in the range 109 * @return {int} Return Returns a random number within this range (both include) 110 */ 111 function randint(min, max) { 112 return Math.floor(Math.random() * (max - min + 1) + min); 113 } 114 115 function getRandomArrayElements(arr, count) { 116 var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index; 117 while (i-- > min) { 118 index = Math.floor((i + 1) * Math.random()); 119 temp = shuffled[index]; 120 shuffled[index] = shuffled[i]; 121 shuffled[i] = temp; 122 } 123 return shuffled.slice(min); 124 } 125 126 127 /** 128 * @description 該函數用於自動選擇 129 */ 130 function RandomChoose() { 131 /** 132 * @name 普通單選題隨機選擇 133 * @param {object} subject single subject 134 */ 135 this.singleChoose = function(subject) { 136 if (subject.querySelectorAll("img")[0]) { //帶有圖片的,無法直接click 標簽<li> 137 var img = subject.querySelectorAll("img"); 138 img[randint(0, img.length - 1)].click(); 139 } else { 140 var list = subject.querySelectorAll("li"); 141 var no; 142 for(var i = 0; i < list.length; i++){ 143 if(list[i].querySelector(".underline") != null){ 144 no = i; 145 } 146 } 147 var index = randint(0, list.length - 1); 148 while(index == no){index = randint(0, list.length - 1);} 149 list[index].click(); 150 151 } 152 } 153 154 /**** 155 * @name 普遍多選題隨機選擇 156 * @param {object} subject single subject 157 * 158 */ 159 this.multiChoose = function(subject) { 160 var list = subject.querySelectorAll("li"); 161 var arr = new Array(); 162 for (var i = 0; i < list.length; i++) { 163 if (list[i].querySelectorAll("input")[0].checked == true) { 164 list[i].click(); 165 } 166 arr.push(list[i]); 167 } 168 var times = randint(3, arr.length - 1); // 多選題選擇數量,一般不小於3 169 var indexAry = getRandomArrayElements(arr, times);//准備選中的項 170 var no;//禁止項 171 for(var j = 0; j < indexAry.length; j++){ 172 if(indexAry[j].querySelector(".underline") != null){//去除多選框里需要填空的項 173 console.log(indexAry[j]); 174 no = j; 175 } 176 } 177 for (i = 0; i < indexAry.length; i++) { 178 if (indexAry[i].querySelectorAll("input")[0].checked == false && (i != no)) { 179 indexAry[i].click(); 180 } 181 } 182 // for (i = 0; i < times; i++) { 183 // var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0]; 184 // if (randomChoose.querySelectorAll("input")[0].checked == false) { 185 // randomChoose.click(); 186 // } 187 // } 188 } 189 190 191 192 //隨機排序題 193 this.randomSort = function(subject) { 194 var list = subject.querySelectorAll("li"); 195 var arr = new Array(); 196 for (var i = 0; i < list.length; i++) { 197 list[i].querySelectorAll("input")[0].checked = false; 198 list[i].querySelectorAll("span")[0].classList.remove("sortnum-sel"); //事實上這個只是一個樣式,真正選擇在於checkd = true || false 199 arr.push(list[i]); 200 } 201 for (i = 0; i < list.length; i++) { 202 var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0]; 203 randomChoose.querySelectorAll("input")[0].checked = true; 204 randomChoose.querySelectorAll("span")[0].classList.add("sortnum-sel"); 205 randomChoose.querySelectorAll("span")[0].innerHTML = i + 1; 206 } 207 } 208 209 //表格單選 210 this.martixSingleChoose = function(subject) { 211 var tr = subject.querySelectorAll("tbody > tr"); 212 for (var i = 0; i < tr.length; i++) { 213 var td = tr[i].querySelectorAll("td"); 214 td[randint(0, td.length - 1)].click(); 215 } 216 } 217 //表格多選 218 this.martixMultiChoose = function(subject) { 219 var tr = subject.querySelectorAll("tbody > tr"); 220 for (var i = 0; i < tr.length; i++) { 221 var td = tr[i].querySelectorAll("td"); 222 var arr = new Array(); 223 for (var j = 0; j < td.length; j++) { 224 td[j].querySelectorAll("input")[0].checked = false; 225 td[j].querySelectorAll("a")[0].classList.remove("jqChecked"); 226 arr.push(td[j]); 227 } 228 229 var times = randint(3, arr.length - 1); // 多選題選擇數量,一般不小於3 230 for (var k = 0; k < times; k++) { 231 var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0]; 232 randomChoose.querySelectorAll("input")[0].checked = true; 233 randomChoose.querySelectorAll("a")[0].classList.add("jqChecked"); 234 } 235 console.log(times); 236 } 237 } 238 this.martixStar = function(subject) { 239 var tr = subject.querySelectorAll("tbody > tr"); 240 for (var i = 0; i < tr.length; i++) { 241 var list = tr[i].querySelectorAll("li"); 242 var rnnum = randint(0, list.length - 1); 243 list[rnnum].click(); 244 console.log(i, rnnum); 245 } 246 } 247 248 this.dropdownSelect = function(subject) { 249 var select = subject.querySelectorAll("select")[0]; 250 var rnnum = randint(1, select.length - 1); 251 select.selectedIndex = rnnum; 252 } 253 254 this.singleSlider = function(subject) { 255 256 /** 257 * 258 * @param {int} _value 隨機值 259 * @param {*} min 可選的最小值 260 * @param {*} max 可選的最大值 261 * @param {*} subject 題目 262 * @description 里面的_coordsX, _Number, getElCoordinate, 方法不用管,這是根據網頁的方法復制下來的, 用來反模擬出clientX的值(即鼠標的值), 因為網頁上沒有提供js直接修改的value,因此只能模擬鼠標時間來點擊拉條,需要參數clientX。 263 * 264 */ 265 function getClientX(_value, min, max, subject) { 266 var _bar = subject.querySelectorAll(".imageBar1")[0]; 267 var _slider = subject.querySelectorAll(".imageSlider1")[0] 268 269 function _coordsX(x) { 270 x = _Number(x); 271 x = x <= _slider.offsetLeft ? _slider.offsetLeft : x >= _slider.offsetLeft + _slider.offsetWidth - _bar.offsetWidth ? _slider.offsetLeft + _slider.offsetWidth - _bar.offsetWidth : x; 272 return x; 273 } 274 275 function _Number(b) { 276 return isNaN(b) ? 0 : b; 277 } 278 279 function getElCoordinate(h) { 280 var e = h.offsetLeft; 281 while (h = h.offsetParent) { 282 e += h.offsetLeft; 283 } 284 return { 285 left: e, 286 }; 287 } 288 289 var x = (_value - min) * ((_slider.offsetWidth - _bar.offsetWidth) / (max - min)); 290 x = _coordsX(x); 291 var clientX = x + getElCoordinate(_slider).left + (_bar.offsetWidth / 2); 292 return Math.round(clientX); 293 } 294 295 var max = Number(subject.querySelectorAll(".slider")[0].getAttribute("maxvalue")); 296 var min = Number(subject.querySelectorAll(".slider")[0].getAttribute("minvalue")); 297 //模擬鼠標點擊的事件, 關鍵參數ClientX 298 var evt = new MouseEvent("click", { 299 clientX: getClientX(randint(min, max), min, max, subject), 300 type: "click", 301 __proto__: MouseEvent, 302 }); 303 subject.querySelectorAll(".ruler")[0].dispatchEvent(evt); 304 } 305 this.singleStar = function(subject) { 306 var list = subject.querySelectorAll("li:not([class='notchoice'])"); 307 list[randint(0, list.length - 1)].click(); 308 } 309 } 310 311 312 /** 313 * @name 智慧樹題目類型判斷,並隨機選擇 314 */ 315 function judgeType() { 316 //q = $$(".div_question"); 317 var q = document.getElementsByClassName("div_question"); 318 var rc = new RandomChoose(); 319 for (var i = 0; i < q.length; i++) { 320 //普通單選 or 多選 321 if ((q[i].querySelectorAll(".ulradiocheck")[0]) && (q[i].querySelectorAll("input")[0])) { // 非表格單選或者多選 322 var input = q[i].querySelectorAll("input"); 323 if (input[0].type == 'radio') { 324 console.log("單選題", i); 325 rc.singleChoose(q[i]); 326 } else if (input[0].type == 'checkbox') { 327 console.log("多選題", i); 328 rc.multiChoose(q[i]); 329 } 330 331 //表格 332 } else if (q[i].querySelectorAll("table")[0]) { 333 if (q[i].querySelectorAll("input")[0]) { // 表格題中包含有單選, 多選 334 input = q[i].querySelectorAll("input"); 335 if (input[0].type == 'radio') { 336 console.log("表格單選", i); 337 rc.martixSingleChoose(q[i]); 338 } else if (input[0].type == 'checkbox') { 339 console.log("表格多選", i); 340 rc.martixMultiChoose(q[i]); 341 } 342 } else if (!q[i].querySelectorAll("input")[0] && q[i].querySelectorAll("li")[0]) { // 表格中的星星題目,沒有Input標簽 343 console.log("Martix-Star", i); 344 rc.martixStar(q[i]); 345 } 346 // 填空題 347 } else if (q[i].querySelectorAll("textarea")[0]) { 348 for(var j = 0; j < config.length; j++){ 349 if(q[i].querySelectorAll("textarea")[0].id == ("q" + config[j].id)){ 350 q[i].querySelectorAll("textarea")[0].value = config[j].answer[Math.floor(Math.random()*config[j].answer.length)]; 351 } 352 } 353 354 console.log("填空", i); 355 } else if (q[i].querySelectorAll(".slider")[0]) { 356 console.log("Slider-Single-line", i); 357 rc.singleSlider(q[i]); 358 } else if (q[i].querySelectorAll(".notchoice")[0]) { 359 console.log("Star-Single-line", i); 360 rc.singleStar(q[i]); 361 } else if (q[i].querySelectorAll(".lisort")[0]) { 362 console.log("li-Sort", i); 363 rc.randomSort(q[i]); 364 } else if (q[i].querySelectorAll("select")[0]) { 365 console.log("Select", i); 366 rc.dropdownSelect(q[i]); 367 } 368 } 369 try{ 370 var textArea = document.getElementsByTagName('textarea'); 371 //textArea[0].value = "無"; 372 //textArea[1].value = "無"; 373 }catch(error){} 374 } 375 judgeType(); 376 377 //滾動到提交按鈕處 378 try { 379 var scrollvalue = document.getElementById("submit_button").offsetParent.offsetParent.offsetTop; 380 window.scrollTo({ 381 top: scrollvalue, 382 behavior: "smooth" 383 }); 384 } catch (error) {} 385 386 })(); 387 window.alert = function(str) { 388 location.reload(); 389 return ; 390 } 391 setTimeout(function(){ 392 // 延時兩秒防止驗證 393 document.getElementById("submit_button").click(); 394 console.log("答題成功!"); 395 },2000); 396 setTimeout(function(){ 397 // 5秒自動刷新,解決驗證問題 398 location.reload(); 399 },5000);