1

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

次のケースでは、 abc変数に格納されている m関数xyzを作成していますが、これも正常に機能しています。

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のリンクを確認してください:

ここをクリック

エラー:

Chromeの場合

  • Uncaught TypeError:不正な呼び出し

Firefoxで

  • エラー:NS_ERROR_XPC_BAD_CONVERT_JS:JavaScript引数を変換できませんでした

なぜこのエラーですか?

解決策は何ですか?

4

5 に答える 5

7

ドキュメントのメンバーである関数への参照を取得しています。その参照を直接呼び出すと、そのコンテキストはドキュメントではなくウィンドウになります。次に例を示します。

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' />")は、これではなく使用することをお勧めします。

于 2013-01-07T19:40:11.300 に答える
5

bind()ネイティブJSメソッドを変数に「割り当てる」ためのメソッドを使用します。

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

IE9+を含む最新のブラウザで動作します。古いブラウザの場合は、ラッパー関数を使用します。

于 2013-01-07T19:37:01.507 に答える
4

jQueryは、次のような簡単な方法で新しい要素を作成できます。

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

あなたのアプローチがうまくいかない理由を知るために、以下の@Kevinのコメントを読んでください。

于 2013-01-07T19:29:58.633 に答える
2

それはそれ自体の内部でdocument.createElement使用するために起こっています。thisあなたがそれをそのように呼ぶとき、document.createElement()それからthisに設定されdocumentます。しかし、それを変数として保存すると、でthisはなくなりdocumentwindowです。

コンテキストで呼び出す必要があります。

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');
于 2013-01-07T19:39:27.510 に答える
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
于 2013-01-07T19:39:38.457 に答える