javascript高级程序设计学习笔记(六)---表单脚本

表单脚本

表单基础

表单由< form >来表示。但是在JavaScript中,表单时HTMLFormElement类型。属性;

  • target,用于发送请求和接收响应的窗口名称
  • reset(),将所有表单域重置为默认值
  • submit(),提交表单 name,表单名称
  • method,要发送的HTTP请求类型
  • length,表单中控件的数量
  • action,接受请求的URL
  • elements,表单中所有控件的集合

可以使用document.forms[]获取页面的所有表单

提交表单

  • 隐式提交

    在操作过程中通过控件的操作来提交表单(敲击回车来提交表单),其需要满足以下的条件:

    表单有非禁用的提交按键
    没有提交按键时,不超过一个类型为 text search url email password date time number 的 input 元素
    提交过程细节

     提交过程分为两个阶段,
     第一个阶段是更具表单 enctype 指定的值构建要提交的数据,
     第二个阶段是使用指定的方法(method)发送数据到 action 指定的目标。
    

    构建提交数据,从可提交元素中提取数据组成指定数据结构过程(可提交元素有 button input keygen object select textarea)

    编码方式(enctype)所支持的形式:

    • application/x-www-form-urlencoded (默认,数据格式为 & 分隔的键值对)

    • multipart/form-data (IFC 2388 字节流形式,例如文件上传所使用的数据编码形式)

    • text/plain
      (回车换行符分隔的键值对)

      特殊案例一

      当一个表单元素 name=“isindex” 并且 type=“text” 而且满足如下要求时:

      编码格式为 application/x-www-form-urlencoded
      作为表单的第一个元素
      则提交时只发送 value 值,不包含 name。
      
<form action="./api" method="post">
		  <input name="isindex">
		  <input name="a">
		  <button>submit</button>
		</form>
	
  • submit 接口

    form.submit() 可以通过调用接口submit()直接提交表单,在提交表单时均会触发一个 onsubmit 表单提交事件,在这个事件中 women 可以做下面的事件:

    提交前的数据验证
    阻止事件的默认行为来取消表单的提交(例如当验证失败时)

form.addEventListener(
	  'submit', function(event) {
    
    
	    var notValid = false;
	    var elements = event.target.elements;
	
	    // 自定义验证
	
	    if (notValid) {
    
    
	      // 取消提交
	      event.preventDefault();
	    }
	  }
	)

无刷新表单提交范例
常用的方式是通过 AJAX 进行实现,这里我们使用 iframe 来做中介代理实现。
在这里插入图片描述

所需知识点:

form
target
iframe
<iframe name="targetFrame" class="f-hidden" style="display:none" id="result">
	
	<form action="./api" method="post" target="targetFrame">
	  <input name="isindex">
	  <input name="a">
	  <button>submit</button>
	</form>
	var frame = document.getElementById('result');
	frame.addEventListener(
	  'load', function(event) {
    
    
	    try {
    
    
	      var result = JSON.parse(
	        frame.contentWindow.document.body.textContent
	      );
	
	      // 还原登陆按钮状态
	      disabledSubmit(false);
	
	      // 识别登陆结果
	      if (result.code === 200) {
    
    
	        showMessage('j-suc', 'success');
	        form.reset();
	      }
	    } catch(ex) {
    
    
	      // 忽略操作
	    }
	  }
	)

使用< input >或< button>提交表单,将其type设置为submit。

<input type="submit" value="Submit Form">
<button type="submit">Submit Form< /button>

使用事件绑定,阻止事件的默认行为,可以取消表单提交。

var form = document.getElementById("myForm")
EventUtil.addHandle(form,'submit',function(event){
    
    
    even = EventUtil.getEvent(event);
    EventUtil.preventDefault(event);
})
form.submit()

解决重复提交表单:在第一次提交表单后禁用提交按钮,或者用onsubmit事件处理程序取消后续表单提交操作

重置表单

重置表单:

 <input type="reset" value="Reset Form">
 <button type="reset">Reset Form</button>

组织重置表单:

var form = document.getElementById("myForm")
EventUtil.addHandle(form,'reset',function(event){
    
    
    even = EventUtil.getEvent(event);
    EventUtil.preventDefault(event);
});
form.reset();

表单字段

elements属性是表单中所有元素的集合。该集合包含表单中所有的字段。

