表单字段们

text输入框

<input type="text" name='name'>
DOM操作
  • 设置文本框的值
    input.value='hello world'
  • 获取文本框的值
    input.value
<body>
<input type="text" name='name'>
<script>
	var elm = document.querySelector('input');
	input.value='hello world';
	console.log(input.value);
</script>
</body>
相关事件
  • input事件
    文本框中输入文本时触发
  • change事件
    文本框中输入的文本改变,且失去焦点(或回车)时触发
<body>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    elm.oninput = function(e){
        console.log(e.type,e.target.value);
    }
    elm.onchange = function(e){
        console.log(e.type,e.target.value);
    }
    </script>
</body>

在这里插入图片描述

  • textInput事件
    文本框内输入文本时触发。
    input事件什么区别?
    textInput事件处理程序只能用 DOM2级方法写(elm.addEventListener)。
    input事件处理程序既可以用 DOM2级方法写,也可以用DOM0级方法写(elm.onInput)
    还有么?
    在这里插入图片描述
    呃,没太懂?那试试 拼音输入法吧。
<body>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    elm.oninput = function(e){
        console.log(e.type,e.target.value);
    }
    const handleTextInput = function(e){
        console.log(e.type,e.target.value);
    }
    elm.addEventListener('textInput',handleTextInput,false);
    </script>
</body>

在这里插入图片描述
说到 拼音输入法,忽然想到 复合事件。

  • compositionstart事件
  • compositionupdate事件
  • compositionend事件
<body>
    <!-- <div id="root"></div> -->
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    const handleCompositionStart = function(e){
        console.log(e.type,e.target.value);
    }
    const handleCompositionUpdate = function(e){
        console.log(e.type,e.target.value);
    }
    const handleCompositionEnd = function(e){
        console.log(e.type,e.target.value);
    }
    elm.addEventListener('compositionstart',handleCompositionStart,false);
    elm.addEventListener('compositionupdate',handleCompositionUpdate,false);
    elm.addEventListener('compositionend',handleCompositionEnd,false);
    </script>
</body>

在这里插入图片描述

  • keypress事件
    按下键盘字符键触发
  • keydown事件
    按下键盘任意键都会触发
<body>
    <div id="root"></div>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    elm.onkeypress = function(e){
        console.log(e.type,e.key);
    }
    elm.onkeydown = function(e){
        console.log(e.type,e.key);
    }
    </script>
</body>

在这里插入图片描述

  • focus事件
    获得焦点时触发
  • blur事件
    失去焦点时触发
<body>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    elm.onfocus = function(e){
        console.log(e.currentTarget,'get focus');
    }
    elm.onblur = function(e){
        console.log(e.currentTarget,'lost focus');
    }
    </script>
</body>

在这里插入图片描述

  • select事件
    选中输入框中的文本时触发
<body>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    var elm = document.getElementById('name');
    elm.onselect = function(e){
        var value = e.currentTarget.value;
        var startIndex = e.currentTarget.selectionStart;
        var endIndex = e.currentTarget.selectionEnd;
        console.log('选中文本:',value.slice(startIndex,endIndex));
    }
    </script>
</body>

在这里插入图片描述

相关方法
  • focus()
    使获得焦点
//页面也加载,就将焦点转移至表单的第一个字段
<body>
    <input type="text" name='name' id='name' autocomplete="off">
    <script>
    window.onload = function(){
        var elm = document.getElementById('name');
        elm.focus();
    }
    </script>
</body>
  • blur()
    使失去焦点
  • select()
    选中全部文本
//页面一加载,就将焦点转移至第一个表单字段
//表单字段一获得焦点,就将框内的文本全部选中,方便用户删除并重新输入
<body>
    <input type="text" name='name' id='name' autocomplete="off" value='Nicholas'>
    <script>
    var elm = document.getElementById('name');
    window.onload = function(){
        elm.focus();
    }
    elm.onfocus = function(){
        elm.select();
    }
    </script>
</body>
相关属性
  • autofocus
    自动聚焦
<input type="text" name='name' id='name' value='Nicholas' autofocus>
  • autocomplete
    自动完成,也就是显示之前输入的值。
    有两个值:onoff,默认是on
    在这里插入图片描述
 <input type="text" name='name' id='name' value='Nicholas' autocomplete="off" >

submit按钮

生成提交按钮,有以下三种方式。

  • 第一种:input[type='submit']
