Bab*_*ker 29 javascript jquery
如何在不使用jQuery的情况下正确执行以下操作.
$(document).ready(function(){
$("#someButton").click(function(){
alert("Hello");
});
});
Run Code Online (Sandbox Code Playgroud)
谢谢.
CMS*_*CMS 35
最简单的方法是:
// DOM Level 0 way
window.onload = function () {
document.getElementById("someButton").onclick = function() {
alert("Hello");
};
};
Run Code Online (Sandbox Code Playgroud)
这将适用于所有浏览器,但请注意,使用此方法只能将一个事件处理程序附加到事件.
另请注意,onload事件并不完全等同于jQuery的ready事件,onload当页面的所有资源都被完全加载(图像,子帧等等)时将被ready触发,同时在解析DOM后立即触发.
如果要附加多个事件处理程序,可以使用DOM Level 2 Standard element.addEventListerner方法(或element.attachEventIE)
获得跨浏览器绑定事件的最简单的抽象方法是:
function addEvent(el, eventType, handler) {
if (el.addEventListener) { // DOM Level 2 browsers
el.addEventListener(eventType, handler, false);
} else if (el.attachEvent) { // IE <= 8
el.attachEvent('on' + eventType, handler);
} else { // ancient browsers
el['on' + eventType] = handler;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以:
var button = document.getElementById("someButton");
addEvent(button, 'click', function () {
alert("Hello");
});
addEvent(button, 'click', function () {
alert("world!");
});
Run Code Online (Sandbox Code Playgroud)
还要注意addEventListener和IE的attachEvent方法有区别,当你将多个处理程序附加到一个事件时,addEventListener它们将以相同的顺序触发,因为处理程序被绑定(FIFO),attachEvent将以相反的顺序触发处理程序(LIFO) ).
点击这里查看示例.
TL; DR
在现代浏览器上:
<input type="button" id="someButton" value="Some Button">
<script>
document.getElementById("someButton").addEventListener("click", function() {
alert("Hello");
}, false);
</script>
Run Code Online (Sandbox Code Playgroud)
请注意,脚本位于HTML中的按钮之后.为什么这很重要?继续阅读.
document.getElementById("someButton").addEventListener("click", function() {
snippet.log("Hello");
}, false);Run Code Online (Sandbox Code Playgroud)
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>Run Code Online (Sandbox Code Playgroud)
哦,好,你一直在读.
这有三个部分:
何时挂钩处理程序(jQuery代码ready用于的部分)
如何找到要挂钩的元素(jQuery代码$("#someButton")用于的部分)
如何挂钩处理程序(它click用于的部分)
直接在元素上处理事件时,在元素存在之前,您无法挂接事件处理程序.处理页面主HTML中的元素时,一旦解析了HTML,就会知道它们存在.例如:
<div>...</div>
<script>
// Here, we know that that div exists
</script>
Run Code Online (Sandbox Code Playgroud)
因此,除非您有充分的理由不这样做,否则请将JavaScript代码的脚本标记放在文档的末尾,就在结束</body>标记之前.然后你知道上面(包括document.body)的所有元素都存在.
如果您别无选择,只能将脚本标记放在其他位置(例如将它们放入其中的反模式<head>),那么您必须在解析页面内容时使用事件处理程序.标准的是DOMContentLoaded你挂钩的document.不幸的是,IE8及更早版本不支持它,这是jQuery提供ready回调的部分原因.您也可以load在window对象上使用该事件,但是在解析页面元素之后很久才会触发该事件,因为它会在触发之前等待所有外部资源加载(所有图像等).
在您的示例中,元素具有id值,因此您可以使用document.getElementById它来获取它; 返回对元素对象的引用,或者null如果没有那个引用id.
现代浏览器以及IE8支持document.querySelector,它将找到匹配任何CSS选择器的第一个元素.因此,例如,document.querySelector('div')找到div文档中的第一个,如果有的话(null如果没有).document.querySelector('div.foo table tr.bar')找到的第一个tr与类元素bar这是内部的table,这是一个内div有类元素foo.
现代浏览器(和IE8)也提供document.querySelectorAll,它为您提供与CSS选择器匹配的所有元素的列表(集合).
querySelector并且querySelectorAll也可以提供元素; 当你在元素上使用它们时,它们只会查看该元素的后代.
还有其他各种功能,例如getElementsByTagName(几乎普遍支持,甚至在旧的IE中),getElementsByName(使用name属性;我不知道它有多广泛支持),getElementsByClassName(通过单个CSS类查找; IE8和更早版本'有它),还有其他一些.
现代浏览器,包括IE9及更高标准模式,支持addEventListener.使用IE8及更早版本,您必须使用Microsoft的原始版本attachEvent(之前的版本addEventListener).
theElement.addEventListener("click", function() {
// ...your handler code here
}, false);
// or
theElement.attachEvent("onclick", function() {
// ...your handler code here
});
Run Code Online (Sandbox Code Playgroud)
请注意,addEventListener只使用事件名称("click"),但attachEvent使用"on"加上事件名称("onclick").还要注意,它addEventListener有一个你几乎总要设置的第三个参数false.(最近的浏览器使参数可选,但并非总是如此,因此,如果您需要支持旧版本,请将其包括在内.)
使用addEventListener或者attachEvent这样做的主要优点是可以很好地与其他人一起使用,因为在使用这些方法时,元素可以为同一事件注册多个事件处理程序.
元素还公开可以为其分配函数的属性,其中属性名称on后跟事件名称,例如onclick:
theElement.onclick = function() {
// Your handler code
};
Run Code Online (Sandbox Code Playgroud)
这通常是跨浏览器支持的,但是存在一个问题,即元素只能以这种方式连接一个处理程序.
所以,我们可以像这样实现你的jQuery代码:
<script>
document.getElementById("someButton").onclick = function() {
alert("Hello");
};
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
(注意标签的位置.)但这与其他人不能很好地协调.
document.getElementById("someButton").onclick = function() {
snippet.log("Hello");
};Run Code Online (Sandbox Code Playgroud)
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>Run Code Online (Sandbox Code Playgroud)
或者在现代浏览器上:
<script>
document.getElementById("someButton").addEventListener("click", function() {
alert("Hello");
}, false);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
document.getElementById("someButton").addEventListener("click", function() {
snippet.log("Hello");
}, false);Run Code Online (Sandbox Code Playgroud)
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>Run Code Online (Sandbox Code Playgroud)
或者在IE8及更早版本:
<script>
document.getElementById("someButton").attachEvent("onclick", function() {
alert("Hello");
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
document.getElementById("someButton").attachEvent("onclick", function() {
snippet.log("Hello");
});Run Code Online (Sandbox Code Playgroud)
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>Run Code Online (Sandbox Code Playgroud)
现在,假设我们使用querySelectorAll或类似并获取元素列表,而不是仅仅一个元素?我们如何在每个上面挂钩处理程序?
我们可以使用其他答案中的技术来循环遍历集合,因为它将是一个类似于数组的对象(但不是实际的数组).假设我们想要div在类的所有元素上查找处理程序foo:
var list = document.querySelectorAll("div.foo");
Array.prototype.forEach.call(list, function(element) {
element.addEventListener("click", handler, false);
});
function handler() {
this.innerHTML = "You clicked me";
}
Run Code Online (Sandbox Code Playgroud)
(不要担心this,我在下面的"更多探索"中介绍.)
var list = document.querySelectorAll("div.foo");
Array.prototype.forEach.call(list, function(element) {
element.addEventListener("click", handler, false);
});
function handler() {
this.innerHTML = "You clicked me";
}Run Code Online (Sandbox Code Playgroud)
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>Run Code Online (Sandbox Code Playgroud)
事件处理不仅仅是关于获取事件.事件处理程序有时还有其他四件事要做:
获取有关该事件的信息(例如,如果按下某个键,键是什么键?)
阻止事件的默认操作(如果有)(例如,防止submit表单上的事件中的默认操作阻止它被提交)
停止将事件传播(冒泡)到容器元素
引用事件被挂钩的元素(因此我们可以在多个元素上使用相同的处理程序)
#4很简单:在附加了我们上面讨论过的任何机制的处理程序中,在处理程序中,this将引用该事件被挂钩的元素.(HTML属性连接不是这样,例如<div onclick="handler()">,这是不使用它们的众多原因之一.)如果你已经做了其他事情this(你可以),你也可以访问你挂钩事件的元素通过currentTarget事件对象的属性(更多下面).
不幸的是,你这样做的方式在IE8和更早版本的attachEvent标准兼容浏览器上是不同的(addEventListener).这是一个函数,hookEvent(我最初为其他答案写的),即使在旧的IE上也可以使用基于标准的方式:
var hookEvent = (function() {
var div;
// The function we use on standard-compliant browsers
function standardHookEvent(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
return element;
}
// The function we use on browsers with the previous Microsoft-specific mechanism
function oldIEHookEvent(element, eventName, handler) {
element.attachEvent("on" + eventName, function(e) {
e = e || window.event;
e.preventDefault = oldIEPreventDefault;
e.stopPropagation = oldIEStopPropagation;
handler.call(element, e);
});
return element;
}
// Polyfill for preventDefault on old IE
function oldIEPreventDefault() {
this.returnValue = false;
}
// Polyfill for stopPropagation on old IE
function oldIEStopPropagation() {
this.cancelBubble = true;
}
// Return the appropriate function; we don't rely on document.body
// here just in case someone wants to use this within the head
div = document.createElement('div');
if (div.addEventListener) {
div = undefined;
return standardHookEvent;
}
if (div.attachEvent) {
div = undefined;
return oldIEHookEvent;
}
throw "Neither modern event mechanism (addEventListener nor attachEvent) is supported by this browser.";
})();
Run Code Online (Sandbox Code Playgroud)
使用hookEvent,我们可以按照基于标准的方式执行前面列出的三件事:
我们接收事件对象作为处理函数的第一个参数,这意味着我们可以使用它currentTarget来获取对我们挂钩事件target的元素的引用,或者获取对事件源自的元素的引用,等等
我们可以通过调用事件对象的preventDefault函数来阻止默认值
我们可以通过调用事件对象的stopPropagation函数来停止传播
我们可以使用this(或event.currentTarget)引用我们挂钩事件的元素
hookEvent不是一个彻底的,全能的,全舞蹈的事件连接功能.(一两件事,我从来没有费心去支持联合国与它挂钩的事件.)这是示例代码,主要是.
HTML5规范现在涵盖了大部分内容,这比HTML要多得多
Mozilla开发者网络拥有大量相当准确的参考资料(与其他一些常常存在准确性问题的元网站不同).
| 归档时间: |
|
| 查看次数: |
11990 次 |
| 最近记录: |