內(nèi)容是《Web前端開發(fā)之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學(xué)習(xí)。
按鈕Button:
按鈕是最常用的表單元素之一,有兩種形式的按鈕,button按鈕和radio單選、checkbox復(fù)選按鈕;
提交和重置元素本身就是按鈕,并且有相關(guān)聯(lián)的默認(rèn)動作,如果其click事件處理程序返回false,也就取消它的默認(rèn)行為了;也可以使用它們的click事件來執(zhí)行表單的驗證及提交,但最為常用的還是使用form對象本身的submit事件進行驗證和提交;
普通按鈕是沒有默認(rèn)行為的,一般來說使用它們來執(zhí)行自定義腳本,當(dāng)然也可以用它來執(zhí)行form.submit()方法來提交表單;
對于type為”submit”或type=”image”的按鈕,HTML5新增了formaction、formmethod、formenctype、formtarget屬性,其中formaction屬性用于覆蓋form的 action屬性,作用是為不同的提交按鈕增加formaction屬性,使得在單擊時可以將表單提交給不同的頁面;formmethod屬性為每個不同的提交按鈕分別指定不同的提交方法;formenctype屬性為每個不同的提交按鈕分別指定不同的編碼方式;formtarget屬性用于為每個不同的提交按鈕指定在何處打開提交頁面;這些屬性在Javascript中都有相對應(yīng)的同名屬性,如:
<form action="demo.php">
<input type="submit" formaction="center/" formmethod="GET" formtarget="_blank" formenctype="multipart/form-data" value="用戶中心" />
<input type="submit" formaction="admin/" formmethod="POST" formaction="_self" formenctype="application/x-www-form-urlencoded" value="后臺管理" />
</form>
<script>
var btnSubmit = document.forms[0].elements[0];
console.log(btnSubmit.formAction);
console.log(btnSubmit.formMethod);
console.log(btnSubmit.formTarget);
console.log(btnSubmit.formEnctype);
</script>
radio單選和checkbox復(fù)選按鈕(框)是開關(guān)按鈕,其只有兩種狀態(tài):選中或未選中;
<form id="myForm" name="myForm">
<p>性別:
<input type="radio" name="sex" id="male" value="1" />男
<input type="radio" name="sex" id="remale" value="0" checked />女
</p>
<p>課程:
HTML<input type="checkbox" name="course" id="c1" value="HTML" />
CSS<input type="checkbox" name="course" id="c2" value="CSS" checked />
JavaScript<input type="checkbox" name="course" id="c3" value="JavaScript" />
</p>
</form>
<script>
var male = document.getElementById("male");
console.log(male); // <input>
male = document.forms["myForm"].elements["male"];
console.log(male); // <input>
</script>
單選和復(fù)選按鈕都定義了checked屬性,該屬性為可讀寫的布爾值;defaultChecked屬性對應(yīng)的是HTML的checked屬性,也是布爾值,它指定了元素在第一次加載頁面時是否選中;
var male = document.forms["myForm"].elements["male"];
var remale = document.forms["myForm"].elements["remale"];
console.log(male.checked); // false
console.log(male.defaultChecked); // false
console.log(remale.checked); // true
console.log(remale.defaultChecked); // true
male.checked = true;
console.log(male.checked); // true
console.log(male.defaultChecked); // false
console.log(remale.checked); // false
console.log(remale.defaultChecked); // true
male.defaultChecked = true;
console.log(male.checked); // true
console.log(male.defaultChecked); // true
console.log(remale.checked); // false
console.log(remale.defaultChecked); // true
checked會令一個單選按鈕組中所有元素互斥,defaultChecked也是可寫的(W3C定義其是只讀的,所以寫入的操作是不規(guī)范的),但它不是互斥的;所以可以利用這兩個屬性把單選按鈕恢復(fù)到默認(rèn)的狀態(tài),如:
male.checked = true;
male.checked = male.defaultChecked;
remale.checked = remale.defaultChecked;
對于復(fù)選框,也是類似的,但其checked不是互斥的,因為它本身就允許多選;
例如:復(fù)位單選和復(fù)選狀態(tài);
<p><input type="button" value="重置單選和復(fù)選" id="resetRadioCheckbox" /></p>
<script>
var resetRadioCheckbox = document.getElementById("resetRadioCheckbox");
resetRadioCheckbox.onclick = function(){
// var radioList = document.querySelectorAll('input[type="radio"]');
var radioList = document.getElementsByName("sex"); // 也可以
console.log(radioList);
for(var i=0,len=radioList.length; i<len; i++)
radioList[i].checked = radioList[i].defaultChecked;
var checkList = document.getElementsByName("course");
for(var i=0,len=checkList.length; i<len; i++)
checkList[i].checked = checkList[i].defaultChecked;
}
</script>
單選和復(fù)選按鈕本身并不顯示任何文本,它們通常和相鄰的HTML文本一起顯示或與<label>元素相關(guān)聯(lián),所以其value屬性并不顯示出來,而只是為了提交給服務(wù)端;
var radioList = document.getElementsByName("sex");
for(var i=0,len=radioList.length; i<len; i++){
if(radioList[i].checked)
console.log("被選中的值是:" + radioList[i].value);
}
var checkList = document.getElementsByName("course");
var checkStr = "";
for(var i=0,len=checkList.length; i<len; i++){
if(checkList[i].checked)
checkStr += checkList[i].value + ",";
}
if(checkStr != "")
checkStr = checkStr.substring(0,checkStr.length - 1);
else
checkStr = "無";
console.log("被選中的值是:" + checkStr);
同時,也會根據(jù)獲取來的值來設(shè)置單選或復(fù)選按鈕的選中狀態(tài),如:
window.onload = function(){
var sexValue = 1; // 從服務(wù)端獲取
var radioList = document.getElementsByName("sex");
for(var i=0,len=radioList.length; i<len; i++){
if(radioList[i].value == sexValue){
radioList[i].checked = true;
break;
}
}
var courseValue = "JavaScript,HTML"; // 從服務(wù)端獲取
var arrCourse = courseValue.split(",");
var checkList = document.getElementsByName("course");
for(var i=0,len=checkList.length; i<len; i++){
// if(arrCourse.indexOf(checkList[i].value) >= 0) // 或者
if(arrCourse.includes(checkList[i].value))
checkList[i].checked = true;
else
checkList[i].checked = false;
}
}
其往往成組并使用共享的name,如果使用共享的name獲取這些元素時,返回是一個類數(shù)組而不是單個元素;
<script>
var sex = document.getElementsByName("sex");
console.log(sex); // NodeList
var sex = document.forms["myForm"].elements["sex"];
console.log(sex); // RadioNodeList
</script>
使用elements集合,返回的類型是更具體的RadioNodeList,該類型擁有一個value屬性,返回單選按鈕組中選中的value值;該屬性是可讀寫的,在設(shè)置value屬性時,value屬性等于值的第一個單選按鈕元素將被設(shè)置為checked,如:
console.log(sex.value); // 0
sex.value = "1"; // 男就被選中的
console.log(sex.value);
radio單選按鈕的本意就是在一組單選按鈕組中只能選擇唯一一個,如果只有一個radio按鈕,是沒有多大實際意義的;即使如此,如果使用elements屬性,其返回的就不是NodeList,而是單個元素對象;
<p><input type="radio" id="single" name="single" value="單個按鈕" /></p>
</form>
<script>
var single = document.forms[0].elements["single"];
console.log(single); // <input>
single.checked = true;
console.log(single.checked);
console.log(single.defaultChecked);
console.log(single.value); // 單個按鈕
</script>
在獲取checkbox時,如:
var courses = document.getElementsByName("course");
console.log(courses); // NodeList<input>
var courses = document.forms["myForm"].elements["course"];
console.log(courses); // RadioNodeList<input>
雖然當(dāng)前為checkbox組,并不是radio組,但返回的也是RadioNodeList,并不是類似的CheckboxNodeList類型,而且也不存在這個類型;
其返回的RadioNodeList集合的value屬性無用;獲取所有選中復(fù)選按鈕的值,可以遍歷所有被選中的選項;
當(dāng)單擊單選或復(fù)選按鈕時,會觸發(fā)onclick事件,如果單擊時改變了開關(guān)按鈕的狀態(tài),也會觸發(fā)change事件;
var sexList = document.forms[0].elements["sex"];
for(var i=0,len=sexList.length; i<len; i++){
var sex = sexList[i];
sex.addEventListener("change", function(event){
console.log(event.target.checked);
console.log(event.target.defaultChecked);
});
}
var courseList = document.forms[0].elements["course"];
var log = document.getElementById("log");
var arrCourse = [];
for(var i=0,len=courseList.length; i<len; i++){
if(courseList[i].checked)
arrCourse.push(courseList[i].value);
}
console.log(arrCourse.join());
log.innerText = arrCourse.join();
for(var i=0,len=courseList.length; i<len; i++){
var course = courseList[i];
course.addEventListener("change", function(event){
if (event.target.checked) {
arrCourse.push(event.target.value);
}else{
arrCourse.splice(arrCourse.indexOf(event.target.value),1);
}
console.log(arrCourse.join());
log.innerText = arrCourse.join();
},false);
}
示例:全選:
<p>
HTML<input type="checkbox" name="course" value="HTML" />
CSS<input type="checkbox" name="course" value="CSS" />
JavaScript<input type="checkbox" name="course" value="JavaScript" />
</p>
<p><button id="all">全選</button>
<button id="not">全不選</button>
<button id="reverse">反選</button></p>
<script>
var chkBoxs = document.getElementsByName("course");
// 全選
var all = document.getElementById("all");
all.onclick = function(){
for(var i=0; i<chkBoxs.length; i++){
chkBoxs[i].checked = true;
}
}
// 全不選
var not = document.getElementById("not");
not.onclick = function(){
for(var i=0; i<chkBoxs.length; i++){
chkBoxs[i].checked = false;
}
}
// 反選
var reverse = document.getElementById("reverse");
reverse.onclick = function(){
for(var i=0; i<chkBoxs.length; i++){
chkBoxs[i].checked = !chkBoxs[i].checked;
}
}
</script>
示例:同意提交
<div id="content">
<p>Lorem ...</p>
</div>
<p><label>同意此協(xié)議</label><input type="checkbox" id="cbAgree" disabled /></p>
<input type="submit" value="提交" id="btnSubmit" disabled />
<script>
window.onload = function(){
var cbAgree = document.getElementById("cbAgree");
var btnSubmit = document.getElementById("btnSubmit");
var s = 5;
var timer = setInterval(function(){
btnSubmit.value = "等待" + s + "秒";
if(--s < 0){
clearInterval(timer);
btnSubmit.value = "提交";
cbAgree.disabled = false;
}
},1000);
cbAgree.addEventListener("change", function(event){
btnSubmit.disabled = !cbAgree.checked;
},false);
}
</script>
Label標(biāo)簽元素:
其與其它表單元素關(guān)聯(lián),關(guān)聯(lián)的方式有兩種:一是使用for屬性,二是將<input>直接嵌套在<label>中,在這種情況下,不需要for和id屬性,因為關(guān)聯(lián)是隱式的;
表單的elements集合中并不包括Lable;
Label屬性:
var label = document.getElementsByTagName("label")[1];
console.log(label);
console.log(label.form);
console.log(label.control);
console.log(label.htmlFor);
label.htmlFor = "c2";
console.log(label.control); // checkbox
console.log(label.htmlFor); // c2
表單元素的labels屬性:只讀,返回表單元素關(guān)聯(lián)的所有<label>元素的NodeList,如:
<p><label for="content">內(nèi)容:</label><br/>
<textarea id="content" name="content"></textarea><br/>
<label for="content">請輸入簡要的內(nèi)容</label></p>
</form>
<script>
var content = document.forms["myForm"].elements["content"];
console.log(content.labels); // NodeList(2)
var label = content.labels[0];
console.log(label); // label
console.log(label.textContent); // 內(nèi)容:
console.log(label.form); // <form>
console.log(label.control); // textarea#content
console.log(label.htmlFor); // content
</script>
select選擇框:
選擇框是通過<select>和<option>元素創(chuàng)建的,其屬于HTMLSelectElement類型,瀏覽器通常將其渲染為下拉菜單的形式或設(shè)置其size屬性大于1呈現(xiàn)為列表的形式;
<form id="myForm" name="myForm">
<select name="province" id="province">
<option value="beijing" label="大北京">北京</option>
<option>安徽</option>
<option value="jiangsu">江蘇</option>
<option value="guangdong">廣東</option>
<option value="shangdong">山東</option>
</select>
</form>
其擁有除了所有表單元素共有的屬性和方法外,還提供了:
var province = document.forms[0].elements["province"];
console.log(province.options); // HTMLOptionsCollection
該集合擁有l(wèi)ength、selectedIndex屬性和add()及remove()方法;其中selectedIndex返回的是選中項的索引;通過options的索引可以返回一個option對象;
console.log(province.options.selectedIndex); // 2
console.log(province.selectedIndex); // 2
console.log(province.options[1]); // <option>
通過select對象的item(index)方法或select的索引也可以返回一個option對象;
var opt = selectbox.item(1);
var opt = selectbox[1];
console.log(opt);
console.log(opt.index);
console.log(opt.text);
每個<option>元素屬于HTMLOptionElement類型,該類型繼承自成 HTMLElement,其擁有下列屬性:
設(shè)置這些屬性的目的,是為了方便對選項數(shù)據(jù)的訪問,雖然可以使用常規(guī)的DOM功能來訪問這些信息,但效率比較低:
var province = document.forms[0].elements["province"];
// 不推薦
// var text = province.options[0].firstChild.nodeValue;
var text = province.options[0].textContent; // 或
var value = province.options[0].getAttribute("value");
console.log(text, value);
// 推薦
var text = province.options[0].text;
var value = province.options[0].value;
console.log(text, value);
console.log(province.options[0].index);
console.log(province.options[0].selected);
console.log(province.options[0].label);
province.options[2].selected = true;
// options[1]沒有value,所以返回其text
console.log(province.options[1].value);
在未指定value特性的情況下,IE7會返回空字符串,其他會返回與text特性相同的值;
<opggroup>:
<optgroup>HTML元素在<select>元素中創(chuàng)建一組選項,其屬于HTMLOptGroupElement類型,屬性為:
disabled:是一個布爾值,表示整個子項列表<option>是否已禁用(true)或未禁用(false);
label:表示組label屬性;
<form>
<select id="selectbox">
<optgroup label="前端" disabled>
<option>HTML</option>
<option>CSS</option>
<option>JavaScript</option>
</optgroup>
<optgroup label="后端">
<option>C#</option>
<option>Java</option>
<option>PHP</option>
</optgroup>
</select>
<script>
var selectbox = document.getElementById("selectbox");
var optgroup = selectbox.getElementsByTagName("optgroup")[0];
console.dir(optgroup); // HTMLOptGroupElement
console.dir(optgroup.label); // 前端
</script>
選擇選項:
對于只允許選擇一項的選擇框,最簡單的方式就是直接使用selectedIndex屬性,利用此屬性既可以獲取選中的項,也可設(shè)置某個項被造中;如:
var selectedIndex = province.selectedIndex;
var selectedOption = province.options[selectedIndex];
console.log("選中項的索引:" + selectedIndex + ",text" + selectedOption.text + ",value:" + selectedOption.value);
province.selectedIndex = 1; // 根據(jù)索引設(shè)置選中項
var selectedIndex = province.selectedIndex;
var selectedOption = province.options[selectedIndex];
console.log("選中項的索引:" + selectedIndex + ",text" + selectedOption.text + ",value:" + selectedOption.value);
對于multiple多項的選擇,單個selectedIndex屬性不足以表示被選中的多個選項,即使選中多個,讀取則只會返回選中項第一項的索引值且其value值也是第一個選中的Option的value值;
selected屬性:另一種選擇選項的方式,即取得某一項的引用,然后將其selected屬性設(shè)置為true;
console.log(province.options[0].selected); // false
console.log(province.options[2].selected); // true
province.options[0].selected = true;
province.options[1].selected = true;
與selectedIndex不同的是,在允許多選的選擇框中設(shè)置選項的selected屬性,不會取消對其他選中項的選擇,因而可以動態(tài)選中任意多個項;但如果是在單選擇框中,會取消對其他選擇的選擇;
selected屬性的作用主要是確定用戶選擇了選擇框中的哪些項;要取得所有選中的項,可以遍歷Options選項集合,逐個測試每個選項的selected屬性:
var province = document.forms[0].elements["province"];
function getSelectedOptions(selectbox){
var result = new Array();
var option = null;
for(var i=0, len=selectbox.options.length; i<len; i++){
option = selectbox.options[i];
if(option.selected){
result.push(option);
}
}
return result;
}
var province = document.forms[0].elements["province"];
var selectedOptions = getSelectedOptions(province);
var msg = "";
for(var i=0,len = selectedOptions.length; i<len; i++){
msg += "index:" + selectedOptions[i].index + ",text:" + selectedOptions[i].text + ",value:"+ selectedOptions[i].value + ";";
}
console.log(msg);
selectedOptions屬性:只讀屬性,其返回當(dāng)前選定的<option>元素的HTMLCollection;
console.log(province.selectedOptions); // HTMLCollection
如果是select-one單選,其中包含一個option,如果是select-mutiple多選,就包括所有選定的option;
例如:獲取所有選中項
<label for="foods">你喜歡吃什么?</label><br>
<select id="foods" name="foods" size="7" multiple>
<option value="1">蘋果</option>
<option value="2">香蕉</option>
<option value="3">桔子</option>
<option value="4">披薩</option>
<option value="5">西紅柿</option>
</select>
<br>
<button name="order" id="order">確定</button>
<p id="output"></p>
<script>
var orderButton = document.getElementById("order");
var itemList = document.getElementById("foods");
var outputBox = document.getElementById("output");
orderButton.addEventListener("click", function() {
var collection = itemList.selectedOptions;
var output = "";
for (var i=0; i<collection.length; i++) {
if (output === "") {
output = "你喜歡吃的食物如下:";
}
output += collection[i].text;
if(i === (collection.length - 2) && (collection.length < 3))
output += "和";
else if(i < (collection.length - 2))
output += ",";
else if(i === (collection.length - 2))
output += "和";
}
if(output === "")
output = "你啥也不喜歡";
outputBox.innerHTML = output;
}, false);
</script>
添加選項:
可以動態(tài)添加選項,并將它們添加到選擇框中;有多種添加的方式:
第一種:使用DOM方法:
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("天津"));
// newOption.setAttribute("value", "tianjin");
newOption.value = "tianjin";
selectbox.appendChild(newOption);
第二種:使用Option構(gòu)造函數(shù)來創(chuàng)建新選項:
語法:var option = new Option(text?, value?, ?defaultSelected, ?selected);參數(shù)text和value分別設(shè)置Option對象的text和value;后兩個參數(shù),分別設(shè)置option的defaultSelected和selected屬性,4個參數(shù)均為可選;其會返回一個<option>元素;
var newOption = new Option("上海", "shanghai");
selectbox.appendChild(newOption);
newOption = new Option("四川","sichuan",true,true);
selectbox.appendChild(newOption);
newOption = new Option();
newOption.text = "貴州";
newOption.value = "guizhou";
newOption.label = "美麗貴州";
newOption.selected = true;
selectbox.appendChild(newOption);
IE7以下不可用,因為它不能正確設(shè)置新選項的text屬性;
第三種:使用選擇框的add()方法:
語法:select.add(option[, before);其接受兩個參數(shù):要添加的新選項option和將位于新選項之后的選項before;before即可以是一個option也可以是選項的索引;before為可選,如果要在列表的最后添加選項,應(yīng)該將第二個參數(shù)設(shè)置為null、undefined或者不設(shè);如:
var newOption = new Option("上海", "shanghai");
selectbox.add(newOption, selectbox.options[1]); // 第2個位置
selectbox.add(newOption, 1); // 第2個位置
selectbox.add(newOption, null); // 最后位置
selectbox.add(newOption, undefined); // 最后位置
selectbox.add(newOption, 100); // 最后位置
selectbox.add(newOption); // 最后位置
如果將新選項添加到任意位置,使用DOM技術(shù)和insertBefore()方法也可以;
第四種,使用options屬性也可以把新的option添加到選擇框中,或者使用表單索引,如:
var newOption = new Option("上海", "shanghai");
selectbox.options[selectbox.options.length] = newOption; // 或者
selectbox[selectbox.options.length] = newOption;
// 如,添加多個
var arrOptions = ['重慶','云南','廣西'];
arrOptions.forEach(function(v,i){
selectbox[selectbox.options.length] = new Option(v);
});
// 或
arrOptions = [
{text: "重慶", value: "chongqing"},
{text: "云南", value: "yunnan"},
{text: "廣西", value: "guangxi"}
];
arrOptions.forEach(function(v,i){
selectbox[selectbox.options.length] = new Option(v.text, v.value);
});
移除選項:
移除選項也有多種方式:首先可以使用DOM的removeChild()方法,為其傳入要移除的選項;其次可以使用選擇框的remove()方法,為其傳入要移除選項的索引;最后,可以將相應(yīng)選項設(shè)置為null;
selectbox.removeChild(selectbox.options[1]);
selectbox.remove(2);
selectbox.options[2]=null;
// 如果不帶參數(shù),會刪除selectbox本身
selectbox.remove();
移除選擇框中所有的項,可以迭代所有選項并逐個移除:
function clearSelectbox(selectbox){
for(var i=0,len=selectbox.options.length; i<len; i++){
selectbox.remove(0);
}
}
clearSelectbox(selectbox);
使用options屬性也可以移除全部或某個選項,
selectbox.options[1] = null; // 移除第2個
selectbox.options.length = 2; // 截斷,只保留2個
// selectbox.options.length = 0; // 移除所有
selectbox.length = 0; // 移除所有
移動選項:
將一個選擇框中的選項移動到另一個選擇框中,使用DOM的appendChild()方法,因為使用appendChild()方法并傳入一個已存在的元素,那么就會先從該元素的父節(jié)點中移除它,再把它添加到新的指定的位置;
var selectbox1 = document.getElementById("selLocation1");
var selectbox2 = document.getElementById("selLocation2");
selectbox2.appendChild(selectbox1.options[1]);
移動和移除選項有一個共同之外,即會重置每一個選項的index屬性;
<h3>移動選項</h3>
<select name="sel1" id="sel1" size="8" multiple>
<option value="">唐</option>
<option value="">宋</option>
<option value="">元</option>
<option value="">明</option>
<option value="">清</option>
</select>
<button id="toRight">>></button>
<button id="toLeft"><<</button>
<select name="sel2" id="sel2" size="8" multiple>
<option value="">秦</option>
<option value="">漢</option>
<option value="">三國</option>
<option value="">兩晉</option>
<option value="">南北朝</option>
</select>
<script>
var sel1 = document.getElementById("sel1");
var sel2 = document.getElementById("sel2");
var toRight = document.getElementById("toRight");
var toLeft = document.getElementById("toLeft");
toRight.onclick = function(){
var options = sel1.selectedOptions;
for(var i=options.length-1; i>=0; i--){
sel2.appendChild(options[i]);
}
};
toLeft.onclick = function(){
var options = sel2.selectedOptions;
for(var i=options.length-1; i>=0; i--){
sel1.appendChild(options[i]);
}
}
</script>
重排選項:
重排選項的次序,最好的方式也是DOM方法,如appendChild()適合將選項添加到選擇框的最后,insertBefore()可以將選項移動到指定位置,如:
var optionToMove = selectbox.options[1];
// 向上移一下
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index - 1]);
// 向下移一下
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index + 2]);
select的事件:
選擇框的change事件與其他表單控件的change事件觸發(fā)的條件不一樣,其他控件的change事件是在值被修改且焦點離開時觸發(fā),而選擇框的change事件只要選中了選項就會觸發(fā);
選擇不同的選項時,也會觸發(fā)input事件,如:
selectbox.addEventListener("change", function(event){
console.log(event.target.selectedIndex);
});
function inputHandler(e){
console.log(e.target.value);
}
selectbox.addEventListener("input", inputHandler);
示例:跳轉(zhuǎn)
<select id="links">
<option value="https://www.zeronetwork.cn">零點網(wǎng)絡(luò)</option>
<option value="https://cn.bing.com">Bing</option>
<option value="https://www.apple.com">蘋果</option>
</select>
<script>
var links = document.getElementById("links");
links.addEventListener("change", function(event){
location.href = event.target.options[event.target.selectedIndex].value;
});
</script>
表單序列化:
隨著Ajax的出現(xiàn),表單序列化已經(jīng)成為一種常見需求;在Javascript中,可以利用表單元素的type屬性,連同name和value屬性一起實現(xiàn)對表單的序列化;
瀏覽器把數(shù)據(jù)發(fā)送給服務(wù)器原理:
如:表單簡單序列化;
var btn = document.getElementById("btn");
btn.addEventListener("click", submitHandler, false);
function submitHandler(event){
var myForm = document.forms[0];
var username = myForm.elements["username"].value;
var userpwd = myForm.elements["userpwd"].value;
var sex = myForm.elements["sex"].value;
var courseValue = [];
var courseList = myForm.elements["course"];
for(var i=0, len=courseList.length; i<len; i++){
if(courseList[i].checked)
courseValue.push(courseList[i].value);
}
var params = "username=" + username +
"&userpwd=" + userpwd +
"&sex=" + sex +
"&course=" + courseValue;
console.log(params);
}
如:通用序列化:
function serialize(form){
// 后面要用到的變量
var params = new Array();
var field = null,
i, j, len,
optLen,
option,
chkObj = {};
for(i=0, len=form.elements.length; i<len; i++){
field = form.elements[i];
switch(field.type){
// 如果是select,包含單選和多選
case "select-one":
case "select-multiple":
arrOpt = [];
for(j=0, optLen=field.options.length; j<optLen; j++){
option = field.options[j];
if(option.selected){
arrOpt.push(encodeURIComponent(option.value));
}
}
arrOpt = arrOpt.join(",");
params.push(encodeURIComponent(field.name) + "=" + arrOpt);
break;
// 如果是fieldset、file、submit、reset、button不提交
case undefined: //字段集
case "file": //文件域
case "submit": //提交
case "reset": //重置
case "button": //按鈕
break;
// 如果是單選或復(fù)選框
case "radio":
case "checkbox":
if(field.checked){
if(chkObj[field.name])
chkObj[field.name].push(encodeURIComponent(field.value));
else
chkObj[field.name] = [encodeURIComponent(field.value)];
}
break;
default:
// 如果沒有名字的表單元素,不提交
if(field.name.length)
params.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
}
}
for(var o in chkObj){
params.push(encodeURIComponent(o) + "=" + chkObj[o].join(","));
}
return params.join("&");
}
// 應(yīng)用
var btn = document.getElementById("btn");
btn.addEventListener("click", submitHandler, false);
function submitHandler(event){
var myForm = document.forms[0];
var params = serialize(myForm);
console.log(params);
}
無刷新提交(局部刷新):
<script>
function saveUserInfo(){
var msg = document.getElementById("msg");
var form = document.forms[0];
// 提交地址
var url = "./demo.php";
// POST的值,把每個變量都通過&來聯(lián)接
var postStr = serialize(form);
// XmlHTTP
var XmlHTTP;
if(window.XMLHttpRequest) {
XmlHTTP = new XMLHttpRequest();
}else if(window.ActiveXObject) {
XmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
}
XmlHTTP.open("POST", url, true);
//定義傳輸?shù)奈募﨟TTP頭信息
XmlHTTP.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
XmlHTTP.send(postStr); //發(fā)送POST數(shù)據(jù)
//獲取執(zhí)行狀態(tài)
XmlHTTP.onreadystatechange = function() {
//如果執(zhí)行狀態(tài)成功,那么就把返回信息寫到指定的層里
if (XmlHTTP.readyState == 4 && XmlHTTP.status == 200) {
msg.innerHTML = XmlHTTP.responseText;
}
}
}
</script>
<div id="msg"></div>
<form name="userinfo" method="post" action="">
姓名:<input type="text" id="username"name="username" /><br />
年齡:<input type="text" name="age" /><br />
性別:<input type="text" name="sex" /><br />
<input type="button" value="提交表單" onClick="saveUserInfo()">
</form>
demo.php:
<?php
$username = $_POST['username'];
$age = $_POST['age'];
$sex = $_POST['sex'];
echo "$username <br>";
echo "$userage <br>";
echo "$usersex <br>";
// 鏈接數(shù)據(jù)庫,并保存到數(shù)據(jù)庫,$result為執(zhí)行結(jié)果
$result = true;
if ($result){
echo "提交成功!";
}
else {
echo "提交失敗!";
}
?>
整合:saveUserInfo()中換成:
// 提交地址
var url = "./demo.php";
// POST的值,把每個變量都通過&來聯(lián)接
var postStr = serialize(form);
submitHandler()事件處理函數(shù):
今天就來聊聊在為了您更好的體驗,本文章聊聊如何僅支持谷歌瀏覽器訪問查看頁面?這篇文章中提到的瀏覽器兼容問題,以此篇文章來證明自己并非不了解瀏覽器兼容性問題,而是當(dāng)時其他因素導(dǎo)致選擇了一刀切的方法來處理需求(我就是一個不粘鍋)。
嘿,xdm~既然點進來了,不妨就繼續(xù)看下去吧^_^
所謂的瀏覽器兼容性問題,是指因為不同的瀏覽器對同一段代碼有不同的解析,造成頁面顯示效果不統(tǒng)一的情況。
上面的定義就是大白話,我們來看看來自百度百科的權(quán)威解釋:瀏覽器兼容性問題又被稱為網(wǎng)頁兼容性或網(wǎng)站兼容性問題,指網(wǎng)頁在各種瀏覽器上的顯示效果可能不一致而產(chǎn)生瀏覽器和網(wǎng)頁間的兼容問題。在網(wǎng)站的設(shè)計和制作中,做好瀏覽器兼容,才能夠讓網(wǎng)站在不同的瀏覽器下都正常顯示。而對于瀏覽器軟件的開發(fā)和設(shè)計,瀏覽器對標(biāo)準(zhǔn)的更好兼容能夠給用戶更好的使用體驗。
造成瀏覽器兼容性問題的根本原因就是各瀏覽器使用了不同的內(nèi)核,并且它們處理同一件事情的時候思路不同。
怎么理解上述文字?即:不同瀏覽器使用的內(nèi)核及所支持的HTML等網(wǎng)頁語言標(biāo)準(zhǔn)不同,以及用戶客戶端的環(huán)境不同(如分辨率不同)造成了顯示效果不能達到理想效果。
前端開發(fā)經(jīng)常需要檢查瀏覽器的兼容性,這里推薦(Can I Use)這個查詢網(wǎng)站。它是一個針對前端開發(fā)人員定制的一個查詢CSS、JS、HTML5、SVG在主流瀏覽器中特性和兼容性的網(wǎng)站,可以很好的保證網(wǎng)頁在瀏覽器中的兼容性。有了這個工具我們就可以快速地了解到代碼在各個瀏覽器中的兼容情況了,強烈推薦一波,大家趕緊去體驗吧?!界面效果如下圖所示:
工具只能給我們顯示查詢的特性在不同瀏覽器上的兼容情況,至于如何解決兼容問題還得看下述的解決辦法→
1、不同瀏覽器的標(biāo)簽?zāi)J(rèn)的內(nèi)外邊距不同
解決方案:*{margin: 0; padding: 0;}
其實清除瀏覽器自帶的默認(rèn)樣式,每個前端開發(fā)者所用的方法大同小異,這里給出我選用的清除默認(rèn)樣式的重置樣式代碼:
/**
* 該文件用于清除瀏覽器樣式
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
padding:0;
margin:0;
border:0;
outline: 0;
font-family: "Helvetica Neue For Number", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
word-wrap:break-word;
}
html, body {
width: 100%;
height: 100%;
}
a {
text-decoration: none;
-webkit-tap-highlight-color:rgba(255,255,255,0);
}
ul, ol {
list-style-type: none;
}
textarea {
resize: none;
}
/*去除input button默認(rèn)樣式*/
input, button, textarea {
-webkit-appearance: none;
-webkit-tap-highlight-color: rgba(255, 225, 225, 0);
padding: 0;
border: 0;
outline: 0;
}
// 修改placeholder屬性默認(rèn)文字顏色
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
/* WebKit browsers */
color: #999;
}
input:-moz-placeholder, textarea:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #999;
}
input::-moz-placeholder, textarea::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #999;
}
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #999;
}
除了自己定義清除默認(rèn)樣式的代碼,也可選擇引用別人寫好的成熟插件Normalize.css來清除默認(rèn)樣式;
2、圖片加a標(biāo)簽在IE9中會有邊框
解決方案:img{border: none;}
3、IE6及更低版本浮動元素,浮動邊雙倍邊距
解決方案:不使用margin,使用padding
4、IE6及更低版本中,部分塊元素?fù)碛心J(rèn)高度
解決方案:給元素設(shè)置font-size: 0;
5、a標(biāo)簽藍色邊框
解決方案:a{outline: none;}
6、IE6不支持min-height屬性
解決方案:{min-height: 200px; _height: 350px;}
7、IE9以下瀏覽器不能使用opacity
解決方案:Firefox/Chrome/Safari/Opera瀏覽器使用opacity;IE瀏覽器使用filter
opacity: 0.7; /*FF chrome safari opera*/
filter: alpha(opacity:70); /*用了ie濾鏡,可以兼容ie*/
8、IE6/7不支持display:inline-block
解決方案:{display: inline-block; *display: inline;}
9、cursor兼容問題
解決方案:統(tǒng)一使用{cursor: pointer;}
10、IE6/7中img標(biāo)簽與文字放一起時,line-height失效的問題
解決方案:文字和<img>都設(shè)置float
11、table寬度固定,td自動換行
解決方案:table設(shè)置 {table-layout: fixed},td設(shè)置 {word-wrap: break-word}
12、相鄰元素設(shè)置margin邊距時,margin將取最大值,舍棄小值
解決方案:不讓邊距重疊,可以給子元素加一個父元素,并設(shè)置該父元素設(shè)置:{overflow: hidden}
13、a標(biāo)簽css狀態(tài)的順序
解決方案:按照link--visited--hover--active的順序編寫
14、IE6/7圖片下面有空隙的問題
解決方案:img{display: block;}
15、ul標(biāo)簽在Firefox中默認(rèn)是有padding值的,而在IE中只有margin有值
解決方案:ul{margin: 0;padding: 0;}
16、IE中l(wèi)i指定高度后,出現(xiàn)排版錯誤
解決方案:設(shè)置line-height
17、ul或li浮動后,顯示在div外
解決方案:清除浮動;須在ul標(biāo)簽后加<div style="clear:both"></div>來閉合外層div
18、ul設(shè)置float后,在IE中margin將變大
解決方案:ul{display: inline;},li{list-style-position: outside;}
19、li中內(nèi)容超過長度時,用省略號顯示
li{
width: 200px;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
20、div嵌套p時,出現(xiàn)空白行
解決方案:li{display: inline;}
21、IE6默認(rèn)div高度為一個字體顯示的高度
解決方案:{line-height: 1px;}或{overflow: hidden;}
22、在Chrome中字體不能小于10px
解決方案:p{font-size: 12px; transform: scale(0.8);}
23、谷歌瀏覽器上記住密碼后輸入框背景色為黃色
input{
background-color: transparent !important;
}
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill{
-webkit-text-fill-color: #333 !important;
-webkit-box-shadow: 0 0 0 1000px transparent inset !important;
background-color: transparent !important;
background-image: none !important;
transition: background-color 5000s ease-in-out 0s;
}
24、CSS3兼容前綴表示
寫法 | 內(nèi)核 | 瀏覽器 |
-webkit- | webkit渲染引擎 | chrome/safari |
-moz- | gecko渲染引擎 | Firefox |
-ms- | trident渲染引擎 | IE |
-o- | opeck渲染引擎 | Opera |
如:
.box{
height: 40px;
background-color: red;
color: #fff;
-webkit-border-radius: 5px; // chrome/safari
-moz-border-radius: 5px; // Firefox
-ms-border-radius: 5px; // IE
-o-border-radius: 5px; // Opera
border-radius: 5px;
}
1、事件對象的兼容
e = ev || window.event
2、滾動事件的兼容
scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
3、阻止冒泡的兼容
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble=true;
}
4、阻止默認(rèn)行為的兼容
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
5、添加事件監(jiān)聽器的兼容
if (target.addEventListener) {
target.addEventListener("click", fun, false);
} else {
target.attachEvent("onclick", fun);
}
6、ajax創(chuàng)建對象的兼容
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft XMLHTTP");
}
7、鼠標(biāo)按鍵編碼的兼容
function mouse (ev) {
var e = ev || window.event;
if (evt) {
return e.button;
} else if (window.event) {
switch (e.button) {
case 1: return 0;
case 4: return 1;
case 2: return 2;
}
}
}
8、在IE中,event對象有x,y屬性,F(xiàn)irefox中與event.x等效的是event.pageX,而event.pageX在IE中又沒有
x = event.x ? event.x : event.pageX;
9、在IE下,event對象有srcElement屬性,但是沒有target屬性;Firefox下,event對象有target屬性,但是沒有srcElement屬性
var source = ev.target || ev.srcElement;
var target = ev.relatedTarget || ev.toElement;
10、在Firefox下需要用CSS禁止選取網(wǎng)頁內(nèi)容,在IE用JS禁止
-moz-user-select: none; // Firefox
obj.onselectstart = function() {return false;} // IE
11、innerText在IE中能正常工作,但在FireFox中卻不行
if (navigator.appName.indexOf("Explorer") > -1) {
document.getElementById('element').innerText = "IE";
} else {
document.getElementById('element').textContent = "Firefox";
}
12、在Firefox下,可以使用const關(guān)鍵字或var關(guān)鍵字來定義常量;在IE下,只能使用var關(guān)鍵字來定義常量
解決方案:統(tǒng)一使用var關(guān)鍵字來定義常量
1、禁止iOS識別長串?dāng)?shù)字為電話
解決方案:<meta content="telephone=no" name="format-detection" />
2、禁止iOS彈出各種操作窗口
解決方案:-webkit-touch-callout:none
3、禁止Android手機識別郵箱
解決方案:<meta content="email=no" name="format-detection" />
4、禁止iOS和Android用戶選中文字
解決方案:-webkit-user-select:none
5、iOS下取消input在輸入的時候英文首字母的默認(rèn)大寫
解決方案:<input autocapitalize="off" autocorrect="off" />
6、Android下取消輸入語音按鈕
解決方案:input::-webkit-input-speech-button {display: none}
7、在移動端修改難看的點擊的高亮效果,iOS和安卓下都有效
解決方案:* {-webkit-tap-highlight-color:rgba(0,0,0,0);}
8、iOS下input為type=button屬性disabled設(shè)置true,會出現(xiàn)樣式文字和背景異常問題
解決方案:使用opacity=1;
9、input為fixed定位,在iOS下input固定定位在頂部或者底部,在頁面滾動一些距離后,點擊input(彈出鍵盤),input位置會出現(xiàn)在中間位置
解決方案:內(nèi)容列表框也是fixed定位,這樣不會出現(xiàn)fixed錯位的問題
10、移動端字體小于12px使用四周邊框或者背景色塊,部分安卓文字偏上bug問題
解決方案:可以使用整體放大1倍(width、height、font-size等等),再使用transform縮放
11、在移動端圖片上傳圖片兼容低端機的問題
解決方案:input 加入屬性accept="image/*" multiple
12、在Android上placeholder文字設(shè)置行高會偏上
解決方案:input有placeholder情況下不要設(shè)置行高
13、overflow: scroll或auto;在iOS上滑動卡頓的問題
解決方案:加入-webkit-overflow-scrolling: touch;
14、iOS中日期如:2022-02-22 00:00:00格式的時間轉(zhuǎn)時間戳不成功
解決方案:需要將時間中的'00:00:00去除之后才能轉(zhuǎn)為時間戳'
15、iOS中需要將時間格式轉(zhuǎn)為/,如:2022/02/22
let date = '2022-02-22';
let dateStr = date.replace(/-/g, '/'); // 2022/02/22
16、移動端click300ms延時響應(yīng)
解決方案:使用Fastclick
window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );
17、移動端1px邊框問題
解決方案:原先元素的border去掉,然后利用:before或者:after重做border,并transform的scale縮小一半,原先的元素相對定位,新做的border絕對定位
.border-1px{
position: relative;
border:none;
}
.border-1px:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
至此,關(guān)于瀏覽器兼容性問題的相關(guān)知識和解決方案就聊完了,最后還穿插了關(guān)于移動端兼容的問題描述,肯定還有很多沒有總結(jié)到的兼容性問題,希望xdm在下方評論↘提供。
看文至此,順手點個贊再走唄,3Q^_^
伙伴們,如果覺得本文對你有些許幫助,點個或者?個關(guān)注在走唄^_^ 。另外如果本文章有問題或有不理解的部分,歡迎大家在評論區(qū)評論指出,我們一起討論共勉。
豬腳本(原飛豬腳本)以按鍵精靈教學(xué)為主,涉及UiBot,Python,Lua等腳本編程語言,教學(xué)包括全自動辦公腳本,游戲輔助腳本,引流腳本,網(wǎng)頁腳本,安卓腳本,IOS腳本,注冊腳本,點贊腳本,閱讀腳本以及網(wǎng)賺腳本等各個領(lǐng)域。想學(xué)習(xí)按鍵精靈的朋友可以添加金豬腳本粉絲交流群:554127455 學(xué)習(xí)路上不再孤單,金豬腳本伴你一同成長.
1.什么是網(wǎng)頁元素特征字符串?
請參考網(wǎng)頁特征字符串詳解;
2.Html系列命令
2.1.HtmlSelect命令
1)HtmlSelect命令只能夠根據(jù)Select項的值來進行選擇,注意這里不是顯示在Select項上的文字,而是該項的value。
一個典型的下拉框HTML代碼如下:
<select name="city">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">廣州</option>
</select>
這里如果要選擇上海,需要選擇值為2的項;
2)級聯(lián)的下拉列表組合。
在有的網(wǎng)頁中,會有幾個級聯(lián)的下拉列表,后一個下拉框會隨前一個框的值變化而發(fā)生變化,典型的有注冊頁面上的省份城市選擇,HtmlSelect命令能夠觸發(fā)Onchange事件,會導(dǎo)致后一個下拉框值發(fā)生變化,但是如果執(zhí)行腳本太快,而導(dǎo)致后一個未能選中正確的值,可以在前一個HtmlSelect后加上適當(dāng)?shù)难訒r;
3)多選表單中的列表控件;有的列表支持多選,在有一些個求職網(wǎng)站中,職業(yè)是可以多選的,這時候可以用%將多個需要選擇的值連接起來傳遞給HtmlSelect命令實現(xiàn)多選;
2.2.HtmlExists命令
HtmlExists命令,能夠判斷指定特征的元素是否存在,并能夠返回具備該特征的元素的個數(shù)。這個命令能夠用來判斷某個元素是否存在,如果為0證明不存在;
2.3.HtmlGet命令
HtmlGet命令比較復(fù)雜,但是功能也非常強大,該命令具備兩個參數(shù),第一個參數(shù)為獲取類型,目前支持的值如下所示:
序號 值 適用對象
1 text 得到指定元素的文本值,對應(yīng)DOM屬性innerText
2 html 得到指定元素內(nèi)部的HTML代碼,對應(yīng)DOM屬性innerHTML
3 outerHtml 得到元素整體的HTML代碼,對應(yīng)DOM屬性的outerHTML
4 value 得到元素的Value值,用于獲取表單元素內(nèi)部的值
5 src 得到圖像元素的src屬性,用于IMG標(biāo)簽對象
6 href 得到鏈接元素的鏈接地址,用于A標(biāo)簽
7 …其他名稱 其他屬性,如果您使用的是合法的屬性名稱,就能夠返回對應(yīng)的值。如何才是合法的屬性?請參閱HTML標(biāo)準(zhǔn)。
第二個參數(shù)為特征字符串,如果匹配多個,只能返回第一個元素的值;
例如,獲得淘寶貨物價格:
Plugin price=Web.HtmlGet("text","id:id_Price")
獲取某個表單文本的值
Plugin email=Web.HtmlGet("value","name:Email")
2.4.RunJS命令
RunJS命令提供了直接運行Javascript的功能,如果您對JS非常熟悉,就能夠極大的擴展WQM的功能。
RunJS命令支持兩中執(zhí)行方式,第一個參數(shù)設(shè)置為0時,能夠執(zhí)行一段沒有返回值的Javascript,
例如:
RunJS(0,"alert('hello');")
第一個參數(shù)設(shè)置為1時,能執(zhí)行一段js并返回由return語句返回的值,返回值為字符串類型;
例如:返回Html文檔的title;
RunJS(1,"var t=document.title;return t;")
如果您分析到網(wǎng)頁中某個按鈕實際上就是執(zhí)行了一個函數(shù),例如
<input type="Button" … />
您就可以直接調(diào)用
RunJS(0,"dosomething();")
JQuery的支持,網(wǎng)頁按鍵精靈集成了Jquery1.3.2,為了不與其他JQ的庫發(fā)生沖突,使用了wqmjq來代替$操作符,如果您需要直接使用JQ來操作網(wǎng)頁,可使用wqmjq來執(zhí)行Jquery語句:
RunJS(0,"wqmjq('#test').click();")
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。