<input type="submit" value='提交'>
  • 第二种:button[type='submit']
<button type='submit'>提交</button>
  • 第三种:input[type='image']
<input type="image" src='./imgs/submit.jpg'>

注意:不论以何种方式生成提交按钮,提交按钮必须嵌在form标签里,否则点击提交按钮无法提交表单数据。

相关事件
  • submit事件
    点击提交按钮时触发
    submit事件发生后,会发送http请求,并刷新页面
    http请求是get还是post,取决于form标签上的method属性值;
    http请求发给谁,form标签上action属性说了算。
    想了解更多,请移步表单Demo
<body>
        <form method='post' action='/addUser'>
            <label>名字: <input type="text" name='name'></label>
            <label>密码: <input type='password' name='pass' /></label>
            <input type="submit" value='注册'>
        </form>
<script>
    var form = document.forms[0];
    form.onsubmit = function(e){
        console.log(e.type);
    }
</script>
</body>
相关方法
  • submit()
    提交表单,但注意哈,不会触发submit事件。

reset按钮

重置按钮和提交按钮的情况几乎一样,也有三种生成方式,只不过typesubmit变成了reset

  • 第一种,input[type='reset']
<input type="reset" value="重置">
  • 第二种,button[type='reset']
 <button type='reset'>重置</button> 
  • 第三种,input[type='image']
<input type="image" src='./imgs/reset.jpg'>
相关事件
  • reset事件
    点击重置按钮时触发reset事件,整个表单数据会被清空。
    实际开发中,重置按钮用的不多,主要因为不实用。试想一下,你辛辛苦苦填了十几项,可能不小心重置了一下,一江春水付诸东流,不抓狂才怪。当然,你可以采用二次确认来避免用户的这种不小心。
<body>
    <div id="root"></div>
    <form>
        <label>名字:<input type="text" name='name' id='name' autocomplete="off"></label>
        <input type="reset" value="重置">
    </form>
    <script>
    var form = document.forms[0];
    form.onreset = function(e){
        console.log(e.type);
    }
    </script>
</body>
相关方法
  • reset()
    重置表单,也会触发reset事件

选择框

相关属性
  • select的属性
    • select.type
      有两个值:select-oneselect-multiple
      select-one 是单选;select-multiple是多选
    • select.multiple
      布尔值。多选是true,单选是false
    • select.size
      选择框可见的行数
    • select.options
      可选项
    • select.selectedIndex
      选中项所在索引,索引从0开始
  • option的属性
    • option.selected
      布尔值。选中是true,没有选中是false
    • option.index
      选项所在索引,索引从0开始
    • option.label
      <option></option>之间的文本值
    • option.text
      <option></option>之间的文本值
    • option.value
      optionvalue属性,则取value属性值;没有value属性,则取<option></option>之间的文本值。
<body>
    <form action="">
        <select name="fruits" id="fruits">
            <option value="grapefruit">葡萄柚</option>
            <option value="lime">酸橙</option>
            <option value="coconut" selected >椰子</option>
            <option value="mango">芒果</option>
        </select>
        <select name="citys" id="citys" size=4 multiple>
            <option value="shenzhen" selected>深圳</option>
            <option value="nanjing" selected>南京</option>
            <option value="hanzhou">杭州</option>
            <option value="nanchang">南昌</option>
        </select>
    </form>
    <script>
        var select = document.forms[0].elements[0];
        var selectedOption = select.options[select.selectedIndex];

        var multipleSelect = document.forms[0].elements[1];
        var selectedOptions = Array.prototype.slice.call(multipleSelect.options).filter(option => option.selected);
        console.log(selectedOptions);
    </script>
</body>
  • 获取选中项
    单选时,比较简单,select.options[select.selecteIndex]即可;
    多选时,稍微复杂一点点,遍历optionoption.selectedtrue则返回,
    Array.prototype.slice.call(multipleSelect.options).filter(option => option.selected)
相关事件
  • change事件
    选中项发生改变时触发
DOM操作
添加选项

首先,我们要生成一个新的option,有两种方式。

//第一种,使用document.createElement
        var option = document.createElement('option');
        option.appendChild(document.createTextNode('大连'));
        option.value = 'dalian';
//第二种,调用构造函数Option
        var option = new Option('大连','dalian');

然后,将新的option插入到选择框,也有两种方式。

