分享常見的 Javascript 副程式,索引:
- 個案1:掛號網站驗證碼OCR結果錯誤的改善方法
- 個案2:自動登入帳密,並延遲按下送出按鈕
- 個案3:cityline 是否正在查詢座位
- 個案4:關鍵字比對需「全部符合」
- 個案5:用關鍵字移除不要的區塊內容
- 個案6:設定張數為指定張數或最大可以支援張數
個案1:掛號網站驗證碼OCR結果錯誤的改善方法
掛號網站站的驗證碼是 5位的數字,就是5個整數,部份的數字會誤判為英文,例如:數字 9 判斷為英文 g, 數字 0 判斷為英文 o,解法是先判斷驗證碼是否為正整數:
function isInteger(value) {
return /^-?\d+$/.test(value);
}
更多進階數字判斷:
https://stackoverflow.max-everyday.com/2024/03/javascript-isnumeric/
個案2:自動登入帳密,並延遲按下送出按鈕
let user_id = "your-account";
let user_password = "your-password";
let login_delay_interval = 3000;
$("#account_selector").val(user_id);
$("#password_selector").val(user_password);
setTimeout(() => {
$("#submit_selecotor").click();
}, login_delay_interval);
由於慢慢登入就可以了,所以增加了 setTimeout 進行延遲,操作起來會更像真的人。
個案3:cityline 是否正在查詢座位
const loadingoverlay = $(".loadingoverlay");
const loading_display = loadingoverlay.css("display");
let able_to_work = true;
if (loading_display && loading_display == "flex") {
able_to_work = false;
}
able_to_work == true, 就是可以按下訂位,反之就是正在查詢座位。
個案4:關鍵字比對需「全部符合」
當輸入的關鍵字使用了空格” “, 例如:”12/01 16:45″, 代表應該要同時符合”12/01” 而且也要出現 “16:45”
// AND logic
if (area_keyword.indexOf(" ") > 0) {
keyword_control_symbol = true;
const keyword_array = area_keyword.split(" ");
let contain = true;
for (var j = 0; j < keyword_array.length; j++) {
if (keyword_array[j] == "") continue;
if (html_text.indexOf(keyword_array[j]) == -1) {
contain = false;
break;
}
}
if (contain) {
// 全部都符合
}
}
個案5:用關鍵字移除不要的區塊內容
下面這幾行就可以把所有 div.ticket-unit 中不要的關鍵字的區塊,使用 .remove() 進行移除,當然也可以用 .hide() 藏起來就好了。
var exclude_keyword_array = ["輪椅", "身障", "身心障礙", "Restricted View", "Wheelchair", "燈柱遮蔽", "視線不完整"];
for (let i = 0; i < exclude_keyword_array.length; i++) {
$("#target_selector").each(function() {
let html_text = $(this).text();
if (html_text.indexOf(exclude_keyword_array[i]) > -1) {
$(this).remove();
}
});
}
個案6:設定張數為指定張數或最大可以支援張數
以下的範例是每 100ms 設定張數的 select tag 為指定的 option, 當無符合的 option 時,就讓最後一個 option 為選取狀態。在按下送出按鈕(#autoMode)之前,延遲 100ms 之後才觸發 button 的 click() 事件。
let ticket_number=2;
function ticketmaster_assign_ticket_number(ticket_number) {
let is_ticket_number_assign = false;
let ticket_options = $("#ticket_price_selector select:first option");
if (ticket_options.length > 1) {
const first_option = ticket_options.first();
if (ticket_number > 0 && first_option.prop('selected') && first_option.prop('value') == '0') {
ticket_options.each(function() {
if ($(this).val() == ticket_number) {
$(this).prop('selected', true);
is_ticket_number_assign = true;
return false;
}
});
if (!is_ticket_number_assign) {
ticket_options.last().prop('selected', true);
is_ticket_number_assign = true;
}
if (is_ticket_number_assign) {
// PS: click too fast will be detected.
setTimeout(() => {
$("#autoMode").click();
}, 100);
}
}
}
return is_ticket_number_assign;
}
setInterval(() =>
{
ticketmaster_assign_ticket_number(ticket_number);
}, 100);
第二種的寫法, 針對同一個畫面中還有多個價位的 select tag:
var ticket_number = 2;
var exclude_keyword_array = [];
var price_keyword_array = [];
function ticketmaster_ticketPriceList_clean_exclude(exclude_keyword_array) {
for (let i = 0; i < exclude_keyword_array.length; i++) {
$("#ticket_price_selector > tbody > tr").each(function() {
let html_text = $(this).text();
//console.log("html:"+html_text);
if (html_text.indexOf(exclude_keyword_array[i]) > -1) {
$(this).remove();
}
});
}
}
function ticketmaster_ticketPriceList_ticket_number(price_keyword_array, ticket_number) {
let is_ticket_number_assign = false;
let target_row = null;
let all_row = $("#ticket_price_selector > tbody > tr");
if (all_row.length > 0) {
if (all_row.length == 1) {
// single select.
target_row = all_row;
} else {
// multi select.
all_row.each(function() {
let is_match_keyword = false;
if (price_keyword_array.length) {
let html_text = $(this).text();
for (let i = 0; i < price_keyword_array.length; i++) {
if (price_keyword_array[i].indexOf(" ") > -1) {
// TODO: muti keywords with AND logic.
} else {
if (html_text.indexOf(price_keyword_array[i]) > -1) {
is_match_keyword = true;
target_row = $(this);
break;
}
}
}
} else {
if (all_row.index(this) == 0) {
is_match_keyword = true;
target_row = $(this);
}
}
//console.log("is_match_keyword:"+is_match_keyword);
if (is_match_keyword) {
return;
}
});
}
let ticket_options = target_row.find("option");
if (ticket_options.length) {
const first_option = ticket_options.first();
if (ticket_number > 0 && first_option.prop('selected') && first_option.prop('value') == '0') {
ticket_options.each(function() {
if ($(this).val() == ticket_number) {
$(this).prop('selected', true);
is_ticket_number_assign = true;
return false;
}
});
}
if (!is_ticket_number_assign) {
ticket_options.last().prop('selected', true);
}
}
}
return is_ticket_number_assign;
}
ticketmaster_ticketPriceList_clean_exclude(exclude_keyword_array);
ticketmaster_ticketPriceList_ticket_number(price_keyword_array, ticket_number);