JavaScript 表单

表单验证
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script>
            function validateForm() {
                var x = document.forms["myForm"]["fname"].value;
                if (x == null || x == "") {
                    alert("需要输入名字。");
                    return false;
                }
            }
        </script>
    </head>
    <body>

        <form name="myForm" action="demo_form.php"
            onsubmit="return validateForm()" method="post">
            名字: <input type="text" name="fname">
            <input type="submit" value="提交">
        </form>

    </body>
</html>
通过浏览器自动验证
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>

        <form action="demo_form.php" method="post">
          <input type="text" name="fname" required="required">
          <input type="submit" value="提交">
        </form>

        <p>点击提交按钮,如果输入框是空的,浏览器会提示错误信息。</p>

    </body>
</html>
必填(或必选)项目
<script>
    function validateForm(){
    var x=document.forms["myForm"]["fname"].value;
    if (x==null || x==""){
      alert("姓必须填写");
      return false;
      }
    }
</script>
<body>
	
<form name="myForm" action="demo-form.php" onsubmit="return validateForm()" method="post">
    姓: <input type="text" name="fname">
    <input type="submit" value="提交">
</form>

E-mail 验证

<script>
    function validateForm(){
        var x=document.forms["myForm"]["email"].value;
        var atpos=x.indexOf("@");
        var dotpos=x.lastIndexOf(".");
        if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length){
            alert("不是一个有效的 e-mail 地址");
            return false;
        }
    }
</script>
<body>

    <form name="myForm" action="demo-form.php" onsubmit="return validateForm();" method="post">
        Email: <input type="text" name="email">
        <input type="submit" value="提交">
    </form>
	
</body>
<input id="id1" type="number" max="100">
<button onclick="myFunction()">验证</button>
 
<p id="demo"></p>
 
<script>
    function myFunction() {
        var txt = "";
        if (document.getElementById("id1").validity.rangeOverflow) {     
        }
        document.getElementById("demo").innerHTML = txt;
    }
</script>

Validity 属性

input 元素的 v包含一系列关于 validity 数据属性:

属性 描述
customError 设置为 true, 如果设置了自定义的 validity 信息。
patternMismatch 设置为 true, 如果元素的值不匹配它的模式属性。
rangeOverflow 设置为 true, 如果元素的值大于设置的最大值。
rangeUnderflow 设置为 true, 如果元素的值小于它的最小值。
stepMismatch 设置为 true, 如果元素的值不是按照规定的 step 属性设置。
tooLong 设置为 true, 如果元素的值超过了 maxLength 属性设置的长度。
typeMismatch 设置为 true, 如果元素的值不是预期相匹配的类型。
valueMissing 设置为 true,如果元素 (required 属性) 没有值。
valid 设置为 true,如果元素的值是合法的。

ES6 可以使用 let 关键字来实现块级作用域let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
let关键字,使用 let 关键字, 它声明的变量作用域只在循环体内,循环体外的变量不受影响。
let i = 5;
for (let i = 0; i < 10; i++) {
    // 一些代码...
}
// 这里输出 i 为 5

JavaScript JSON

是用于存储和传输数据的格式
通常用于服务端向网页传递数据
Json语法规则:
  • 数据为 键/值 对。
  • 数据由逗号分隔。
  • 大括号保存对象
  • 方括号保存数组
JSON数据:"name":"value"
JSON对象:{"name":"value","url":"www.json.com"}
JSON数组:"site":[{},{},{}]  数组中可以包含对象

JSON字符串转换为javaScript对象,通过内置函数JSON.parse()将字符串转化为JavaScript对象。JSON.stringify(),用于将JavaScript值转换为JSON字符串。
<h2>为 JSON 字符串创建对象</h2>
<p id="demo"></p>
<script>
    var text = '{ "sites" : [' +
        '{ "name":"Runoob" , "url":"www.runoob.com" },' +
        '{ "name":"Google" , "url":"www.google.com" },' +
        '{ "name":"Taobao" , "url":"www.taobao.com" } ]}';

    obj = JSON.parse(text);
    document.getElementById("demo").innerHTML = obj.sites[1].name + " " + obj.sites[1].url;
</script>

javascript:void(alert('warning!!!'))
实例中,用户点击会弹出警告信息。
<script type="text/javascript">
    <!--
    //-->
</script>
</head>
<body>
	
<p>点击以下链接查看结果:</p>
<a href="javascript:void(alert('Warning!!!'))">点我!</a>

href="#"与href="javascript:void(0)"的区别

# 包含了一个位置信息,默认的锚是#top 也就是网页的上端。

而javascript:void(0), 仅仅表示一个死链接。

在页面很长的时候会使用 # 来定位页面的具***置,格式为:# + id

如果你要定义一个死链接请使用 javascript:void(0) 。