//第一种,appendChild或insertBefore
select.appendChild(option);//插入末尾
//select.appendChild(option,select.options[1]);//插入指定位置
//第二种,调用add方法
select.add(option);//插入末尾
//select.add(option1,1);//插入指定位置
//select.add(option,select.options[1]);//插入指定位置

举例:新增选项 大连

在这里插入图片描述

<body>
    <form action="">
        <select name="citys" id="citys" size=4>
            <option value="shenzhen">深圳</option>
            <option value="nanjing">南京</option>
            <option value="hanzhou">杭州</option>
        </select>
    </form>
    <script>
        var select = document.forms[0].elements[0];
        var option = new Option('大连','dalian');
        select.insertBefore(option,select.options[1]);
        // select.add(option,1);
        // select.add(option,select.options[1]);
    </script>
</body>
删除选项

有三种方式

//第一种
select.removeChild(select.options[select.options.length-1]);
//第二种
select.remove(select.options.length-1);
//第三种
select.options[select.options.length-1] = null;

举例:删除选项 大连

在这里插入图片描述

<body>
    <form action="">
        <select name="citys" id="citys" size=4>
            <option value="shenzhen">深圳</option>
            <option value="nanjing">南京</option>
            <option value="hanzhou">杭州</option>
            <option value='dalian'>大连</option>
        </select>
    </form>
    <script>
        var select = document.forms[0].elements[0];
        // select.removeChild(select.options[select.options.length-1]);
        // select.remove(select.options.length-1);
        select.options[select.options.length-1] = null;
    </script>
</body>
移动选项

将已经存在的元素进行插入操作即可实现移动。

//杭州 这个选项 向前移动一个位置
        var select = document.forms[0].elements[0];
        var optionHZ = select.options[2];
        select.insertBefore(optionHZ,select.options[optionHZ.index-1]);
//杭州 这个选项 向后移动一个位置
        var select = document.forms[0].elements[0];
        var optionHZ = select.options[2];
        select.insertBefore(optionHZ,select.options[optionHZ.index+2]);

举例:将 杭州、大连 这两个选项交换位置

在这里插入图片描述

<body>
    <form action="">
        <select name="citys" id="citys" size=4>
            <option value="shenzhen">深圳</option>
            <option value="nanjing">南京</option>
            <option value="hanzhou">杭州</option>
            <option value='dalian'>大连</option>
        </select>
    </form>
    <script>
        var select = document.forms[0].elements[0];
        var optionHZ = select.options[2];
        var optionDL = select.options[select.options.length-1];
        // select.appendChild(optionHZ);
        // select.add(optionHZ);
        select.insertBefore(optionDL,optionHZ);
    </script>
</body>
自定义选择框的实现
//index.js
import React from "react";
import ReactDOM from "react-dom";
import './index.css';

function ListItem(props){
    const {value,label} = props;
    
    return (
        <li value={value}>{label}</li>   
        )
}

class Selector extends React.Component{
    constructor(props){
        super(props);
        // this.handleMouseDown = this.handleMouseDown.bind(this);
        this.handleClick = this.handleClick.bind(this);
    }
    handleMouseDown(e){
        this.props.selectItem(e.target.textContent);
    }
    handleClick(e){
        this.props.selectItem(e.target.textContent);
    }
    render(){
        const items = this.props.items;
        return (
            <ul className='selector'
                // onMouseDown={this.handleMouseDown}
                onClick={this.handleClick}
                >

                {
                    items.map(item => (
                        <ListItem key={item.value}
                                value={item.value}
                                label={item.label}/>
                    ))
                }
            </ul>
        )        
    }
}

class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            value:'请选择',
            isOpen:false
        }
        this.container = React.createRef();
        this.handleClick = this.handleClick.bind(this);
        this.handleOutsideClick = this.handleOutsideClick.bind(this);
        // this.handleFocus = this.handleFocus.bind(this);
        // this.handleBlur = this.handleBlur.bind(this);
        this.selectItem = this.selectItem.bind(this);
    }
    // handleFocus(){
    //     clearTimeout(this.timeId);
    // }
    // handleBlur(){
    //     this.timeId = setTimeout(() => {
    //         this.setState({
    //             isOpen:false
    //         })
    //     })
    //     // },100)
    // }
    handleClick(){
        this.setState(currentState => ({
            isOpen:!currentState.isOpen
        }))
    }
    handleOutsideClick(e){
        if(this.state.isOpen && !this.container.current.contains(e.target)){
            this.setState({
                isOpen:false
            })
        }
    }
    selectItem(value){
        this.setState({
            value
        })
    }
    componentDidMount(){
        window.addEventListener('click',this.handleOutsideClick,false);
    }
    componentWillUnmount(){
        window.removeEventListener('click',this.handleOutsideClick,false);
    }
    render(){
        const {items} = this.props;
        const {value,isOpen} = this.state;
        return (
            <div className='container' ref={this.container}
                // onFocus={this.handleFocus}
                // onBlur={this.handleBlur}
            >
            <input type='button'
                    value={value}
                    onClick={this.handleClick}
                    />
            {
                isOpen && <Selector items={items}
                                    selectItem={this.selectItem}/>
            }
        </div>
        )
    }
}