var form = document.getElementById("form1");
var field1 = form.elements[0];
var field2 = form.elements['textbox1'];
var fieldCount = form.elements.length;
  • 共有的表单字段属性
    • disabled,表示当前字段是否被禁用
    • form,指向当前字段所属表单的指针
    • name,当前字段的名称
    • readOnly,表示当前字段是否只读
    • type,当前字段的类型
    • value,当前字段将被提交给服务器的值

避免多次提交表单:

  EventUtil.addHandler(form,'submit',function(event){
    
    
      event = EventUtil.getEvent(event);
      var target = EventUtil.getTarget(event);
  
      var btn = target.elements['submit-btn'];
  
      // 禁用
      btn.disabled = true;
  });

一般不通过监听click事件来实现上面功能,因为不同浏览器,可能有的在触发submit事件之前触发click,有的则相反。且只有在包含提交按钮情况下,才有可能触发表单的submit事件。

  • 共有的表单字段方法
    • focus,用于将浏览器的焦点设置到表单字段,激活表单字段,响应键盘事件
    • blur
  EventUtil.addHandler(window,"load",function(event){
    
    
      var element = document.forms[0].elements[0];
      if(element.autofocus !== true){
    
    
          element.focus();
          console.log('focus');
      }
  })
  • 共有的表单字段事件
    • blur,当前字段失去焦点时触发
    • change,对于input和textarea元素,在失去焦点且value值改变时触发,对于select元素,在选项改变时触发
    • focus,当前字段获取焦点时触发
  var textbox = document.forms[0].elements[0];
  EventUtil.addHandler(textbox,"focus",function(event){
    
    
      event = EventUtil.getEvent(event);
      var target = EventUtil.getTarget(event);
      if(target.style.backgroundcolor != "red"){
    
    
          target.style.backgroundcolor = "yellow"
      }
  });
  
  
  EventUtil.addHandler(textbox,"blur",function(event){
    
    
      event = EventUtil.getEvent(event);
      var target = EventUtil.getTarget(event);
      if(/[^\d]/.test(target.value)){
    
    
          target.style.backgroundcolor = "red"
      }else{
    
    
          target.style.backgroundcolor = "yellow"
      }
  });
  
  EventUtil.addHandler(textbox,"change",function(event){
    
    
      event = EventUtil.getEvent(event);
      var target = EventUtil.getTarget(event);
      if(/[^\d]/.test(target.value)){
    
    
          target.style.backgroundcolor = "red"
      }else{
    
    
          target.style.backgroundcolor = ""
      }
  });
  • 应用
//获取表单
var form = document.forms.loginForm;
var message = document.getElementById('message');
//展示信息
function showMessage(class, message) {
    
    
  if(!class) {
    
    
    message.innerHTML = "";
    message.classList.remove('j-suc');
    message.classList.remove('j-err');
  } else {
    
    
    message.innerHTML = message;
    message.classList.add(class);
  }
}
//表单invalid输入
function invalidInput (node, message) {
    
    
  showMessage('j-err', message);
  node.classList.add('j-err');
  node.focus();
}
//清楚invalid输入
function clearInvalid(node){
    
    
  showMessage();
  node.classList.remove('j-err');
}

function disabledSubmit(disabled) {
    
    
  form.loginBtn.disabled = !!disabled;
  var method = !disabled ? 'remove' : 'add';
  form.loginBtn.classList[method]('j-disabled');
}

// 验证手机号码(系统自带方法)
form.telephone.addEventListener(
  'invalid', function(event) {
    
    
    event.preventDefault();
    invalidInput(form.telephone, 'invalid mobile number');
  }
);

// 验证密码
form.addEventListener(
  'submit', function(event) {
    
    
  //获取密码
    var input = form.password;
    var password = input.value;
    errorMessage = '';
    //验证长度
    if (password.length < 9) {
    
    
      errorMessage = 'password less than 9 char';
    } else if (!/\d./test(password) || !/[a-z]/i.test(password)) {
    
    
      errorMessage = 'password must contains number and letter'
    }

    if (!errorMessage) {
    
    
    //阻止提交
      event.preventDefault();
      invalidInput(input, errorMessage);
      return;
    }
  }
);
// 提交表单
form.addEventListener(
  'submit', function(event){
    
    
  //加密处理
    input.value = md5(password);
    disabledSubmit(true);
  }
);
// 状态恢复
form.addEventListener(
  'focus', function(event) {
    
    
    // 错误还原
    clearInvalid(event.target);
    // 还原登陆按钮状态
    disabledSubmit(false);
  }
)

