jQuery .prop() 返回未定义,而 .attr() 对数据按预期工作-* [英] jQuery .prop() returns undefined, while .attr() works as expected for data-*
问题描述
我只是想从两个元素中获取几个属性.从 input
元素获取属性 value
按预期工作.问题在于从 button
元素获取属性 data-detail
属性.它在使用 .prop()
时返回 undefined
,但在使用 .attr()
时按预期工作.
谁能解释一下我目睹的这种奇怪的行为?
HTML
<label for="firstName">名字</label><div class="detailsControlBtns"><button id="editFirstName" class="btn ctaBtn greenBtn editBtn">编辑</button><button class="btn ctaBtn greenBtn saveBtn" data-detail="firstName">保存</button><button id="closeFirstName" class="btn ctaBtn greyBtn closeBtn">关闭</button><input type="text" id="firstName" name="firstName" value="[+firstName+]" readonly>
JS
$(".saveBtn").on("click", function() {var saveBtn = $(this);//以下语句产生未定义.使用 .attr() 时,它按预期工作.var detail = saveBtn.prop("data-detail");var relatedInput = saveBtn.parent().next();//以下语句按预期工作.var value = relatedInput.prop("value");//...});
那是因为 HTML 元素上没有 data-detail property.
这里是对.data()的简要说明,.prop() 和 .attr() :
DOM 元素是一个对象,它具有methods
和properties
(来自DOM
) 和 attributes
(来自呈现的 HTML
).其中一些 properties
通过 attributes
id->id, class->className, 获得它们的
initial value
标题->标题、样式->样式等
考虑这个元素: <input type="checkbox" checked data-detail="somedata" >
以下的结果是:
$('input').prop('id');//=>" "-空字符串,元素上存在属性 id(由 DOM 定义),但未设置.$('input').attr('id');//=>未定义 - 不存在.
<小时>如果您执行以下操作:
$('input').attr('id',"someID");$('input').prop('id');//=>某个ID"$('输入').attr('id');//=>某个ID"
还有:
$('input').prop('id',"someOtherID");$('input').prop('id');//=>其他 ID"$('input').attr('id');//=>其他 ID"
<块引用>
因此,某些属性和属性具有1:1 映射.(的变化prop 的 attr 结果变化,反之亦然).
<小时>考虑以下几点:
$('input').prop('value');//=>一些价值"$('输入').val();//=>一些价值"$('输入').attr('值');//=>一些价值"
如果你这样做了:
$('input').prop('value','newVal');//或者$('input').val('newVal');$('输入').prop('值');//=>"newVal" - 属性值$('输入').val();//=>"newVal" - 属性值$('输入').attr('值');//=>"someValue" - attr 的值没有改变,因为在这种情况下它不是 1:1 映射(prop 值的变化不会反映到属性值).
<小时>
案例 .data()强>
1) 获取方式:
- 记住 attribute name
是 data-*
而 property name
是 dataset
,所以:
$('input')[0].dataset;//=>[对象 DOMStringMap] { 详细信息:一些数据"}$('输入')[0].dataset.detail;//=>一些数据"$('输入').prop('数据集');//=>[object DOMStringMap] { detail: "somedata"}$('input').prop('dataset').detail;//=>一些数据"$('输入').data('详细信息');//=>一些数据"$('input').attr('data-detail');//=>一些数据"
2) 如何设置:
I) $('input').prop('dataset').detail='newData';
$('input').prop('dataset');//=>[对象 DOMStringMap] { 详细信息:新数据"}$('input').prop('dataset').detail;//=>新数据"$('input').attr('data-detail');//=>新数据"$('输入').data('详细信息');//=>新数据"
II) $('input').attr('data-detail','newData');
$('input').prop('dataset');//=>[对象 DOMStringMap] { 详细信息:新数据"}$('input').prop('dataset').detail;//=>新数据"$('input').attr('data-detail');//=>新数据"$('输入').data('详细信息');//=>新数据"
<块引用>
所以你可以看到这里是 1:1 映射,attr 变化反映了 prop 和反之亦然.
但是检查第三种方式:
III) $('input').data('detail','newData');
$('input').prop('dataset');//=>[对象 DOMStringMap] { 详细信息:一些数据"}$('input').prop('dataset').detail;//=>一些数据"$('input').attr('data-detail');//=>一些数据"$('输入').data('详细信息');//=>新数据"<----******
那么,这里发生了什么?
<块引用>$(elem).data(key, value)
不会改变 HTML5 data-*
属性元素的.它在内部将其值存储在 $.cache
中.
所以为了获得 data-*
你永远不会出错 .data()
:
$(".saveBtn").on("click", function() {var saveBtn = $(this);var detail = saveBtn.data("detail");var relatedInput = saveBtn.parent().next();var value = relatedInput.prop("value");});
I am simply trying to get a couple of properties from two elements. Getting the property value
from the input
element works as expected. The problem is with getting the property data-detail
property from the button
element. It returns undefined
when using .prop()
, but works as expected when using .attr()
.
Can anyone explain this odd behaviour I am witnessing?
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");
// ...
});
That's because there's no data-detail property on HTML element.
Here is a quick explanation for .data(), .prop() and .attr() :
DOM element is an object which has methods
, and properties
(from the DOM
) and attributes
(from the rendered HTML
). Some of those properties
get their initial value
by the attributes
id->id, class->className, title->title, style->style etc.
Consider this element: <input type="checkbox" checked data-detail="somedata" >
The result of the following would be:
$('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.
If you do the following:
$('input').attr('id',"someID");
$('input').prop('id'); // => "someID"
$('input').attr('id'); // => "someID"
And also:
$('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).
Consider the following:
<input type="text" data-detail="somedata" value="someValue">
$('input').prop('value'); // => "someValue"
$('input').val(); // => "someValue"
$('input').attr('value'); // => "someValue"
And if you do:
$('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).
Case with the .data()
1) How to get:
- Have in mind that attribute name
is data-*
and property name
is dataset
, so:
<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) How to set:
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"
So you can see that here is 1:1 mapping, attr change reflects prop and vice versa.
But check the third way:
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" <-----******
So, what is happening up here?
$(elem).data(key, value)
does not change theHTML5 data-*
attributes of the element. It stores its values in$.cache
internally.
So for getting data-*
you would never go wrong with .data()
:
$(".saveBtn").on("click", function() {
var saveBtn = $(this);
var detail = saveBtn.data("detail");
var relevantInput = saveBtn.parent().next();
var value = relevantInput.prop("value");
});
这篇关于jQuery .prop() 返回未定义,而 .attr() 对数据按预期工作-*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!