JS用户界面事件(UI事件)

用户界面(User Interface,UI)事件负责响应用户与页面元素的交互。

焦点处理

焦点处理主要包括获取焦点(focus)和失去焦点(blur)事件类型。所谓焦点,就是激活表单字段,使其可以相应键盘事件。

focus

当单击或使用 Tab 键切换到某个表单元素或超链接对象时,会触发该事件。focus 事件是确定页面内鼠标当前定位的一种方式。在默认情况下,整个文档处于焦点状态,但是单击或使用 Tab 键可以改变焦点的位置。

blur

blur 事件类型表示在元素失去焦点时响应,它与 focus 事件类型是相对的,主要作用于表单元素和超链接对象。

【示例1】在下面示例中为所有输入表单元素绑定了 focus 和 blur 事件处理函数,设置当元素获取焦点时呈凸起显示,失去焦点时则显示为默认的凹陷效果。

<input type="text" />
<input type="text" />
<script>
    var o = document.getElementsByTagName("input");  //获取表单元素集合
    for (var i = 0; i < o.length; i ++ ) {  //遍历所有表单元素
        o[i].onfocus = function () {  //注册focus事件处理函数
            this.style.borderStyle = "outset";
        }
        o[i].blur = function () {  //注册focus事件处理函数
            this.style.borderStyle = "inset";
        }
    }
</script>

每个表单字段都有两个方法:focus() 和 blur(),其中 focus() 方法用于设置表单字段为焦点。

【示例2】在下面示例中设计在页面加载完毕后将焦点转移到表单中的第 1 个文本框字段中,让其准备接收用户输入。

<form id="myform" method="post" action="#">
    姓名<input type="text" name="name" /><br />
    密码<input type="password" name="pass" /><br />
</form>
<script>
    var form = document.getElementById("myform");
    var field = form.elements["name"];
    window.onload = function () {
        field.focus();
    }
</script>

如果是隐藏字段(<input type="hidden">)或者使用 CSS 的 display 和 visibility 隐藏字段显示,设置其获取焦点将引发异常。

blur() 方法的作用时从元素中移走焦点。在调用 blur() 方法时,并不会把焦点转移到某个特定的元素上,仅仅时将焦点移走。早期开发中有用户使用 blur() 方法代替 readonly 属性,创建只读字段。

选择文本

当在文本框或文本区域内选择文本时,将触发 select 事件。通过该事件可以设计用户选择操作的交互行为。

在 IE 9+、Opera、Firefox、Chrome 和 Safari 中,只有用户选择了文本且释放鼠标,才会触发 select 事件;但是在 IE8 及更早版本中,只要用户选择了一个字母,不必释放鼠标,就会触发 select 事件。另外,在调用 select() 方法时也会触发 select 事件。

【示例】在下面的示例中,当选择第 1 个文本框中的文本时,则在第 2 个文本框中会动态显示用户所选择的文本。

<input type="text" id="a" value="请随意选择字符串" />
<input type="text" id="b" />
<script>
    var a = document.getElementsByTagName("input")[0];
    // 获取第一个文本框的引用指针
    var b = document.getElementsByTagName("input")[1];
    // 获取第二个文本框的引用指针
    a.onselect = function(){  // 为第一个文本框绑定select事件处理函数
        if (document.selection){  // 兼容IE
            o = document.selection.createRange(); // 创建一个选择区域
            if(o.text.length > 0)  // 如果选择区域内存在文本
            b.value = o.text;   // 则把该区域内的文本赋值给第二个文本框
        }else{  // 兼容DOM
            p1 = a.selectionStart;  // 获取文本框中选择的初始位置
            p2 = a.selectionEnd;  // 获取文本框中选择的结束位置
            b.value = a.value.substring(p1, p2);
            // 截取文本框中被选取的文本字符串,然后赋值给第二个文本框
        }
    }
</script>

字段值变化监测

change 事件类型时在表单元素的值发生变化时触发,它主要用于 input、select 和 textarea 元素。对于 input 和 textarea 元素来说,当它们失去焦点且 value 值改变时触发;对于 select 元素,在其选项改变时触发,也就是不是去焦点,也会触发 change 事件。