文本框脚本

input元素的单行文本框—type为text,

  • size限定文本框显示的字符数
  • value设置初始值
  • maxlength指定最大字符数

textarea 元素

  • name
  • value (用户输入信息)
  • select() (全选当前输入的内容)
  • selectionStart 选中的内容的起始位置,无选中时返回当前光标所在位置)
  • selectionEnd (选中内容结束位置,无选中时返回光标位置)
  • selectionDirection (选取方向 forward backward)
  • setSelectionRange(start,end[, direction]) (使用程序选中内容)
  • setRangeText(replacement[, start, end, [mode]]) (设置内容范围)

selection
表示选择区域,对于 input 元素同样有效。

selectionDirection 主要是用于在使用 SHIFT 键与方向键组合选取时的选取方向。设置为 forward 时选取移动的方向为 selectionEnd 设置为 backward 时移动方向为 selectionStart。

@输入提示示例
所需知识点:

oninput
selectionStart
setRangeText

textarea.addEventListener(
  'input', function(event) {
    
    
    var target = event.target,
        cursor = target.selectionStart;
    if(target.value.charAt(cursor-1) === '@') {
    
    
      doShowAtList(functi=on(name){
    
    
        var end = cursor + name.length;
        target.setRangeText(
          name, cursor, end, 'end'
        );
      });
    }
  }
);

选择文本

input和textarea都支持select()方法

var textbox = document.forms[0].elements[0];
EventUtil.addHandler(textbox,"focus",function(event){
    
    
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
    target.select()
});
  • 选择事件

    IE9+,Opera、FireFox、Chrome和Safari中,只有选择了文本才触发select事件

var textbox = document.forms[0].elements[0];
  EventUtil.addHandler(textbox,"focus",function(event){
    
    
       alert(textbox.value)
  });
  • 取得选择的文本
    • selectionStart
    • selectionEnd
  var textbox = document.forms[0].elements[0];
  function getSelectedText(textbox){
    
    
      return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd)
  }
  • 选择部分文本
  setSelectionRange()
  var textbox = document.forms[0].elements[0];
  textbox.value = "hello world";
  textbox.setSelectionRange(0,textbox.value);
  textbox.setSelectionRange(0,2);

过滤输入

  • 屏蔽字符

    响应向文本框插入字符的是keypress事件。可以通过组织这个事件的默认行为来屏蔽字符。

  EventUtil.addHandler(textbox,"keypress",function(event){
    
    
      event = EventUtil.getEvent(event);
      var target = EventUtil.getTarget(event);
      var charCode = EventUtil.getCharCode(event);
      if(!/\d/.text(String.fromCharCode(charCode))&&charCode>9&&!event.ctrlKey){
    
    
          EventUtil.preventDefault(event)
      }
  });
  • 操作剪贴板

6个剪贴板事件

  • beforecopy,发生赋值操作前触发
  • copy,发生复制操作时触发
  • beforecut,剪切操作前触发
  • cut,剪切时触发
  • beforepaste,粘贴操作前触发
  • paste,粘贴时触发

使用clipboardData对象访问剪贴板中的数据。只有在处理剪贴板事件期间有效。存在三个方法:

  • getData()
  • setData()
  • clearData()
 var EventUtil = {
    
    
      getClipboardText:function(event){
    
    
          var clipboardData = (event.clipboardData||window.clipboardData):
          return clipboardData.getData("text");
      },
  
      setClipboardText:function(event,event){
    
    
          if(event.clipboardData){
    
    
              return event.clipboardData.setData("text/plain",value);
          }else if(window.clipboardData){
    
    
              return window.clipboardData.setData("text",value)
          }
      },
  
  
  }
  • 自动切换焦点

    在前一个文本框字符达到最大数量后,自动将焦点切换到下一文本框。

 (function () {
    
    
      function tabForward(event) {
    
    
          event = EventUtil.getEvent(event);
          var target = EventUtil.getTarget(event);
  
          if(target.value.length == target.maxLength){
    
    
              var form = target.form;
              for(var i=0,len=form.elements.length;i<len;i++){
    
    
                  if(form.elements[i]==target){
    
    
                      if(form.elements[i+1]){
    
    
                          form.elements[i+1].focus();
                      }
                      return;
                  }
                  
              }
          }
      }
  })
  • HTML5约束验证
    • button
    • input
    • select
    • textarea

