Position():
获取匹配元素集合中第一个元素的当前坐标。相对于最近一级的position属性不为static的祖先元素偏移量。相对于offset parent的当前坐标值
Offset():
获取第一个元素的当前坐标,或者将每个元素的坐标设置为相对于文档的匹配元素集合。相对于偏移document。
应用实例:
点击edit,在下方添加一个编辑框,实现修改地址功能。每次都自动定位到当前正在编辑的按钮坐标。如图:
代码实现:
/**
* Add Address
*
* @param {string} postcode -Postcode.
* @description
* 1. Check postcode is not empty.
* 2. Search addresses by postcode.
* 3. Padding the data to select options.
* 4. Padding the data by option.
* 5. Ajax submit and reload.
*/
$body.on('click', '.addaddress-btn', function () {
var $this = $(this),
id = $this.data('id'),
ajaxData = {};
if ($this.hasClass('loading')) {
return false;
}
$this.addClass('loading');
ajaxData.id = id;
if ($body.hasClass('checkout-address-page')) {
ajaxData.type = 'checkout';
}
if (ajaxAddAddress !== undefined) {
ajaxAddAddress.abort();
}
ajaxAddAddress = $.ajax({
url: eventure.getUncachedUrl('/Base/AddressEditor'),
data: ajaxData,
success: function (data) {
var $modal,
$form,
$panel,
$postcodeSelect,
$country,
$stateCode,
usCountryID,
scrollHeight;
if ($body.hasClass('checkout-address-page')) {
if ($body.find('.check-address')) {
$('.check-address').remove();
}
$this.closest('div').append(data);
$modal = $('.check-address');
if ($this.hasClass('btn-red')) {
scrollHeight = $this.position().top + $('.basket-col').position().top - ($('.pre-header').height() + $('.navbar-section .navbar').height() + $('.price-menu').height() + $('.section-desktop').innerHeight()) - 10;
} else {
scrollHeight = $('.basket-col').position().top + $this.closest('.radio').position().top - ($('.pre-header').height() + $('.navbar-section .navbar').height() + $('.price-menu').height() + $('.section-desktop').innerHeight()) - 10;
}
$('.scroller').animate({
scrollTop: scrollHeight
});
} else {
$modal = $('.modal-addaddress');
$modal.remove();
$body.append(data);
}
$form = $modal.find('form');
$.validator.unobtrusive.parse($form);
$form.validate().settings.ignore = [];
$panel = $('.address-panel');
$postcodeSelect = $panel.find('.postcode-select');
$panel.find(".postcode-find").click(function () {
var $find = $(this),
postcode = $.trim($panel.find('.postcode').val()),
$loading = $panel.find(".postcode-loading");
if ($find.hasClass('loading')) {
return false;
}
//Check postcode is not empty.
if (postcode === '') {
eventure.message('error', 'Please enter postcode.');
return false;
}
$('.controls').show();
$find.addClass("loading");
$loading.show();
$panel.find('.postcode-select-wrap').hide();
// 1.Search addresses by postcode.
// 2.Padding the data to select options.
$.ajax({
url: '/Handlers/GetAdrApi.ashx',
data: {
postcode: postcode
},
success: function (data) {
var html = '<option value="">Please select</option>';
$find.removeClass("loading");
$loading.hide();
if (data.length) {
$.each(data, function (index, value) {
html += '<option value="' + index + '" data-county="' + value.County + '" data-town="' + value.Town + '" data-line1="' + value.Line1 + '" data-line2="' + value.Line2 + '" data-line3="' + value.Line3 + '">' + value.Line1 + ', ' + value.Line2 + ', ' + value.Line3 + ', ' + value.Town + ', ' + value.County + '</option>';
});
$postcodeSelect.html(html);
$panel.find('.postcode-select-wrap').show();
} else {
$postcodeSelect.html(html);
$panel.find('.postcode-select-wrap').hide();
eventure.message('error', 'Sorry, no addresses found.');
}
}
});
return false;
});
//Autofill the data.
$postcodeSelect.change(function () {
var $select = $(this),
$selected;
if ($select.val() !== '') {
$selected = $select.find('option').filter(':selected');
$panel.find('.address-1').val($selected.data('line1'));
$panel.find('.address-2').val($selected.data('line2'));
$panel.find('.city').val($selected.data('town'));
$panel.find('.county').val($selected.data('county'));
$panel.find('.country').val('14').select('refreshContents'); // UK
} else {
$panel.find('.address-1').val('');
$panel.find('.address-2').val('');
$panel.find('.city').val('');
$panel.find('.county').val('').select('refreshContents');
}
return false;
});
$country = $modal.find('.country');
$stateCode = $modal.find('.state-code-select');
usCountryID = $modal.find('.us-country-id').val();
$modal.find('select').select2({
minimumResultsForSearch: Infinity
});
if ($country.val() === usCountryID) {
$stateCode.show();
} else {
$stateCode.hide();
}
$country.on("change", function () {
if ($country.val() === usCountryID) {
$stateCode.show();
} else {
$stateCode.hide();
}
});
if (!$body.hasClass('checkout-address-page')) {
$modal.modal('show');
}
$this.removeClass('loading');
// Ajax submit the form and reload.
$form.submit(function () {
var $btn = $form.find('.btn-submit');
if ($btn.hasClass('loading')) {
return false;
}
if ($form.valid()) {
$btn.addClass('loading');
$form.ajaxSubmit({
success: function (data) {
if (data.status === 's') {
location.reload(true);
} else {
$btn.removeClass('loading');
eventure.message('error', data.message);
}
},
error: function () {
$btn.removeClass('loading');
eventure.message('error');
}
});
}
return false;
});
},
error: function () {
$this.removeClass('loading');
eventure.message('error');
}
});
return false;
});
注意:
1.JQuery不支持获取隐藏元素的偏移坐标,也不支持在<html>上设置margin.
2.visibility:hidden可以取到偏移量,display:none元素的position未定义。
3.jQuery获取数组的第一个元素:$('.radio').eq(0)
4.调试代码:console控制台确保元素唯一
5.是JS动态添加的,修改功能的节点也是JS动态添加的页面的,所以不能使用bootstrap的collapse插件。