JS函数

函数声明和函数使用:

function functionName(parameters) {
  执行的代码
}
<p id="demo"></p>
<script>
    function myFunction(a,b){
        return a*b;
    }
    document.getElementById("demo").innerHTML=myFunction(4,3);
</script>

函数表达式

<p id="demo"></p>
<script>
    var x = function (a, b) {return a * b};
    document.getElementById("demo").innerHTML = x;
</script>

Function()构造函数

<p id="demo"></p>
<script>
    var myFunction = new Function("a", "b", "return a * b");
    document.getElementById("demo").innerHTML = myFunction(4, 3);
</script>

箭头函数

ES6 新增了箭头函数,箭头函数不需要使用 function、return 关键字及大括号 {}
  • 多参数:(参数1,参数2,...参数N) =>{ 函数声明 }
  • 一个参数:(单一参数) =>{函数声明}
  • 没有参数:()=>{函数声明}
<p>IE11 及更早 IE 版本不支持箭头函数。</p>

<p id="demo"></p>

<script>
    const x = (x, y) => x * y;
    document.getElementById("demo").innerHTML = x(5, 5);
</script>
<p>设置参数的默认值。</p>
<p id="demo1"></p>
<p id="demo2"></p>
<script>
    function myFunction(x, y = 10) {
        // 如果不传入参数 y ,则其默认值为 10
        return x + y;
    }
    // 输出 2
    document.getElementById("demo1").innerHTML = myFunction(0, 2) ;
    // 输出 15, y 参数的默认值
    document.getElementById("demo2").innerHTML = myFunction(5);
</script>

arguments 对象

内置对象,包含了函数调用的参数数组。
<p>查找最大的数。</p>
<p id="demo"></p>
<script>
    x = findMax(1, 123, 500, 115, 44, 88);

    function findMax() {
        var i, max = arguments[0];

        if(arguments.length < 2) return max;

        for (i = 0; i < arguments.length; i++) {
            if (arguments[i] > max) {
                max = arguments[i];
            }
        }
        return max;
    }
    document.getElementById("demo").innerHTML = x;
</script>
或者统计所有数值的和:
x = sumAll(1, 123, 500, 115, 44, 88);
 