示例1

在下面示例中,当在第 1 个文本框中输入或修改值时,则第 2 个文本框内会立即显示第 1 个文本框中的当前值。

<input type="text" id="a" />
<input type="text" id="b" />
<script>
    var a = document.getElementsByTagName("input")[0];
    var b = document.getElementsByTagName("input")[1];
    a.onchange = function(){  // 为第一个文本框绑定change事件处理函数
        b.value = this.value;   // 把第一个文本框中的值传递给第二个文本框
    }
</script>

示例2

下面示例演示了当在下拉列表框中选择不同的网站时,会自动打开该网站的首页。

<select>
    <option value="http://www.baidu.com/">百度</option>
    <option value="http://www.google.cn/">Google</option>
</select>
<script>
    var a = document.getElementsByTagName("select")[0];
    a.onchange = function(){
       window.open(this.value,"");   // 根据下拉列表框的当前值打开指定的网址
    }
</script>

示例3

在其他表单元素中也可以应用 change 事件类型。下面示例演示了如何在单选按钮选项组中动态显示变化的值。

<input type="radio" name="r" value="1"  checked="checked" /> 1
<input type="radio" name="r" value="2" /> 2
<input type="radio" name="r" value="3" /> 3
<script>
    var r = document.getElementsByTagName("input");
    for(var i = 0; i < r.length; i ++ ){
        r[i].onchange = function(){
            alert(this.value);
        }
    }
</script>

对于 input 元素来说,由于 change 事件类型仅在用户已经离开了元素且失去焦点时触发,所以当执行上面 3 个示例时会明显感觉延迟响应现象。为了更好地提升用户体验,很多时候会根据需要定义在按键松开或鼠标单击时执行响应,这样速度会快很多。

focus、blur 和 change 事件经常配合使用。一般可以使用 focus 和 blur 事件来以某种方式改变用户界面,要么是向用户给出视觉提示,要么是向界面中添加额外的功能。例如,为文本框显示一个下拉选项菜单。而 change 事件则经常用于验证用户在字段中输入的数据。

示例4

下面示例设计一个文本框,只允许用户输入数值。此时,可以利用 focus 事件修改文本框的背景颜色,以便更清楚的表明这个字段获得了焦点。可以利用 blur 事件恢复文本框的背景颜色,利用 change 事件在用户输入了非数字字符时再次修改背景颜色。

<form id="myform"  method="post" action="javascript:alert('表单提交啦!')">
    <p>
        <label for="comments">请输入数字:</label>
        <br />
        <input type="text" id="txtNumbers" name="numbers" />
    </p>
    <p>
        <input type="submit" value="提交表单" id="submit-btn" />
    </p>
</form>
<script>
    var form = document.getElementById("myform");
    var numbers = form.elements["numbers"];
    numbers.onfocus = function(event){
    event = event || window.event;
    var target = event.target || event.srcElement;
    target.style.backgroundColor = "yellow";
    }
    numbers.onblur = function(event){  
        event = event || window.event;
        var target = event.target || event.srcElement;
        if (/[^/d]/.test(target.value)){
            target.style.backgroundColor = "red";
        } else {
            target.style.backgroundColor = "";
        }
    }
    numbers.onchange = function(event){  
        event = event || window.event;
        var target = event.target || event.srcElement;
        if (/[^/d]/.test(target.value)){
            target.style.backgroundColor = "red";
        } else {
            target.style.backgroundColor = "";
        }
    }
    numbers.focus();
</script>

在上面代码中,onfocus 事件处理程序将文本框的背景颜色修改为黄色,以清楚地表示当前字段已经激活。onblur 和 onchange 事件处理程序则会在发现非数值字符时,将文本框背景色修改为红色。为了测试用户输入的是不是非数值,这里针对文本框的 value 属性使用了简单的正则表达式。而且,为确保无论文本框的值如何变化,验证规则始终如一,onblur 和 onchange 事件处理程序中使用了相同的正则表达式。

关于 blur 和 change 事件发生顺序并没有严格的规定,不同的浏览器没有统一规定。因此,不能假定这两个事件总会以某种顺序一次触发。

