1. ホーム
  2. jquery

[解決済み] jQuery .data()は動作しないが、.attr()は動作する。

2022-09-10 14:37:39

質問

具体的でなくて申し訳ないのですが、このような奇妙なバグがあります。私はこのような奇妙なバグを持っています。ドキュメントがロードされた後、私はいくつかの要素をループします。 data-itemname="" を持つ要素をループさせ、それらの値を .attr("data-itemname", "someValue") .

問題点 これらの要素を後でループさせるとき、もし elem.data().itemname とすると "" が、もし elem.attr("data-itemname") を実行すると "someValue" . これはまるでjQueryの .data() ゲッターは、何らかの値を含むように初期設定された要素のみを取得しますが、元々空で、後から設定された場合、その要素が .data() は後で値を取得することはありません。

このバグを再現しようとしたのですが、できませんでした。

Edit

バグを再現してみました http://jsbin.com/ihuhep/edit#javascript,html,live

また、上記のリンクからのスニペット...

JSです。

var theaters = [
    { name: "theater A", theaterId: 5 },
    { name: "theater B", theaterId: 17 }
];

$("#theaters").html(
    $("#theaterTmpl").render(theaters)
);

// DOES NOT WORK - .data("name", "val") does NOT set the val
var theaterA = $("[data-theaterid='5']");
theaterA.find(".someLink").data("tofilllater", "theater5link"); // this does NOT set data-tofilllater
$(".someLink[data-tofilllater='theater5link']").html("changed link text"); // never gets changed

// WORKS - .attr("data-name", "val") DOES set val
var theaterB = $("[data-theaterid='17']");
theaterB.find(".someLink").attr("data-tofilllater", "theater17link"); // this does set data-tofilllater
$(".someLink[data-tofilllater='theater17link']").html("changed link text");

HTMLです。

<body>
    <div id="theaters"></div>
</body>

<script id="theaterTmpl" type="text/x-jquery-tmpl">
    <div class="theater" data-theaterid="{{=theaterId}}">
        <h2>{{=name}}</h2>
        <a href="#" class="someLink" data-tofilllater="">need to change this text</a>
    </div>
</script>

どのように解決するのですか?

数日前、同じようなバグに遭遇しました。 .data().attr('data-name') はHTML5のデータ属性です。

あなたが説明している動作はバグではなく、デザインによるものです。

.data() の呼び出しは特殊で、HTML5 データ属性を取得するだけでなく、その属性の評価や解析も試みます。そのため、次のような属性では data-myjson='{"hello":"world"}' で取得された場合 .data() で取得した場合は Object を返しますが .attr() は文字列を返します。 jsfiddle の例を参照してください。

から .data() は余分な処理を行うので、jQuery は属性評価の結果を $.cache - 結局のところ、一旦データ属性が評価されると、すべての .data() 特にデータ変数には複雑な JSON 文字列が含まれることがあるため、すべての 呼び出しで再評価するのは無駄です。

私は次のことを言うために、すべてを言いました。 で属性を取得した後 .data() によって行われたいかなる変更も .attr('data-myvar', '') で行った変更は、後続の .data() の呼び出しによって見られることはありません。 jsfiddleでテストしてみましょう。

この問題を回避するために を混在させない .data.attr() を呼び出します。 どちらか一方を使用します。