任何人都可以解释我目睹的这种奇怪的行为吗?
<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"); // ... });
解决方法
以下是.data(),.prop()和.attr()的快速说明:
DOM元素是一个对象,它具有方法和属性(来自DOM)和属性(来自呈现的HTML).其中一些属性通过属性id-> id,class-> className,title-> title,style-> style等获得其初始值.
考虑这个元素:< 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)如何获得:
– 请记住,属性名称是data- *,属性名称是数据集,因此:
<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"
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()永远不会出错:
$(".saveBtn").on("click",function() { var saveBtn = $(this); var detail = saveBtn.data("detail"); var relevantInput = saveBtn.parent().next(); var value = relevantInput.prop("value"); });