JavaScript(19):HTML DOM 事件



一、HTML DOM 事件

1、HTML 事件属性

如需向 HTML 元素分配 事件,您可以使用事件属性。

向 button 元素分配 onclick 事件:

<button onclick="displayDate()">点这里</button> //名为 displayDate 的函数将在按钮被点击时执行。

2、使用 HTML DOM 来分配事件

向 button 元素分配 onclick 事件:按钮点击时Javascript函数将会被执行。

<script>
    document.getElementById("myBtn").onclick=function(){displayDate()}; //名为 displayDate 的函数被分配给 id="myBtn" 的 HTML 元素。
</script>

3、onload 和 onunload 事件

onload 和 onunload 事件会在用户进入或离开页面时被触发。

onload 事件可用于检测访问者的浏览器类型和浏览器版本,并基于这些信息来加载网页的正确版本。

onload 和 onunload 事件可用于处理 cookie。

<body onload="checkCookies()">

4、onchange 事件

onchange 事件常结合对输入字段的验证来使用。

下面是一个如何使用 onchange 的例子。当用户改变输入字段的内容时,会调用 upperCase() 函数。

<input type="text" id="fname" onchange="upperCase()">

5、onmouseover 和 onmouseout 事件

onmouseover 和 onmouseout 事件可用于在用户的鼠标移至 HTML 元素上方或移出元素时触发函数。

<div onmouseover="mOver(this)" onmouseout="mOut(this)" style="background-color:#D94A38;width:120px;height:20px;padding:40px;">Mouse Over Me</div>
<script>
  function mOver(obj){
    obj.innerHTML="Thank You"
  }
  function mOut(obj){
    obj.innerHTML="Mouse Over Me"
 }
</script>

6、onmousedown、onmouseup 以及 onclick 事件

onmousedown, onmouseup 以及 onclick 构成了鼠标点击事件的所有部分。

首先当点击鼠标按钮时,会触发 onmousedown 事件;当释放鼠标按钮时,会触发 onmouseup 事件;最后,当完成鼠标点击时,会触发 onclick 事件。

<div  onmousedown="mDown(this)"  onmouseup="mUp(this)"  style="background-color:#D94A38;width:200px;height:50px;padding-top:25px;text-align:center;">
点击这里
</div>

<script>
 function mDown(obj)
 {
   obj.style.backgroundColor="#1ec5e5";
   obj.innerHTML="松开鼠标"
 }

 function mUp(obj)
 {
   obj.style.backgroundColor="#D94A38";
   obj.innerHTML="谢谢你"
 }
</script>

二、HTML DOM 事件监听器

1、addEventListener() 语法

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

语法:element.addEventListener(event, function, useCapture);

  • 第一个参数是事件的类型 (如 "click" 或 "mousedown").
  • 第二个参数是事件触发后调用的函数。
  • 第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。

注意:不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。

2、向原元素添加事件句柄

当用户点击元素时弹出 "Hello World!" :

element.addEventListener("click", function(){ alert("Hello World!"); });

在用户点击按钮时触发监听事件:

document.getElementById("myBtn").addEventListener("click", displayDate);

function displayDate() {
    alert ("Hello World!");
}

3、向同一个元素中添加多个事件句柄

  • 你可以向同个元素添加多个同类型的事件句柄,如:两个 "click" 事件。
  • addEventListener() 方法添加的事件句柄不会覆盖已存在的事件句柄。
element.addEventListener("click", myFunction);
element.addEventListener("click", mySecondFunction);

4、向一个元素添加多个事件句柄

element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
element.addEventListener("mouseout", myThirdFunction);

5、向任何 DOM 对象添加事件监听

不仅仅是 HTML 元素。如: window 对象。

addEventListener() 方法允许你在 HTML DOM 对象添加事件监听, HTML DOM 对象如: HTML 元素, HTML 文档, window 对象。或者其他支出的事件对象如: xmlHttpRequest 对象。

当用户重置窗口大小时添加事件监听:

window.addEventListener("resize", function(){
    document.getElementById("demo").innerHTML = sometext;
});

6、传递参数

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

element.addEventListener("click", function(){ myFunction(p1, p2); });

7、事件冒泡或事件捕获

addEventListener() 方法可以更简单的控制事件(冒泡与捕获)。当你使用 addEventListener() 方法时, JavaScript 从 HTML 标记中分离开来,可读性更强, 在没有控制HTML标记时也可以添加事件监听。

事件传递有两种方式:冒泡与捕获。

事件传递定义了元素事件触发的顺序。 如果你将元素插入到元素中,用户点击元素, 哪个元素的 "click" 事件先被触发呢?

  1. 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即:元素的点击事件先触发,然后会触发元素的点击事件。
  2. 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:元素的点击事件先触发 ,然后再触发元素的点击事件。

addEventListener() 方法可以指定 "useCapture" 参数来设置传递类型:

addEventListener(event, function, useCapture); 默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。

document.getElementById("myDiv").addEventListener("click", myFunction, true);

8、removeEventListener() 方法

你可以使用 removeEventListener() 方法来移除事件的监听。

removeEventListener() 方法移除由 addEventListener() 方法添加的事件句柄:

element.removeEventListener("mousemove", myFunction);

三、跨浏览器的事件注册函数

js中事件监听方法总共有三种,分别如下所示:

  • element.addEventListener(type, listener[, useCapture]); // IE6~8不支持,支持事件冒泡和捕获
  • element.attachEvent(’on’ + type, listener); // IE6~10,IE11不支持,只支持事件冒泡
  • element[’on’ + type] = function(){} // 所有浏览器,只支持事件冒泡,不支持对同一个元素的同一个事件注册多个事件监听器

不是所有的事件都能冒泡,例如:blur、focus、load、unload。

1、绑定事件

IE 8 及更早 IE 版本,Opera 7.0及其更早版本不支持 addEventListener() 和 removeEventListener() 方法。但是,对于这类浏览器版本可以使用 detachEvent() 方法来移除事件句柄:

  • element.attachEvent(event, function);
  • element.detachEvent(event, function);
function addHandler(element, type, handler) { //绑定事件
    if (element.addEventListener) { // IE9以下不兼容
        element.addEventListener(type, handler, false)
    } else if (element.attachEvent) { //IE独有
        element.attachEvent('on' + type, handler)
    } else {
        element['on' + type] = handler; //一个元素只能绑定一个处理程序
    }
}

2、取消绑定事件

和绑定事件的处理基本一致,有一个注意点:传入的handler必须与绑定事件时传入的相同(指向同一个函数)

function removeHandler(element, type, handler) { //移除事件
    if (element.removeEventListener) { //addEventListener
        element.removeEventListener(type, handler, false)
    } else if (element.detachEvent) { //attachEvent
        element.detachEvent('on' + type, handler)
    } else {
        element['on' + type] = null;

    }
}

3、阻止默认行为

function preventDefault(event) {
    if (event.preventDefault) {
        event.preventDefault()
    } else {
        event.returnValue = false;
    }
}

4、停止冒泡

function stoppropagation(event) {
    if (event.stopPropagation) {
        event.stopPropagation()
    } else {
        evenvt.cancelBubble = true;
    }
}

5、获取事件和目标

function getEvent(event) {
    return event ? event: window.event;
}
function getTarget(event) {
    return event.target || event.srcElement
}

6、Handler.js—可移植事件处理程序注册函数

/*   * Handler.js -- Portable event-handler registration functions   *   * This module defines event-handler registration and deregistration functions   * Handler.add( ) and Handler.remove( ). Both functions take three arguments:   *   *     element: the DOM element, document, or window on which the handler   *           is to be added or removed.   *   *     eventType: a string that specifies the type of event for which the   *           handler is to be invoked. Use DOM-standard type names, which do   *           not include an "on" prefix. Examples: "click", "load", "mouseover".   *   *     handler: The function to be invoked when an event of the specified type   *           occurs on the specified element. This function will be invoked as   *           a method of the element on which it is registered, and the "this"   *           keyword will refer to that element. The handler function will be   *           passed an event object as its sole argument. This event object will   *           either be a DOM-standard Event object or a simulated one. If a   *           simulated event object is passed, it will have the following DOM-   *           compliant properties: type, target, currentTarget, relatedTarget,   *           eventPhase, clientX, clientY, screenX, screenY, altKey, ctrlKey,   *           shiftKey, charCode, stopPropagation( ), and preventDefault( )   *   * Handler.add( ) and Handler.remove( ) have no return value.   *   * Handler.add( ) ignores duplicate registrations of the same handler for   * the same event type and element. Handler.remove( ) does nothing if called   * to remove a handler that has not been registered.   *   * Implementation notes:   *   * In browsers that support the DOM standard addEventListener( ) and   * removeEventListener( ) event-registration functions, Handler.add( ) and   * Handler.remove( ) simply invoke these functions, passing false as the   * third argument (meaning that the event handlers are never registered as   * capturing event handlers).   *   * In versions of Internet Explorer that support attachEvent( ), Handler.add( )   * and Handler.remove() use attachEvent( ) and detachEvent( ). To   * invoke the handler function with the correct this keyword, a closure is   * used. Since closures of this sort cause memory leaks in Internet Explorer,   * Handler.add( ) automatically registers an onunload handler to deregister   * all event handlers when the page is unloaded. To keep track of   * registered handlers, Handler.add( ) creates a property named _allHandlers on   * the window object and creates a property named _handlers on any element on   * which a handler is registered.   */
var Handler = {};

// In DOM-compliant browsers, our functions are trivial wrappers around
// addEventListener( ) and removeEventListener( ).
if (document.addEventListener) {         Handler.add = function(element, eventType, handler) {                 element.addEventListener(eventType, handler, false);         };         Handler.remove = function(element, eventType, handler) {                 element.removeEventListener(eventType, handler, false);         };
}
// In IE 5 and later, we use attachEvent( ) and detachEvent( ), with a number of
// hacks to make them compatible with addEventListener and removeEventListener.
else if (document.attachEvent) {         Handler.add = function(element, eventType, handler) {                 // Don't allow duplicate handler registrations                 // _find( ) is a private utility function defined below.                 if (Handler._find(element, eventType, handler) != -1) return;                 // To invoke the handler function as a method of the                 // element, we've got to define this nested function and register                 // it instead of the handler function itself.                 var wrappedHandler = function(e) {                         if (!e) e = window.event;                         // Create a synthetic event object with partial compatibility                         // with DOM events.                         var event = {                                 _event: e,       // In case we really want the IE event object                                 type: e.type,                     // Event type                                 target: e.srcElement,     // Where the event happened                                 currentTarget: element, // Where we're handling it                                 relatedTarget: e.fromElement?e.fromElement:e.toElement,                                 eventPhase: (e.srcElement==element)?2:3,                                 // Mouse coordinates
                               clientX: e.clientX, clientY: e.clientY,                                 screenX: e.screenX, screenY: e.screenY,                               // Key state
                               altKey: e.altKey, ctrlKey: e.ctrlKey,                                 shiftKey: e.shiftKey, charCode: e.keyCode,                                 // Event-management functions                                 stopPropagation: function( ) {this._event.cancelBubble = true;},                                 preventDefault: function( ) {this._event.returnValue = false;}                         }                         // Invoke the handler function as a method of the element, passing                         // the synthetic event object as its single argument.                         // Use Function.call( ) if defined; otherwise do a hack                         if (Function.prototype.call)                                 handler.call(element, event);                         else {                                 // If we don't have Function.call, fake it like this.                                 element._currentHandler = handler;                                 element._currentHandler(event);                                 element._currentHandler = null;                         }                 };                 // Now register that nested function as our event handler.                 element.attachEvent("on" + eventType, wrappedHandler);                 // Now we must do some record keeping to associate the user-supplied                 // handler function and the nested function that invokes it.                 // We have to do this so that we can deregister the handler with the                 // remove( ) method and also deregister it automatically on page unload.
                 // Store all info about this handler into an object.                 var h = {                         element: element,                         eventType: eventType,                         handler: handler,                         wrappedHandler: wrappedHandler                 };                 // Figure out what document this handler is part of.                 // If the element has no "document" property, it is not                 // a window or a document element, so it must be the document                 // object itself.                 var d = element.document || element;                 // Now get the window associated with that document.                 var w = d.parentWindow;                 // We have to associate this handler with the window,                 // so we can remove it when the window is unloaded.                 var id = Handler._uid( );   // Generate a unique property name                 if (!w._allHandlers) w._allHandlers = {};   // Create object if needed                 w._allHandlers[id] = h; // Store the handler info in this object
                 // And associate the id of the handler info with this element as well.                 if (!element._handlers) element._handlers = [];                 element._handlers.push(id);                 // If there is not an onunload handler associated with the window,                 // register one now.                 if (!w._onunloadHandlerRegistered) {                         w._onunloadHandlerRegistered = true;                         w.attachEvent("onunload", Handler._removeAllHandlers);                 }         };         Handler.remove = function(element, eventType, handler) {                 // Find this handler in the element._handlers[] array.                 var i = Handler._find(element, eventType, handler);                 if (i == -1) return;   // If the handler was not registered, do nothing
                 // Get the window of this element.                 var d = element.document || element;                 var w = d.parentWindow;                 // Look up the unique id of this handler.                 var handlerId = element._handlers[i];                 // And use that to look up the handler info.                 var h = w._allHandlers[handlerId];                 // Using that info, we can detach the handler from the element.                 element.detachEvent("on" + eventType, h.wrappedHandler);                 // Remove one element from the element._handlers array.                 element._handlers.splice(i, 1);                 // And delete the handler info from the per-window _allHandlers object.                 delete w._allHandlers[handlerId];         };         // A utility function to find a handler in the element._handlers array         // Returns an array index or -1 if no matching handler is found         Handler._find = function(element, eventType, handler) {                 var handlers = element._handlers;                 if (!handlers) return -1;   // if no handlers registered, nothing found
                 // Get the window of this element                 var d = element.document || element;                 var w = d.parentWindow;                 // Loop through the handlers associated with this element, looking                 // for one with the right type and function.                 // We loop backward because the most recently registered handler                 // is most likely to be the first removed one.                 for(var i = handlers.length-1; i >= 0; i--) {                         var handlerId = handlers[i];               // get handler id                         var h = w._allHandlers[handlerId];   // get handler info                         // If handler info matches type and handler function, we found it.                         if (h.eventType == eventType && h.handler == handler)                                 return i;                 }                 return -1;   // No match found
       };         Handler._removeAllHandlers = function( ) {                 // This function is registered as the onunload handler with                 // attachEvent. This means that the this keyword refers to the                 // window in which the event occurred.                 var w = this;                 // Iterate through all registered handlers                 for(id in w._allHandlers) {                         // Get handler info for this handler id                         var h = w._allHandlers[id];                         // Use the info to detach the handler                         h.element.detachEvent("on" + h.eventType, h.wrappedHandler);                         // Delete the handler info from the window                         delete w._allHandlers[id];                 }         }         // Private utility to generate unique handler ids         Handler._counter = 0;         Handler._uid = function( ) { return "h" + Handler._counter++; };
}

调用:

Handler.add(document,”click”,function(e){alert(e.stopPropagation);});

四、Event事件对象

1、事件的返回值

事件默认返回true,会继续执行默认动作.

onsubmit , onclick , onkeydown , onkeypress , onmousedown , onmouseup 和 onreset 返回false会阻止他们的默认行为发生.

Event是其他所有的事件父类,所有的事件都实现了这个接口.

支持属性:

  • type: 触发的事件的名称,如"click" 或 "mouseover"
  • target: 发生事件的节点
  • currentTarget: 当前正在处理该事件的节点,在捕捉阶段或起泡阶段他的值与target的值不同.在事件处理函数中应该用这个属性而不是this来指代当前处理的节点
  • eventPhase: 一个数字,指定了当前事件所处的传播过程的阶段.它的值是常量,可以是Event.CAPTURING_PHASE或Event.AT_TARGET或Event.BUBBLING_PHASE.
  • timeStamp: 一个Date对象,表明事件的发生时间
  • bubbles: 布尔值,表明该事件是否起泡
  • cancelable :布尔值,表明事件是否可以用preventDefault()方法来取消默认的动作.
  • stopPropagation( ): 停止事件的传播
  • preventDefault( ) :阻止默认事件发生,和0级DOM中返回false的作用类似

四、Key Event事件对象

IE和Firefox系列的模型

通常,一次按键有3个过程keydown, keypress, 和 keyup.

  • 如果用户按键事件足够长,在keyup事件触发之前,会触发多次keydown事件
  • keypress为输入的ASCII字符,如"@"等.不可打印字符如空格,回车, 退格,方向键,F1到F12,如果没有对应的ASCII码,不产生该事件
  • keypress,keyup为"virtual keycode" ,如同时按下 "shift"和"2", 发生事件"shift-2"
  • altKey, ctrlKey, shiftKey属性可以用来查询这三个键的状态(ALT在IE中不产生keypress事件),当按下时为true,否则为false

为了获得嵌入的字符,

  • Firefox定义了两个属性keyCode(返回"virtual keycode")和charCode(返回字符编码),对于不可打印字符,charCode是0.
  • IE中只有keyCode属性,为keydown事件时,keyCode是virtual keycode;为keypress事件时, keyCodes是字符编码

3级DOM并没有标准化keyCode,而是定义了新属性key,因此如果考虑后续符合规范,需要同时考虑使用key属性。key和keyCode的区别是,key不是unicode编码,而是直接的字符。

下边提供一个Keymap类,可以利用它把按键标识映射成JavaScript函数,这些函数作为这些按键的响应而调用。Keymap.js:

/*   * Keymap.js: bind key events to handler functions.   *   * This module defines a Keymap class. An instance of this class represents a   * mapping of key identifiers (defined below) to handler functions. A   * Keymap can be installed on an HTML element to handle keydown and keypress   * events. When such an event occurs, the Keymap uses its mapping to invoke   * the appropriate handler function.   *   * When you create a Keymap, pass a JavaScript object that represents the   * initial set of bindings for the Keymap. The property names of this object   * are key identifers, and the property values are the handler functions.   *   * After a Keymap has been created, you can add new bindings by passing a key   * identifer and handler function to the bind( ) method.

You can remove a   * binding by passing a key identifier to the unbind( ) method.   *   * To make use of a Keymap, call its install( ) method, passing an HTML element,   * such as the document object. install( ) adds an onkeypress and onkeydown   * event handler to the specified object, replacing any handlers previously set   * on those properties. When these handlers are invoked, they determine the   * key identifier from the key event and invoke the handler function, if any,   * bound to that key identifier. If there is no mapping for the event, it uses   * the default handler function (see below), if one is defined. A single   * Keymap may be installed on more than one HTML element.   *   * Key Identifiers   *   * A key identifier is a case-insensitive string representation of a key plus   * any modifier keys that are held down at the same time. The key name is the   * name of the key: this is often the text that appears on the physical key of   * an English keyboard. Legal key names include "A", "7", "F2", "PageUp",   * "Left", "Delete", "/", "~". For printable keys, the key name is simply the   * character that the key generates. For nonprinting keys, the names are   * derived from the KeyEvent.DOM_VK_ constants defined by Firefox. They are   * simply the constant name, with the "DOM_VK_" portion and any underscores   * removed. For example, the KeyEvent constant DOM_VK_BACK_SPACE becomes   * BACKSPACE. See the Keymap.keyCodeToFunctionKey object in this module for a   * complete list of names.   *   * A key identifier may also include modifier key prefixes. These prefixes are   * Alt_, Ctrl_, and Shift_. They are case-insensitive, but if there is more   * than one, they must appear in alphabetical order. Some key identifiers that   * include modifiers include "Shift_A", "ALT_F2", and "alt_ctrl_delete". Note   * that "ctrl_alt_delete" is not legal because the modifiers are not in   * alphabetical order.   *   * Shifted punctuation characters are normally returned as the appropriate   * character. Shift-2 generates a key identifier of "@", for example. But if   * Alt or Ctrl is also held down, the unshifted symbol is used instead.   * We get a key identifier of Ctrl_Shift_2 instead of Ctrl_@, for example.   *   * Handler Functions   *   * When a handler function is invoked, it is passed three arguments:   *     1) the HTML element on which the key event occurred   *     2) the key identifier of the key that was pressed   *     3) the event object for the keydown event   *   * Default Handler   *   * The reserved key name "default" may be mapped to a handler function. That   * function will be invoked when no other key-specific binding exists.   *   * Limitations   *   * It is not possible to bind a handler function to all keys. The operating   * system traps some key sequences (Alt-F4, for example). And the browser   * itself may trap others (Ctrl-S, for example). This code is browser, OS,   * and locale-dependent. Function keys and modified function keys work well,   * and unmodified printable keys work well. The combination of Ctrl and Alt   * with printable characters, and particularly with punctuation characters, is   * less robust.   */

// This is the constructor function
function Keymap(bindings) {         this.map = {};       // Define the key identifier->handler map         if (bindings) {     // Copy initial bindings into it, converting to lowercase                 for(name in bindings) this.map[name.toLowerCase( )] = bindings[name];         }
}

// Bind the specified key identifier to the specified handler function
Keymap.prototype.bind = function(key, func) {         this.map[key.toLowerCase( )] = func;
};

// Delete the binding for the specified key identifier
Keymap.prototype.unbind = function(key) {         delete this.map[key.toLowerCase( )];
};

// Install this Keymap on the specified HTML element
Keymap.prototype.install = function(element) {         // This is the event-handler function         var keymap = this;         function handler(event) { return keymap.dispatch(event); }         // Now install it         if (element.addEventListener) {                 element.addEventListener("keydown", handler, false);                 element.addEventListener("keypress", handler, false);         }         else if (element.attachEvent) {                 element.attachEvent("onkeydown", handler);                 element.attachEvent("onkeypress", handler);         }         else {                 element.onkeydown = element.onkeypress = handler;         }
};

// This object maps keyCode values to key names for common nonprinting
// function keys. IE and Firefox use mostly compatible keycodes for these.
// Note, however that these keycodes may be device-dependent and different
// keyboard layouts may have different values.
Keymap.keyCodeToFunctionKey = {         8:"backspace", 9:"tab", 13:"return", 19:"pause", 27:"escape", 32:"space",         33:"pageup", 34:"pagedown", 35:"end", 36:"home", 37:"left", 38:"up",         39:"right", 40:"down", 44:"printscreen", 45:"insert", 46:"delete",         112:"f1", 113:"f2", 114:"f3", 115:"f4", 116:"f5", 117:"f6", 118:"f7",         119:"f8", 120:"f9", 121:"f10", 122:"f11", 123:"f12",         144:"numlock", 145:"scrolllock"
};

// This object maps keydown keycode values to key names for printable
// characters. Alphanumeric characters have their ASCII code, but
// punctuation characters do not. Note that this may be locale-dependent
// and may not work correctly on international keyboards.
Keymap.keyCodeToPrintableChar = {         48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8",         57:"9", 59:";", 61:"=", 65:"a", 66:"b", 67:"c", 68:"d",         69:"e", 70:"f", 71:"g", 72:"h", 73:"i", 74:"j", 75:"k", 76:"l", 77:"m",         78:"n", 79:"o", 80:"p", 81:"q", 82:"r", 83:"s", 84:"t", 85:"u", 86:"v",         87:"w", 88:"x", 89:"y", 90:"z", 107:"+", 109:"-", 110:".", 188:",",         190:".", 191:"/", 192:"'", 219:"[", 220:"//", 221:"]", 222:"/""
};

// This method dispatches key events based on the keymap bindings.
Keymap.prototype.dispatch = function(event) {         var e = event || window.event;   // Handle IE event model         // We start off with no modifiers and no key name         var modifiers = ""         var keyname = null;         if (e.type == "keydown") {                 var code = e.keyCode;                 // Ignore keydown events for Shift, Ctrl, and Alt                 if (code == 16 || code == 17 || code == 18) return;                 // Get the key name from our mapping                 keyname = Keymap.keyCodeToFunctionKey[code];                 // If this wasn't a function key, but the ctrl or alt modifiers are                 // down, we want to treat it like a function key                 if (!keyname && (e.altKey || e.ctrlKey))                         keyname = Keymap.keyCodeToPrintableChar[code];                 // If we found a name for this key, figure out its modifiers.                 // Otherwise just return and ignore this keydown event.                 if (keyname) {                         if (e.altKey) modifiers += "alt_";                         if (e.ctrlKey) modifiers += "ctrl_";                         if (e.shiftKey) modifiers += "shift_";                 }                 else return;         }         else if (e.type == "keypress") {                 // If ctrl or alt are down, we've already handled it.                 if (e.altKey || e.ctrlKey) return;                 // In Firefox we get keypress events even for nonprinting keys.                 // In this case, just return and pretend it didn't happen.                 if (e.charCode != undefined && e.charCode == 0) return;                 // Firefox gives us printing keys in e.charCode, IE in e.charCode                 var code = e.charCode || e.keyCode;                 // The code is an ASCII code, so just convert to a string.                 keyname=String.fromCharCode(code);                 // If the key name is uppercase, convert to lower and add shift                 // We do it this way to handle CAPS LOCK; it sends capital letters                 // without having the shift modifier set.                 var lowercase = keyname.toLowerCase( );                 if (keyname != lowercase) {                         keyname = lowercase;       // Use the lowercase form of the name                         modifiers = "shift_";     // and add the shift modifier.                 }         }         // Now that we've determined the modifiers and key name, we look for         // a handler function for the key and modifier combination         var func = this.map[modifiers+keyname];         // If we didn't find one, use the default handler, if it exists         if (!func) func = this.map["default"];         if (func) {   // If there is a handler for this key, handle it                 // Figure out what element the event occurred on                 var target = e.target;                           // DOM standard event model                 if (!target) target = e.srcElement; // IE event model                 // Invoke the handler function                 func(target, modifiers+keyname, e);                 // Stop the event from propagating, and prevent the default action for                 // the event. Note that preventDefault doesn't usually prevent                 // top-level browser commands like F1 for help.                 if (e.stopPropagation) e.stopPropagation( );   // DOM model                 else e.cancelBubble = true;                                   // IE model                 if (e.preventDefault) e.preventDefault( );       // DOM                 else e.returnValue = false;                                   // IE                 return false;                                                               // Legacy event model         }
};         /**   * InputFilter.js: unobtrusive filtering of keystrokes for  tags   *   * This module finds all "text"> elements in the document that   * have a nonstandard attribute named "allowed". It registers an onkeypress   * event handler for any such element to restrict the user's input so that   * only characters that appear in the value of the allowed attribute may be   * entered. If the  element also has an attribute named "messageid",   * the value of that attribute is taken to be the id of another document   * element. If the user types a character that is not allowed, the messageid   * element is made visible. If the user types a character that is allowed,   * the messageid element is hidden. This message id element is intended to   * offer an explanation to the user of why her keystroke was rejected. It   * should typically be styled with CSS so that it is initially invisible.   *   * Here is some sample HTML that uses this module.   *     Zipcode:   *     "zip" type="text" allowed="0123456789" messageid="zipwarn">   *     "zipwarn" style="color:red;visibility:hidden">Digits only   *   * In browsers such as IE, which do not support addEventListener( ), the   * keypress handler registered by this module overwrites any keypress handler   * defined in HTML.   *   * This module is purely unobtrusive: it does not define any symbols in   * the global namespace.   */
(function( ) {   // The entire module is within an anonymous function         // When the document finishes loading, call the init( ) function below         if (window.addEventListener) window.addEventListener("load", init, false);         else if (window.attachEvent) window.attachEvent("onload", init);         // Find all the  tags we need to register an event handler on         function init( ) {                 var inputtags = document.getElementsByTagName("input");                 for(var i = 0 ; i < inputtags.length; i++) { // Loop through all tags                         var tag = inputtags[i];                         if (tag.type != "text") continue; // We only want text fields                         var allowed = tag.getAttribute("allowed");                         if (!allowed) continue;   // And only if they have an allowed attr                         // Register our event handler function on this input tag                         if (tag.addEventListener)                                 tag.addEventListener("keypress", filter, false);                         else {                                 // We don't use attachEvent because it does not invoke the                                 // handler function with the correct value of the this keyword.                                 tag.onkeypress = filter;                         }                 }         }         // This is the keypress handler that filters the user's input         function filter(event) {                 // Get the event object and character code in a portable way                 var e = event || window.event;                 // Key event object                 var code = e.charCode || e.keyCode;       // What key was pressed                 // If this keystroke is a function key of any kind, do not filter it                 if (e.charCode == 0) return true;             // Function key (Firefox only)                 if (e.ctrlKey || e.altKey) return true; // Ctrl or Alt held down                 if (code < 32) return true;                         // ASCII control character                 // Now look up information we need from this input element                 var allowed = this.getAttribute("allowed");         // Legal chars                 var messageElement = null;                                           // Message to hide/show                 var messageid = this.getAttribute("messageid"); // Message id, if any                 if (messageid)   // If there is a message id, get the element                         messageElement = document.getElementById(messageid);                 // Convert the character code to a character                 var c = String.fromCharCode(code);                 // See if the character is in the set of allowed characters                 if (allowed.indexOf(c) != -1) {                         // If c is a legal character, hide the message, if any                         if (messageElement) messageElement.style.visibility = "hidden";                         return true; // And accept the character                 }                 else {                         // If c is not in the set of allowed characters, display message                         if (messageElement) messageElement.style.visibility = "visible";                         // And reject this keypress event                         if (e.preventDefault) e.preventDefault( );                         if (e.returnValue) e.returnValue = false;                         return false;                 }         }
})( ); // Finish anonymous function and invoke it.

五、加载事件 onload Event

onload回在文档完全加载完成后运行

一个跨平台的版本

function runOnLoad(f) {
    if (runOnLoad.loaded) f( );    // If already loaded, just invoke f( ) now.
     else runOnLoad.funcs.push(f); // Otherwise, store it for later
 }

runOnLoad.funcs = []; // The array of functions to call when the document loads
 runOnLoad.loaded = false; // The functions have not been run yet.

// Run all registered functions in the order in which they were registered.
 // It is safe to call runOnLoad.run( ) more than once: invocations after the
 // first do nothing. It is safe for an initialization function to call
 // runOnLoad( ) to register another function.
 runOnLoad.run = function( ) {
     if (runOnLoad.loaded) return;  // If we've already run, do nothing

    for(var i = 0; i < runOnLoad.funcs.length; i++) {
         try { runOnLoad.funcs[i]( ); }
         catch(e) { /* An exception in one function shouldn't stop the rest */ }
     }

    runOnLoad.loaded = true; // Remember that we've already run once.
     delete runOnLoad.funcs;  // But don't remember the functions themselves.
     delete runOnLoad.run;    // And forget about this function too!
 };

// Register runOnLoad.run( ) as the onload event handler 
  for the window
 if (window.addEventListener)
     window.addEventListener("load", runOnLoad.run, false);
 else if (window.attachEvent) window.attachEvent("onload", runOnLoad.run);
 else window.onload = runOnLoad.run;

六、鼠标事件

MouseEvent是UIEvent的一个子类

支持属性:

  • button: 一个数字,表明在mousedown,mouseup和click中,那个鼠标键改变了状态.0表示左键,1表示中键,2表示右键.
  • altKey , ctrlKey, metaKey, shiftKey: 表明对应的键盘上的键的状态(PC上,Meta键通常对应 Alt 键)
  • screenX , screenY: 鼠标指针相对于屏幕左上角X,Y坐标,如果你想在鼠标附近弹出一个窗口,这个值很有用
  • clientX, clientY: 鼠标指针相对于浏览器页面显示部分左上角的X,Y坐标,注意,这个值不考虑文档滚动。
    如果需要相对于文档的位置,IE中可以加上document.body.scrollLeft和document.body.scrollTop,其他浏览器可以加上window.pageXOffset and window.pageYOffset
  • relatedTarget: 该属性仅对mouseover和mouseout生效。对于mouseover是它离开的节点,对于mouseout是它进入的节点.

button 点击时按下的是鼠标的哪个键(不同浏览器的赋值不同,不易使用)

拖动文档元素:

/**
 * 拖动绝对定位的HTML元素
 * 该方法依赖之前收集的getScrollOffset方法
 */
function drag( elementToDrag, event ){
    // 初始化鼠标位置,转换为文档坐标
    var scroll = getScrollOffset(),
        startX = event.clientX + scroll.x,
        startY = event.clientY + scroll,y,
        // 这里假设了elementToDrag的offsetParent是文档的body元素,似乎会有问题
        origX = elementToDrag.offsetLeft,
        origY = elementToDrag.offsetTop,
        deltaX = startX - origX,
        deltaY = startY - origY;

    if( document.addEventListener ){
        document.addEventListener( "mousemove", movehandler, true );
        document.addEventListener( "mouseup", upHandler, true );
    }else if( document.attachEvent ){
        // IE的事件模型中,捕获事件是通过调用元素上的setCapture()实现的
        elementToDrag.setCapture();
        elementToDrag.attachEvent( "onmousemove", moveHandler );
        elementToDrag.attachEvent( "onmouseup", upHandler );
        // 作为mouseup事件看待鼠标捕获的丢失???
        elementToDrag.attachEvent( "onlosecapture", upHandler );
    }
    if( event.stopPropagation ) event.stopPropagation();
    else event.cancelBubble = true;

    // 现在阻止任何默认操作
    if( event.preventDefault ) event.preventDefault();
    else event.returnValue = false;

    function moveHandler( e ){
        if( !e ) e = window.event;
        var scroll = getScrollOffset();
        elementToDrag.style.left = ( e.clientX + scroll.x - deltaX ) + "px";
        elementToDrag.style.top = ( e.clientY + scroll.y -deltaY ) + "px";
        if( e.stopPropagation ) e.stopPropagation();
        else e.cancelBubble = true;
    }

    function upHandler( e ){
        if( !e ) e = window.event;
        if( document.removeEventListener ){
            document.removeEventListener( "mouseup", upHandler, true );
            document.removeEventListener( "mousemove", movehandler, true );
        }else if( document.attachEvent ){
            elementToDrag.detachEvent( "onlosecapture", upHandler );
            elementToDrag.detachEvent( "onmouseup", upHandler );
            elementToDrag.detachEvent( "onmousemove", movehandler );
            elementToDrag.releasecapture();
        }
        if( e.stopPropagation ) e.stopPropagation();
        else e.cancelBubble = true;
    }
}

调用:

<div style="position:absolute;left:120px;top:150px;width:250px; border:1px solid black;">
    <div style="background-color:#416ea5; width:250px;height:22px;cursor:move;font-weight:bold;    border-bottom:1px solid black;" onmousedown="drag(this.parentNode, event);">可拖动标题</div>
    <p>可被拖动的窗口</p>
    <p>窗口内容</p>
</div>

<img src="image/logo.jpg" alt="按住Shift可拖动"  style="position:absolute;"
 onmousedοwn="if (event.shiftKey) drag(this, event);" />

tooltip 弹出层

鼠标坐标窗口几何属性,Geometry.js

var Geometry = {};

if (window.screenLeft) 
{
  Geometry.getWindowX = function()
  {
    return window.screenLeft;
  };
  Geometry.getWindowY = function()
  {
    return window.screenTop;
  };
}
else 
  if (window.screenX) 
  {
    Geometry.getWindowX = function()
    {
      return window.screenX;
    };
    Geometry.getWindowY = function()
    {
      return window.screenY;
    };
  }

if (window.innerWidth) 
{
  Geometry.getViewportWidth = function()
  {
    return window.innerWidth;
  };
  Geometry.getviewportHeight = function()
  {
    return window.innerHeight;
  };
  Geometry.getHorizontalScroll = function()
  {
    return window.pageXOffset;
  };
  Geometry.getVerticalScroll = function()
  {
    return window.pageYOffset;
  };
}
else 
  if (document.documentElement && document.documentElement.clientWidth) 
  {
    Geometry.getViewportWidth = function()
    {
      return document.documentElement.clientWidth;
    };
    Geometry.getviewportHeight = function()
    {
      return document.documentElement.clientHeight;
    };
    Geometry.getHorizontalScroll = function()
    {
      return document.documentElement.scrollLeft;
    };
    Geometry.getVerticalScroll = function()
    {
      return document.documentElement.scrollTop;
    };
  }
  else 
    if (document.body.clientWidth) 
    {
      Geometry.getViewportWidth = function()
      {
        return document.body.clientWidth;
      };
      Geometry.getviewportHeight = function()
      {
        return document.body.clientHeight;
      };
      Geometry.getHorizontalScroll = function()
      {
        return document.body.scrollLeft;
      };
      Geometry.getVerticalScroll = function()
      {
        return document.body.scrollTop;
      };
    }

if (document.documentElement && document.documentElement.scrollWidth) 
{
  Geometry.getDocumentWidth = function()
  {
    return document.documentElement.scrollWidth;
  };
  Geometry.getDocumentHeight = function()
  {
    return document.documentElement.scrollHeight;
  };
}
else 
  if (document.body.scrollWidth) 
  {
    Geometry.getDocumentWidth = function()
    {
      return document.body.scrollWidth;
    };
    Geometry.getDocumentHeight = function()
    {
      return document.body.scrollHeight;
    };
  }

Tooltip.js

Tooltip.X_OFFSET = 25;
Tooltip.Y_OFFSET = 15;
Tooltip.DELAY = 500;
Tooltip.Text;
function Tooltip()
{
  this.tooltip = document.createElement("div");//create div for shadow
  this.tooltip.style.position = "absolute";//
  this.tooltip.style.visibility = "hidden";
  this.tooltip.className = "tooltipShadow";

  this.content = document.createElement("div");//create div for content
  this.content.style.position = "relative";
  this.content.className = "tooltipContent";

  this.tooltip.appendChild(this.content);
}

Tooltip.prototype.show = function(text, x, y)
{
  this.content.innerHTML = text;
  this.tooltip.style.left = x + "px";
  this.tooltip.style.top = y + "px";
  this.tooltip.style.visibility = "visible";

  if (this.tooltip.parentNode != document.body) 
    document.body.appendChild(this.tooltip);
};


Tooltip.prototype.hide = function()
{
  this.tooltip.style.visibility = "hidden";
};


Tooltip.prototype.schedule = function(target, e)
{

  var text = Tooltip.Text;
  if (!text) 
    return;

  var x = e.clientX + Geometry.getHorizontalScroll();
  var y = e.clientY + Geometry.getVerticalScroll();

  x += Tooltip.X_OFFSET;
  y += Tooltip.Y_OFFSET;

  var self = this;
  var timer = window.setTimeout(function()
  {
    self.show(text, x, y);
  }, Tooltip.DELAY);

  if (target.addEventListener) 
    target.addEventListener("mouseout", mouseout, false);
  else 
    if (target.attachEvent) 
      target.attachEvent("onmouseout", mouseout);
    else 
      target.onmouseout = mouseout;

  function mouseout()
  {
    self.hide();
    window.clearTimeout(timer);

    if (target.removeEventListener) 
      target.removeEventListener("mouseout", mouseout, false);
    else 
      if (target.detachEvent) 
        target.detachEvent("mouseout", mouseout);
      else 
        target.onmouseout = null;
  }
};

Tooltip.tooltip = new Tooltip();


Tooltip.schedule = function(target, e)
{
  Tooltip.tooltip.schedule(target, e);
}

Tooltip.init = function(value){Tooltip.Text = value};

tooltip.css

.tooltipShadow {
    background-color:#A9A9A9;
}
.tooltipContent {
    left:-4px;
    top:-4px;
    background-color:#F0F8FF;
    border:solid black 1px;
    padding:5px;
    font:9pt sans-serif;
    color:#0000CC;
    width:150px;
}

使用:

在jsp需要提示的地方加入οnmοusemοve="Tooltip.schedule(this,event)"。js中要设置提示的内容Tooltip.init("提示的内容");

posted on 2019-03-23 09:24  springsnow  阅读(1052)  评论(0编辑  收藏  举报

导航