如何将Javascript命名空间分配给HTML元素并调用此元素上所述命名空间中定义的函数?
我问了另一个问题: Attaching JavaScript to the prototype of an ASCX client side instance
上一个问题回答了如何做到这一点,但现在我很好奇它是如何在纯Javascript / HTML级别上运行的。而且我也没有把它搞清楚了。
假设我有一个只包含文本框的HTML页面:
<html>
<body>
<div>
<input type="text" id="MyTextBox" />
</div>
</body>
</html>
在浏览器中,我可以document.getElementById('MyTextBox')
。
然而我的问题是,只使用javascript,如何分配返回javascript类型的对象,以便从对象中调用命名空间中定义的函数?
例如,我想这样做:
var x = document.getElementById('MyTextBox');
x.SetTheText('blah');
在我的自定义命名空间/类型/类中,我将SetTheText定义为
function SetTheText(text) {
this.value = text;
}
我怎么说MyTextBox是一个可以运行JS命名空间中定义的函数的对象。 我希望这是有道理的
答案 0 :(得分:3)
基本上,您可以向(几乎)任何类型的JS对象添加任何类型的属性。如果向对象添加函数,则该函数的this
将成为对象。
换句话说
var x = document.getElementById('MyTextBox'); // a DOM object
x.setTheText = function(text) {
this.value = text;
};
x.setTheText('blah'); // bingo
如果要扩展整个对象类,也可以通过原型
进行扩展HTMLTextAreaElement.prototype.setTheText = function(text) {
this.value = text;
};
someRandomTextArea.setTheText("blah"); // bingo. Again.
然而,这并不是真正推荐的,因为你正在搞乱你无法控制的对象(即它像其他脚本和浏览器更新一样脆弱,以及可能会阻碍的方式)。此外,您可以通过执行此操作来破坏其他代码。
更好的解决方案(在很多方面)是将未修改的DOM元素包装在另一个对象中的jQuery解决方案,并且直接调用包装器对象而不是元素上的方法(就个人而言,我更喜欢可以使用的“漂亮”代码来自只是扩展本机JS对象,但唉,它不安全,所以我试图放弃它。)
P.S。在javascript中使用Captilized类;方法是camelCase。我已经相应地编辑了代码。这不是任何东西,而是风格的风格。
编辑:为了进行比较,您可以查看the prototype.js library,它通过扩展DOM来发挥其神奇作用。同样,在我看来,与jQuery的$(...).xyz(...)
的常量调用相比,它产生了一些非常漂亮的代码,但它仍然是一个稍微危险的路径
答案 1 :(得分:2)
您不应该修改主机目标,所有主要的库都同意这一点。改为使用包装器对象:
<input type="text" id="inp0">
<script type="text/javascript">
function CreateCustomElement(el) {
this.element = el;
}
CreateCustomElement.prototype = {
setTheValue: function(text) {
this.element.value = text;
}
}
var x = new CreateCustomElement(document.getElementById('inp0'));
x.setTheValue('foo');
</script>