jQuery .prop() returns 未定义,而 .attr() 按数据预期的方式工作-*
jQuery .prop() returns undefined, while .attr() works as expected for data-*
我只是想从两个元素中获取几个属性。从 input
元素获取 属性 value
按预期工作。问题在于从 button
元素获取 属性 data-detail
属性。它 returns 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");
// ...
});
那是因为 HTML 元素上没有 data-detail 属性。
下面是对.data(), .prop() and .attr()的简单解释:
DOM 元素是一个 对象 ,它具有 methods
和 properties
(来自 DOM
) 和 attributes
(来自呈现的 HTML
)。其中一些 properties
通过 attributes
id->id, class->className, title->title, style->style etc.
获得了他们的 initial value
考虑这个元素: <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"
So, some attributes and properties have 1:1 mapping. (change of
the attr result change of the prop and vice versa).
考虑以下因素: <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 name
是 data-*
而 property name
是 dataset
,所以:
<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)设置方法:
我) $('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"
So you can see that here is 1:1 mapping, attr change reflects prop and
vice versa.
但是检查第三种方式:
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)
does not change the HTML5 data-*
attributes
of the element. It stores its values in $.cache
internally.
所以为了获得 data-*
你永远不会出错 .data()
:
$(".saveBtn").on("click", function() {
var saveBtn = $(this);
var detail = saveBtn.data("detail");
var relevantInput = saveBtn.parent().next();
var value = relevantInput.prop("value");
});
我只是想从两个元素中获取几个属性。从 input
元素获取 属性 value
按预期工作。问题在于从 button
元素获取 属性 data-detail
属性。它 returns 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");
// ...
});
那是因为 HTML 元素上没有 data-detail 属性。
下面是对.data(), .prop() and .attr()的简单解释:
DOM 元素是一个 对象 ,它具有 methods
和 properties
(来自 DOM
) 和 attributes
(来自呈现的 HTML
)。其中一些 properties
通过 attributes
id->id, class->className, title->title, style->style etc.
获得了他们的 initial value
考虑这个元素: <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"
So, some attributes and properties have 1:1 mapping. (change of the attr result change of the prop and vice versa).
考虑以下因素:
<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 name
是 data-*
而 property name
是 dataset
,所以:
<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)设置方法:
我) $('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"
So you can see that here is 1:1 mapping, attr change reflects prop and vice versa.
但是检查第三种方式:
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)
does not change theHTML5 data-*
attributes of the element. It stores its values in$.cache
internally.
所以为了获得 data-*
你永远不会出错 .data()
:
$(".saveBtn").on("click", function() {
var saveBtn = $(this);
var detail = saveBtn.data("detail");
var relevantInput = saveBtn.parent().next();
var value = relevantInput.prop("value");
});