jQuery .prop()返回undefined,而.attr()按预期工作 - 数据 - *

时间:2016-04-16 11:41:18

标签: javascript jquery html attr prop

我只想从两个元素中获取几个属性。从value元素获取属性input可以按预期工作。问题是从data-detail元素获取属性button属性。使用undefined时会返回.prop(),但在使用.attr()时会按预期工作。

有人能解释我目睹的这种奇怪的行为吗?

HTML

<div class="formRow">
    <label for="firstName">First name</label>
    <div class="detailsControlBtns">
        <button id="editFirstName" class="btn ctaBtn greenBtn editBtn">Edit</button>
        <button class="btn ctaBtn greenBtn saveBtn" data-detail="firstName">Save</button>
        <button id="closeFirstName" class="btn ctaBtn greyBtn closeBtn">Close</button>
    </div>
    <input type="text" id="firstName" name="firstName" value="[+firstName+]" readonly>
</div>

JS

$(".saveBtn").on("click", function() {
    var saveBtn = $(this);
    // The following statement yields undefined. When using .attr() it works as expected.
    var detail = saveBtn.prop("data-detail");
    var relevantInput = saveBtn.parent().next();
    // The following statement works as expected.
    var value = relevantInput.prop("value");
    // ...
});

1 个答案:

答案 0 :(得分:16)

那是因为HTML元素上没有数据详细信息 属性

以下是.data().prop().attr()的简要说明:

DOM 元素是对象,其中包含methodsproperties(来自DOM)和attributes(来自渲染的HTML)。其中一些properties通过initial value attributes获得id->id, class->className, title->title, style->style etc. 请考虑以下因素: <input type="checkbox" checked data-detail="somedata" >

以下的结果将是:

$('input').prop('id'); // => " "-empty string, property id exist on the element (defined by DOM) , but is not set.
$('input').attr('id');// => undefined - doesn't exist.

<小时/> 如果您执行以下操作:

$('input').attr('id',"someID");
$('input').prop('id'); // =>  "someID"
$('input').attr('id'); // =>  "someID"

还有:

$('input').prop('id',"someOtherID");
$('input').prop('id');// =>  "someOtherID"
$('input').attr('id');// =>  "someOtherID"
  

因此,某些属性和属性具有 1:1映射。 (的变化   支柱的attr结果变化,反之亦然。)

<小时/> 请考虑以下事项: <input type="text" data-detail="somedata" value="someValue">

$('input').prop('value'); // =>  "someValue"
$('input').val();         // =>  "someValue"
$('input').attr('value'); // =>  "someValue"

如果你这样做:

$('input').prop('value','newVal');

// or

$('input').val('newVal');

$('input').prop('value'); // => "newVal"    -value of the property
$('input').val();         // => "newVal"    -value of the property
$('input').attr('value'); // => "someValue" -value of the attr didn't change, since in this case it is not 1:1 mapping (change of the prop value doesn't reflect to the attribute value).

案例与 .data()

1)如何获得:

- 请注意,attribute namedata-*property namedataset,因此:

<input type="checkbox" data-detail="somedata" > 

 $('input')[0].dataset; //=> [object DOMStringMap] { detail: "somedata"}
 $('input')[0].dataset.detail; // => "somedata"
 $('input').prop('dataset'); //=>[object DOMStringMap] { detail: "somedata"}
 $('input').prop('dataset').detail; // => "somedata"
 $('input').data('detail'); // => "somedata"
 $('input').attr('data-detail');  //  => "somedata"

2)如何设置:

I) $('input').prop('dataset').detail='newData';

 $('input').prop('dataset');  //=> [object DOMStringMap] { detail: "newData"}
 $('input').prop('dataset').detail; // => "newData"
 $('input').attr('data-detail'); // => "newData"
 $('input').data('detail'); // => "newData"

II) $('input').attr('data-detail','newData');

 $('input').prop('dataset');  //=> [object DOMStringMap] { detail: "newData"}
 $('input').prop('dataset').detail; // => "newData"
 $('input').attr('data-detail'); // => "newData"
 $('input').data('detail'); // => "newData"
  

所以你可以看到这里是1:1的映射,attr的变化反映了prop和   反之亦然。

但请检查第三种方式:

III) $('input').data('detail','newData');

 $('input').prop('dataset'); // =>  [object DOMStringMap] { detail: "somedata"}
 $('input').prop('dataset').detail; // => "somedata"
 $('input').attr('data-detail'); // => "somedata"
 $('input').data('detail');  // => "newData"    <-----******

那么,这里发生了什么?

  

$(elem).data(key, value)不会更改HTML5 data-*属性   元素。它将其值存储在$.cache内部。

为了获得data-*,您永远不会错过.data()

$(".saveBtn").on("click", function() {
    var saveBtn = $(this);
    var detail = saveBtn.data("detail");
    var relevantInput = saveBtn.parent().next();
    var value = relevantInput.prop("value");

});