简体   繁体   English

document.createElement不起作用

[英]document.createElement not working

I am creating a plugin using jQuery library. 我正在使用jQuery库创建一个插件。

Here i am storing String.prototype in a variable then i am using this variable to extend my Sting object. 在这里,我将String.prototype存储在一个变量中,然后使用该变量扩展我的Sting对象。 And this is working fine. 这很好。

// 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());

In the next case i am creating m function xyz which stored in abc variable and this is also working fine. 在下一种情况下,我正在创建m 函数xyz ,该函数存储在abc变量中,并且也可以正常工作。

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

In the last case i am storing document.createElement in a variable tag and using tag to create a button. 在最后一种情况下,我将document.createElement存储在变量标签中,并使用标签创建按钮。 but this is not working. 但这不起作用。

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

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

Please check the link on jsFiddle: 请检查jsFiddle上的链接:

click here 点击这里

Error: 错误:

In Chrome 在Chrome中

  • Uncaught TypeError: Illegal invocation 未捕获的TypeError:非法调用

in Firefox 在Firefox中

  • Error: NS_ERROR_XPC_BAD_CONVERT_JS: Could not convert JavaScript argument 错误:NS_ERROR_XPC_BAD_CONVERT_JS:无法转换JavaScript参数

Why this error? 为什么会出现这个错误?

What is the solution? 解决办法是什么?

You are getting a reference to a function that is a member of the document. 您将获得对作为文档成员的函数的引用。 When you call that reference directly, it's context is now the window rather than the document. 当您直接调用该引用时,它的上下文现在是窗口而不是文档。 Here's an example: 这是一个例子:

http://jsfiddle.net/DeCNx/ 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

Since the context was lost, the bar() call didn't result in a console.log(); 由于上下文丢失,因此bar()调用不会导致console.log();

obviously this is just a simplification to demonstrate. 显然,这只是一个简化的演示。

Update: For the use you are making, i'd suggest doing this: 更新:对于您正在使用的用途,我建议您这样做:

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

Now you can simply do $.createElement("button").html("tag").appendTo("#myDiv"); 现在,您可以简单地执行$.createElement("button").html("tag").appendTo("#myDiv"); It is fast and still easy to read. 它既快速又易于阅读。 Note however IE has problems with inputs, if you're creating input elements, i suggest using $("<input type='text' />") rather than this. 但是请注意,但是IE在输入方面存在问题,如果要创建输入元素,建议不要使用$("<input type='text' />")

Use the bind() method for "assigning" the native JS method to a variable: 使用bind()方法将本机JS方法“分配”给变量:

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

Works in modern browsers including IE9+. 在包括IE9 +的现代浏览器中均可使用。 For older browsers, use a wrapper function. 对于较旧的浏览器,请使用包装器功能。

jQuery can create new elements for you as simple as: jQuery可以为您创建新元素 ,方法很简单:

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

To have a reason why your approach is not working, read @Kevin's comment below. 要弄清您的方法不起作用的原因,请阅读下面的@Kevin评论

That is happening because document.createElement uses this inside itself. 这是发生因为document.createElement使用this内部本身。 When you call it like document.createElement() then this is set to document . 当你称呼它document.createElement()this设置为document But, when you save it as a variable, then this is no longer document , it's window . 但是,当你将它保存为一个变量,那么this不再是document ,它的window

You need to call it with the context. 您需要使用上下文来调用它。

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

If your browser supports it, you can also use .bind : 如果您的浏览器支持,也可以使用.bind

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

The reason for this error is that the method lost its context. 出现此错误的原因是该方法失去了上下文。 The method createElement() must be called in the context of a document object. 方法createElement()必须在document对象的上下文中调用。

Try this in a console: 在控制台中尝试:

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

The specific details of why createElement() must be called in the context of document are implementation specific, but can easily be guessed at. 为什么必须在document上下文中调用createElement()的特定细节是实现特定的,但很容易猜到。

So, to maintain context, create a function wrapper for document.createElement() : 因此,要维护上下文,请为document.createElement()创建一个函数包装器:

function tag(tagName) {
    return document.createElement(tagName);
}

Of course, jQuery will also create elements for you: 当然,jQuery还将为您创建元素:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM