1. 程式人生 > >JQuery position().top和offset().top的區別

JQuery position().top和offset().top的區別

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外掛。