剪贴板数据

HTML 5 规范了剪贴板数据操作,主要包括以下 6 个剪贴板事件:

  • beforecopy:在发生复制操作前触发。
  • copy:在发生复制操作时发生。
  • beforecut:在发生剪切操作前触发。
  • cut:在发生剪切操作时触发。
  • beforepaset:在发生粘贴操作前触发。
  • paset:在发生粘贴操作时触发。

浏览器支持状态:IE、Safari 2+、Chrome 和 Firefox 3+,Opera 不支持访问剪贴板数据。

在 Safari、Chrome 和 Firefox 中,beforecopy、beforecut 和 beforepaste 事件只会显示针对文本框的上下文菜单的情况下触发。IE 则会在触发 copy、cut 和 paste 事件之前先行触发这些事件。

至于 copy、cut 和 paste 事件,只要是在上下文菜单中选择了响应选项,或者使用了相应的键盘组合键,所有浏览器都会触发它们。在实际的事件发生之前,通过 beforecopy、beforecut 和 beforepaste 事件可以在向剪贴板发送数据,或者从剪贴板取得数据之前修改数据。

使用 clipboardData 对象可以访问剪贴板中的数据。在 IE 中,可以任何状态下使用 window.clipboardData 访问剪贴板;在 Fiirefox 4+、Safari 和 Chrome 中,通过事件对象的 clipboardData 属性访问剪贴板,且只有在处理剪贴板事件期间,clipboardData 对象才有效。

clipboardData 对象定义了两个方法:

  • getData():从剪贴板中读取数据。包含 1 个 参数,设置取得的数据的格式。IE 提供两种数据格式:“text”和“URL”;Firefox、Safari 和 Chrome 中定义参数为 MIME 类型,可以用“text”代表“text/plain”。
  • setData():设置剪贴板数据。包含两个参数,其中第 1 个参数设置数据类型,第 2 个参数是要放在剪贴板中的文本。对于第 1 个参数,IE 支持“text”和“URL”,而 Safari 和 Chrome 仍然只支持 MIME 类型,但不再识别“text”类型。在成功将文本放到剪贴板中后,都会返回 true;否则,返回 false。

示例1

可以使用下面两个函数兼容 IE 和非 IE 的剪贴板数据操作。

var getClipboardText = function(event){
    var clipboardData =  (event.clipboardData || window.clipboardData);
    return clipboardData.getData("text");
}
var  setClipboardText = function(event, value){
    if (event.clipboardData){
        event.clipboardData.setData("text/plain", value);
    } else if (window.clipboardData){
        window.clipboardData.setData("text", value);
    }
}

在上面代码中,getClipboardText() 方法比较简单,它只要访问 clipboardData 对象,然后以 text 类型调用 getData() 方法;setClipboardText() 方法相对复杂,它在取得 clipboardData 对象之后需要根据不同的浏览器实现为 setData() 传入不同的类型。

示例2

下面示例利用剪贴板事件,当用户向文本框粘贴文本时,先检测剪贴板中的数据是否都为数字,如果不是数字,取消默认的行为,则禁止粘贴操作,这样可以确保文本框只能接收数字字符。

<script>
    var form = document.getElementById("myform");
    var field1 = form.elements[0];
    var getClipboardText = function(event){
        var clipboardData =  (event.clipboardData || window.clipboardData);
        return clipboardData.getData("text");
    }
    var  setClipboardText = function(event, value){
        if (event.clipboardData){
            event.clipboardData.setData("text/plain", value);
        } else if (window.clipboardData){
            window.clipboardData.setData("text", value);
        }
    }
    var  addHandler = function(element, type, handler){
        if (element.addEventListener){
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent){
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
    addHandler(field1, "paste", function(event){
        event = event || window.event;
        var text =  getClipboardText(event);
        if (!/^/d*$/.test(text)){
            if (event.preventDefault){
                event.preventDefault();
            } else {
                event.returnValue = false;
            }
        }
    })
</script>

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/23286.html

(0)
上一篇 2021年7月20日
下一篇 2021年7月20日

相关推荐

发表回复

登录后才能评论