以下情况不可以做验证

  • input 元素在类型是 hidden, reset,
  • button 时 button 元素在类型为 reset, button 时
  • input 与 textarea 当属性为 readonly 时
  • 当元素为 datalist 的子孙节点时
  • 当元素被禁用时 disabled 的状态

属性
验证涉及到以下的以下属性,在每一个可以验证的元素上均可以调用对于的属性或通过接口进行操作:

  • willValidate (表明此元素在表单提交时是否会被验证)
  • checkValidity() (用于验证元素,返回 true当验证通过,或者触发 invalid 事件)
  • validity (存储验证结果)
  • validationMessage (显示验证异常信息)
  • setCustomValidity(message) (自定义验证错误信息)

自定义异常范例
涉及到的知识点:

oninvalid
setCustomValidity
<form action="./api" method="post">
  <label>Name: <input name="username" required></label>
  <button>submit</button>
</form>
input.addEventListener(
  'invalid', function(event){
    
    
    var target = event.target;
    if (target.validity.valueMissing) {
    
    
      target.setCustomValidity('Name is missing');
    }
  }
)

禁止验证范例

使用 form 中 novalidate 属性来禁止表单提交的验证。

<form action="./api" method="post" novalidate>
  <label>Mobile: <input name="mobile" type="number"></label>
  <button>submit</button>
</form>
- 必填字段
  required属性
 <input type="text" name="username" required>
  • 其他输入类型
<input type="email" name="email" >
  <input type="url" name="homepage" >
  • 数值范围
  <input type="number" name="count" min="0" max="100" step="5">
  • 禁用验证
  <form method="post" action="signup.php" novalidate> < /form>

选择框脚本

selected的方法和属性有:

  • add(new,relOption),向控件中插入新option元素,位置在相关项之前
  • multiple,表示是否允许多项选择
  • options,空间中所有options元素的HTMLCollection
  • remove(index),移除给定位置
  • selectedIndex,基于0的选中项的索引
  • size,选择框可见的行数

option的方法和属性:

  • index,当前选项的options集合中的索引

  • label,当前选项的标签

  • selected,表示当前选项是否被选中

  • text,选项的文本

  • value,选项的值

  • 选择选项

只允许选择一项的选择框,使用selectedIndex访问选中项。

 var selectedOption = selectbox.options[selectbox.selectedIndex];
  var selectedIndex = selectbox.selectedIndex;
  var selectedOption = selectbox.options[selectedIndex];

另一种方式:取得某一项的引用,将其selected设置为true。
在允许多选的选择框中设置选项的selected属性,不会取消对其他选中项的选择。但是在单选中,修改则会取消对其他选项的选择。

  • 添加选项

方法一

 var selectbox = document.getElementById("selLocation");
  var newOption = document.createElement("option");
  newOption.appendChild(document.createTextNode("Option text"));
  newOption.setAttribute("value","Option value");
  
  selectbox.appendChild(newOption)

方法二:
使用Option构造函数创建新选项,

 var newOption = new Option("Option text","Option value"):
  selectbox.appendChild(newOption)

方法三:
使用add()方法。接受参数:要添加的新选项和将位于新选项之后的选项。

  var newOption = new Option("Option text","Option value");
  selectbox.add(newOption,undefined)
  • 移除选项
  selectbox.removeChild(selectbox.option[0]);
  selectbox.remove(0)
  function clearSelectbox(selectbox){
    
    
  	for(var i=0,len=selectbox.option.length;i<len;i++){
    
    
  		selectbox..remove(i);
  	}
  }
  • 移动和重排选项

使用DOM的appendChild方法,可以将第一个选择框中的选项直接移动到第二个选择框中。

  var selectbox1 = document.getElementById("selLocations1");
  var selectbox2 = document.getElementById("selLocations2");
  selectbox2.appendChild(selectbox1.options[0]);

会重置每一个选项的index属性。

在选择框向前移动一个选项的位置:

  var optionToMove = selectbox.options[1];
  selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index-1]};

富文本编辑

本质:在页面中嵌入一个包含空HTML页面的iframe,通过设置designMode属性,这个空白的HTML页面可以被编辑,而编辑对象则是该页body元素的HTML代码。把designMode设置为on,可以编辑,但只要在页面完全加载后才能设置这个属性。

  • 操作富文本

    使用document.execCommand()事项交互。传递参数:要执行的命令名称、表示浏览器是否应该我为当前命令提供用户界面的布尔值和执行命令必须的一个值。
    命令:

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ningpeixi679/article/details/113127730