function sumAll() {
    var i, sum = 0;
    for (i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

JavaScript 闭包

函数自我调用,变量add指定了函数自我调用的返回字值。
自我调用函数只执行一次,设置计数器为0,并返回函数表达式。
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰,直观地说是形成一个不销毁的栈环境。
<p>局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
    var add = (function () {
        var counter = 0;
        return function () {return counter += 1;}
    })();
    function myFunction(){
        document.getElementById("demo").innerHTML = add();
    }
</script>

JavaScript HTML DOM

当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)

HTML DOM 树

DOM HTML tree
通过可编程的对象模型,javaScript获得了足够的能力来常见动态的HTML
  • JavaScript 能够改变页面中的所有 HTML 元素
  • JavaScript 能够改变页面中的所有 HTML 属性
  • JavaScript 能够改变页面中的所有 CSS 样式
  • JavaScript 能够对页面中的所有事件做出反应
查找HTML元素:
1.   通过id,如果找到返回对象在X中的形式,否则返回null
<p id="intro">你好世界!</p>
<p>该实例展示了 <b>getElementById</b> 方法!</p>
<script>
    x=document.getElementById("intro");
    document.write("<p>文本来自 id 为 intro 段落: " + x.innerHTML + "</p>");
</script>
2.  通过标签名
<p>你好世界!</p>
<div id="main">
    <p> DOM 是非常有用的。</p>
    <p>该实例展示了  <b>getElementsByTagName</b> 方法</p>
</div>
<script>
    var x=document.getElementById("main");
    var y=x.getElementsByTagName("p");
    document.write('id="main"元素中的第一个段落为:' + y[0].innerHTML);
</script>
3.  通过类名
<p class="intro">你好世界!</p>
<p>该实例展示了 <b>getElementsByClassName</b> 方法!</p>
<script>
    x=document.getElementsByClassName("intro");
    document.write("<p>文本来自 class 为 intro 段落: " + x[0].innerHTML + "</p>");
</script>
<p><b>注意:</b>Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法。</p>
改变HTML输出流:
document.getElementById(id).innerHTML=新的 HTML
使用HTML DOM的id获取元素,然后通过innerHTML更改元素
<p id="p1">Hello World!</p>
<script>
    document.getElementById("p1").innerHTML="新文本!";
</script>
<p>以上段落通过脚本修改文本。</p>

改变HTML属性:
document.getElementById(id).attribute=新属性值
使用HTML DOM获取id的元素,更改此元素的属性值
<img id="image" src="smiley.gif">

<script>
    document.getElementById("image").src="landscape.jpg";
</script>

改变HTML样式:
document.getElementById(id).style.property=新样式
<p id="p1">Hello World!</p>
<p id="p2">Hello World!</p>
<script>
    document.getElementById("p2").style.color="blue";
    document.getElementById("p2").style.fontFamily="Arial";
    document.getElementById("p2").style.fontSize="larger";
</script>

使用事件:
  • 元素被点击。
  • 页面加载完成。
  • 输入框被修改。
  • ……
<h1 id="id1">我的标题 1</h1>
<button type="button" 
onclick="document.getElementById('id1').style.color='red'">
点我!</button>

点击改变内容:
<h1 onclick="this.innerHTML='Ooops!'">点击文本!</h1>
或者
<script>
    function changetext(id)
    {
        id.innerHTML="Ooops!";
    }
</script>
</head>
<body>
<h1 onclick="changetext(this)">点击文本!</h1>

onload 和 onunload 事件

会在用户进入或离开页面时触发。
<body onload="checkCookies()">

<script>
    function checkCookies(){
        if (navigator.cookieEnabled==true){
            alert("Cookies 可用")
        }
        else{
            alert("Cookies 不可用")
        }
    }
</script>
<p>弹窗-提示浏览器 cookie 是否可用。</p>

onchange 事件

常结合对输入字段的验证来使用
<script>
    function myFunction(){
        var x=document.getElementById("fname");
        x.value=x.value.toUpperCase();
    }
</script>
</head>
<body>

输入你的名字: <input type="text" id="fname" onchange="myFunction()">
<p>当你离开输入框后,函数将被触发,将小写字母转为大写字母。</p>

JavaScript HTML DOM EventListener

用户点击按钮触发监听事件:
element.addEventListener(event, function, useCapture);

第一个参数是事件的类型 (如 "click" 或 "mousedown").

第二个参数是事件触发后调用的函数。

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。

  • addEventListener() 方法用于向指定元素添加事件句柄。

  • addEventListener() 方法添加的事件句柄不会覆盖已存在的事件句柄。

<p>该实例使用 addEventListener() 方法在按钮中添加点击事件。 </p>
<button id="myBtn">点我</button>
<p id="demo"></p>
<script>
    document.getElementById("myBtn").addEventListener("click", displayDate);
    function displayDate() {
        document.getElementById("demo").innerHTML = Date();
    }
</script>
向原元素添加时间句柄
element.addEventListener("click", function(){ alert("Hello World!"); });
<p>该实例使用 addEventListener() 方法在用户点击按钮时执行函数。</p>
<button id="myBtn">点我</button>
<script>
    document.getElementById("myBtn").addEventListener("click", myFunction);
    function myFunction() {
        alert ("Hello World!");
    }
</script>
向同一个元素添加多个事件句柄
addEventListener() 方法允许向同一个元素添加多个事件,且不会覆盖已存在的事件:
<p>该实例使用 addEventListener() 方法向同个按钮中添加两个点击事件。</p>
<button id="myBtn">点我</button>
<script>
    var x = document.getElementById("myBtn");
    x.addEventListener("click", myFunction);
    x.addEventListener("click", someOtherFunction);
    function myFunction() {
        alert ("Hello World!")
    }
    function someOtherFunction() {
        alert ("函数已执行!")
    }
</script>
向一个按钮添加鼠标移入、移出、点击等句柄
<p>实例使用 addEventListener() 方法在同一个按钮中添加多个事件。</p>
<button id="myBtn">点我</button>
<p id="demo"></p>
<script>
    var x = document.getElementById("myBtn");
    x.addEventListener("mouseover", myFunction);
    x.addEventListener("click", mySecondFunction);
    x.addEventListener("mouseout", myThirdFunction);
    function myFunction() {
        document.getElementById("demo").innerHTML += "Moused over!<br>"
    }
    function mySecondFunction() {
        document.getElementById("demo").innerHTML += "Clicked!<br>"
    }
    function myThirdFunction() {
        document.getElementById("demo").innerHTML += "Moused out!<br>"
    }
</script>
向Window对象添加事件句柄
<p>实例在 window 对象中使用 addEventListener() 方法。</p>
<p>尝试重置浏览器的窗口触发 "resize" 事件句柄。</p>
<p id="demo"></p>
<script>
    window.addEventListener("resize", function(){
        document.getElementById("demo").innerHTML = Math.random();
    });
</script>

当传递参数值时,使用"匿名函数"调用带参数的函数

<p>实例演示了在使用 addEventListener() 方法时如何传递参数。</p>
<p>点击按钮执行计算。</p>
<button id="myBtn">点我</button>
<p id="demo"></p>
<script>
    var p1 = 5;
    var p2 = 7;
    document.getElementById("myBtn").addEventListener("click", function() {
        myFunction(p1, p2);
    });
    function myFunction(a, b) {
        var result = a * b;
        document.getElementById("demo").innerHTML = result;
    }
</script>

事件冒泡或事件捕获

时间传递的两种方式,冒泡和捕获。默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。
冒泡:内部元素先被触发
捕获:外部元素先被触发。
<style>
    div {
        background-color: coral;
        border: 1px solid;
        padding: 50px;
    }
</style>
</head>
<body>

<p>实例演示了在添加不同事件监听时,冒泡与捕获的不同。</p>
<div id="myDiv">
	<p id="myP">点击段落,我是冒泡。</p>
</div><br>
<div id="myDiv2">
	<p id="myP2">点击段落,我是捕获。 </p>
</div>
<script>
    document.getElementById("myP").addEventListener("click", function() {
        alert("你点击了 P 元素!");
    }, false);
    document.getElementById("myDiv").addEventListener("click", function() {
        alert(" 你点击了 DIV 元素 !");
    }, false);
    document.getElementById("myP2").addEventListener("click", function() {
        alert("你点击了 P2 元素!");
    }, true);
    document.getElementById("myDiv2").addEventListener("click", function() {
        alert("你点击了 DIV2 元素 !");
    }, true);
</script>

removeEventListener() 方法

removeEventListener() 方法移除由 addEventListener() 方法添加的事件句柄:
<style>
    #myDIV {
        background-color: coral;
        border: 1px solid;
        padding: 50px;
        color: white;
    }
