document.createElement不起作用

时间:2013-01-07 19:28:25

标签: javascript jquery

我正在使用jQuery库创建一个插件。

这里我将 String.prototype 存储在变量中,然后我使用此变量来扩展我的Sting对象。这很好。

// String Prototyping store in a variable
// Save bytes in the minified version of js
var StrProto = String.prototype;
String.prototype.toProperCase = function () {
  return this.replace(/\w\S*/g, function (txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });
};
// working fine
alert("yogesh kumar".toProperCase());

在下一种情况下,我创建了存储的m 函数xyz abc 变量,这也正常。

function xyz(x){
  alert(x)
}
var abc = xyz;
// working fine
abc("yogesh kumar");

在最后一种情况下,我将 document.createElement 存储在变量中 标记并使用标记创建按钮。但这不起作用。

var tag=document.createElement;
$(document.createElement("button")).html("document.Element").appendTo("#myDiv");

// not working
$(tag("button")).html("tag").appendTo("#myDiv");

请检查jsFiddle上的链接:

  

click here

错误:

在Chrome中

  • 未捕获的TypeError:非法调用
Firefox中的

  • 错误:NS_ERROR_XPC_BAD_CONVERT_JS:无法转换JavaScript 参数

为什么会出现此错误?

解决方案是什么?

5 个答案:

答案 0 :(得分:6)

您将获得对作为文档成员的函数的引用。当您直接调用该引用时,它的上下文现在是窗口而不是文档。这是一个例子:

http://jsfiddle.net/DeCNx/

var foo = {
  createElement: function(tagname) {
    if (this._secretvarthatisneeded) {
      console.log(tagname + " Element Created!");
    }
  },
  _secretvarthatisneeded: true
}

foo.createElement("FOOBAR"); // works

var bar = foo.createElement;
bar("BARFOO"); // doesn't work
bar.call(foo,"BARBAR") // works

由于上下文丢失,bar()调用未导致console.log();

显然这只是一个简化演示。

更新:对于您正在使用的用途,我建议您这样做:

$.createElement = function(tagName,attributes){
    return $(
        document.createElement(tagName),
        attributes ? attributes : {}
    )
}

现在你可以简单地做$.createElement("button").html("tag").appendTo("#myDiv");它很快并且仍然易于阅读。但请注意,IE输入存在问题,如果您正在创建输入元素,我建议使用$("<input type='text' />")而不是此。

答案 1 :(得分:5)

jQuery可以create new elements为您提供如下简单:

$("<button />").html("document.Element").appendTo("#myDiv");

要了解您的方法无效的原因,请阅读下面的@Kevin's comment

答案 2 :(得分:5)

使用bind()方法将原生JS方法“赋值”给变量:

var ce = document.createElement.bind(document);
var elem = ce('div');
alert(elem.nodeName);

适用于现代浏览器,包括IE9 +。对于旧版浏览器,请使用包装函数。

答案 3 :(得分:2)

这种情况正在发生,因为document.createElement内部使用了this。当您将其称为document.createElement()时,this设置为document。但是,当您将其另存为变量时,this不再是document,而是window

您需要使用上下文调用它。

var tag = document.createElement;  // you are saving the function, not its context
var btn = tag.call(document, 'button'); // you need to set the context

如果您的浏览器支持,您也可以使用.bind

var tag = document.createElement.bind(document);
var btn = tag('button');

答案 4 :(得分:2)

此错误的原因是该方法丢失了其上下文。必须在createElement()对象的上下文中调用方法document

在控制台中尝试:

var tag = document.createElement;
tag.call(document, "div");  // no error
tag("div");  // error

必须在createElement()的上下文中调用document的原因的具体细节是特定于实现的,但很容易被猜到。

因此,要维护上下文,请为document.createElement()

创建一个函数包装器
function tag(tagName) {
    return document.createElement(tagName);
}

当然,jQuery也会为你创建元素:

$("<div>");  // new div element