const items = [
    {value:'sz',label:'深圳'},
    {value:'hz',label:'杭州'},
    {value:'nj',label:'南京'}
]
ReactDOM.render(
    <App items={items}/>,
    document.getElementById('root')
)
//index.css
.container{
    display:inline-block;
}
.selector{
    list-style:none;
    margin:0px 15px;
    padding:0px;
    border:1px solid lightgrey;
    width:80px;
    text-align:left;
    background-color:#fff;
    box-shadow:1px 1px 1px grey;
    font-size:14px;
    border-radius: 2px;
    position:absolute;
}

.selector li:hover{
    cursor:pointer;
    background:lightgrey;
}
.selector li{
    padding-left:3px;
}

input{
    display:block;
    margin:5px;
}
无障碍访问的实现

鼠标操作时,整个功能是OK的,但键盘操作时,功能就有问题了。

  • 鼠标操作
    在这里插入图片描述
  • 键盘操作
    在这里插入图片描述
    这是因为,键盘操作tab切换焦点不会触发click事件,所以不会调用handleOutsideClick来关闭选项。
    于是添加blurfocus事件来修复以上问题。
    在修复的过程中,遇到一个问题:blur事件会先于click触发,导致选项一被点击,选项面板就关闭了。
    在这里插入图片描述
    有两个解决方法。
  • setTimeout的延时时间长一些,比如200ms
    100ms不够无法解决问题;500ms长了点,反应迟钝。总之,延时时间不好确定,治标不治本。
  • ul上的click事件改用mousedown事件
    效果好很多

主要是针对Selector组件、App组件的修改。

class Selector extends React.Component{
    constructor(props){
        super(props);
        this.handleMouseDown = this.handleMouseDown.bind(this);
    }
    handleMouseDown(e){
        this.props.selectItem(e.target.textContent);
    }
    render(){
        const items = this.props.items;
        return (
            <ul className='selector'
                onMouseDown={this.handleMouseDown}
                >

                {
                    items.map(item => (
                        <ListItem key={item.value}
                                value={item.value}
                                label={item.label}/>
                    ))
                }
            </ul>
        )        
    }
}

class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            value:'请选择',
            isOpen:false
        }
        this.container = React.createRef();
        this.handleClick = this.handleClick.bind(this);
        this.handleOutsideClick = this.handleOutsideClick.bind(this);
        this.handleFocus = this.handleFocus.bind(this);
        this.handleBlur = this.handleBlur.bind(this);
        this.selectItem = this.selectItem.bind(this);
    }
    handleFocus(){
        clearTimeout(this.timeId);
    }
    handleBlur(){
        this.timeId = setTimeout(() => {
            this.setState({
                isOpen:false
            })
        })
    }
    handleClick(){
        this.setState(currentState => ({
            isOpen:!currentState.isOpen
        }))
    }
    handleOutsideClick(e){
        if(this.state.isOpen && !this.container.current.contains(e.target)){
            this.setState({
                isOpen:false
            })
        }
    }
    selectItem(value){
        this.setState({
            value
        })
    }
    componentDidMount(){
        window.addEventListener('click',this.handleOutsideClick,false);
    }
    componentWillUnmount(){
        window.removeEventListener('click',this.handleOutsideClick,false);
    }
    render(){
        const {items} = this.props;
        const {value,isOpen} = this.state;
        return (
            <div className='container' ref={this.container}
                onFocus={this.handleFocus}
                onBlur={this.handleBlur}
            >
            <input type='button'
                    value={value}
                    onClick={this.handleClick}
                    />
            {
                isOpen && <Selector items={items}
                                    selectItem={this.selectItem}/>
            }
        </div>
        )
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值