</style>
</head>
<body>

<div id="myDIV"> div 元素添加了 onmousemove 事件句柄,鼠标在桔红色的框内移动时会显示随机数。
  <p>点击按钮移除 DIV 的事件句柄。</p>
  <button onclick="removeHandler()" id="myBtn">点我</button>
</div>
<p id="demo"></p>
<script>
    document.getElementById("myDIV").addEventListener("mousemove", myFunction);
    function myFunction() {
        document.getElementById("demo").innerHTML = Math.random();
    }
    function removeHandler() {
        document.getElementById("myDIV").removeEventListener("mousemove", myFunction);
    }
</script>
跨浏览器解决方法
var x = document.getElementById("myBtn");
if (x.addEventListener) {                    // 所有主流浏览器,除了 IE 8 及更早版本
    x.addEventListener("click", myFunction);
} else if (x.attachEvent) {                  // IE 8 及更早版本
    x.attachEvent("onclick", myFunction);
}

JavaScript HTML DOM 元素 (节点)

创建新的HTML元素(节点)-appendChild()用于添加新元素到尾部。-insertBefore()用于添加新元素到指定位置。
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
 
<script>
    var para = document.createElement("p");     //创建一个<p>标签
    var node = document.createTextNode("这是一个新的段落。");     //创建一个节点内容
    para.appendChild(node);       //为<p>标签添加节点内容

    var element = document.getElementById("div1");
    element.appendChild(para);     //将以上创立的节点及其内容添加到HTML元素中结尾处
</script>
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
 
<script>
    var para = document.createElement("p");
    var node = document.createTextNode("这是一个新的段落。");
    para.appendChild(node);

    var element = document.getElementById("div1");
    var child = document.getElementById("p1");
    element.insertBefore(para, child);            //将新节点及其内容添加到指定位置之前
</script>

移除已存在的元素-removeChild(child)

要移除一个元素,你需要知道该元素的父元素。
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
 
<script>
    var parent = document.getElementById("div1");
    var child = document.getElementById("p1");
    parent.removeChild(child);     //移除节点id为p1,是根据其父结点的函数removeChild()
</script>

替换 HTML 元素 - replaceChild()

<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
 
<script>
    var para = document.createElement("p");
    var node = document.createTextNode("这是一个新的段落。");
    para.appendChild(node);

    var parent = document.getElementById("div1");  //先获取待替换节点的父结点
    var child = document.getElementById("p1");
    parent.replaceChild(para, child);      //将id为p1的替换为新节点
</script>

JavaScript HTML DOM 集合(Collection)

获取文档所有的<p>元素,实际就是个数组,通过x[1]可以访问第二个元素
length属性为元素的数量
var x = document.getElementsByTagName("p");

HTMLCollection 与 NodeList 的区别

HTMLCollection 是 HTML 元素的集合。

NodeList 是一个文档节点的集合。

NodeList 与 HTMLCollection 有很多类似的地方。

NodeList 与 HTMLCollection 都与数组对象有点类似,可以使用索引 (0, 1, 2, 3, 4, ...) 来获取元素。

NodeList 与 HTMLCollection 都有 length 属性。

HTMLCollection 元素可以通过 name,id 或索引来获取。

NodeList 只能通过索引来获取。

只有 NodeList 对象有包含属性节点和文本节点。