为jQuery插件实现可配置选项功能的技术求助
解决jQuery货币转换插件配置不生效的问题
问题根源
你的代码里存在几个关键问题导致配置无法生效:
- 插件初始化方式错误,直接修改
defaults的调用写法不对 - 硬编码覆盖了配置值(比如手动写死了
values数组) - 插件方法仅合并了配置但没有将合并后的配置应用到实际逻辑中
- 存在语法错误(比如MutationObserver部分的注释写法破坏了代码结构)
修复后的完整代码
$(document).ready(function() { // 定义插件方法,处理配置合并并应用 $.fn.tsCurrOptions = function(options) { // 合并默认配置与用户配置,并更新全局defaults $.fn.tsCurrOptions.defaults = $.extend({}, $.fn.tsCurrOptions.defaults, options); // 初始化插件逻辑 initCurrencyConverter(); }; // 默认配置 $.fn.tsCurrOptions.defaults = { AvailableCurrencies: ["GBP", "USD", "EUR", "AUD"], BaseCurrency: "GBP", DecimalPrecision: 2 }; // 核心初始化逻辑 function initCurrencyConverter() { const settings = $.fn.tsCurrOptions.defaults; const valuesCurr = settings.AvailableCurrencies; const baseCurr = settings.BaseCurrency; const deciP = settings.DecimalPrecision; // 添加转换容器 $(".product-price").after('<div class="ts-currency-converter"></div>'); // 创建货币选择下拉框 const select = $('<select>').prop('id', 'currency').prop('name', 'currency'); $(valuesCurr).each(function() { select.append($("<option>").prop('value', this).text(this.charAt(0).toUpperCase() + this.slice(1))); }); const label = $("<label>").prop('for', 'currency').text(""); const br = $("<br>"); $('.header-display-desktop').before(label).before(select).before(br); let resultCurr; // 设置货币转换基础 fx.base = baseCurr; fx.settings = { from: fx.base }; // 初始化本地存储 const currencylocalStorage = localStorage.getItem('Currency'); if (!currencylocalStorage) { localStorage.Currency = fx.base; } // 获取汇率数据 $.getJSON('https://api.exchangerate-api.com/v4/latest/USD', function(data) { if (typeof fx !== "undefined" && fx.rates) { fx.rates = data.rates; fx.base = data.base; } else { window.fxSetup = { rates: data.rates, base: data.base }; } // 提取纯文本方法 $.fn.justtext = function() { return $(this).clone().children().remove().end().text(); }; // 价格更新逻辑 $.fn.hentryGrid = function() { const localCurr = localStorage.getItem('Currency'); $('.hentry').each(function() { const self = $(this); const hasSale = $(this).find('.product-price').children().length > 0; if (hasSale) { const saleOriginalPrice = self.find('.original-price').text().replace(/[^\d.]/g, ''); const salePrice = $(this).find('.product-price').justtext().replace(/[^\d.]/g, ''); const saleupdateCurr = fx.convert(salePrice, { to: localCurr }); const saleTsUpdateCurr = accounting.formatMoney(saleupdateCurr, "", deciP, ",", "."); const saleOrigina1updateCurr = fx.convert(saleOriginalPrice, { to: localCurr }); const saleOrigina1TsUpdateCurr = accounting.formatMoney(saleOrigina1updateCurr, "", deciP, ",", "."); self.find(".ts-currency-converter").html(` <div class="ts-price"> <span class="ts-orignal-price">${localCurr} ${saleOrigina1TsUpdateCurr}</span> <span class="ts-sale-price">${localCurr} ${saleTsUpdateCurr}</span> </div> `); } else { const myTextSub = self.find('.product-price').text(); const priceTxt = myTextSub.replace(/[^a-z]/gi, ''); const localamount = myTextSub.replace(/[^\d.]/g, ''); const localupdateCurr = fx.convert(localamount, { to: localCurr }); const formattedPrice = accounting.formatMoney(localupdateCurr, "", deciP, ",", "."); self.find(".ts-currency-converter").html(` <div class="ts-price">${priceTxt} ${localCurr} ${formattedPrice}</div> `); } }); }; // 页面加载时更新价格 const localCurr = localStorage.getItem('Currency'); $("select#currency").val(localCurr); $.fn.hentryGrid(); // 切换货币时更新 $('#currency').on('change', function() { resultCurr = this.value; localStorage.Currency = resultCurr; $.fn.hentryGrid(); }); // 变体更新监听 $('.variant-select-wrapper').on('data-attribute-changed', function() { const data = $('#contains-data').data('text'); alert('Data changed to: ' + data); }); // MutationObserver监听变体变化 const targetNode = document.querySelector('.variant-select-wrapper'); const config = { attributes: true, childList: true, subtree: true }; const callback = (mutationList) => { for (const mutation of mutationList) { if (mutation.type === 'attributes') { $.fn.hentryGrid(); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); }); } // 正确调用插件,传入用户自定义配置 $.fn.tsCurrOptions({ AvailableCurrencies: ["GBP", "USD", "EUR", "AUD", "CAD"], BaseCurrency: "EUR", DecimalPrecision: 5 }); });
关键修改说明
- 重构插件结构:将核心逻辑封装到
initCurrencyConverter函数中,插件方法合并配置后自动调用初始化逻辑 - 修正配置应用:所有逻辑中使用合并后的
settings变量,不再直接取defaults或硬编码值 - 修复初始化方式:用
$.fn.tsCurrOptions({...})替代错误的$.fn.tsCurrOptions.defaults({...})调用 - 修复语法错误:修正MutationObserver部分的注释写法,避免破坏代码结构
- 优化模板字符串:用ES6模板字符串替代拼接,减少语法错误
- 统一精度配置:之前代码里有一处硬写的
2,现在全部改用配置的deciP变量
内容的提问来源于stack exchange,提问作者Muhammad Waqas
相关产品推荐
相关产品推荐

