如何重写Shopify.addItem函数?当前重写代码未生效
Let's break down why your override isn't working and fix it step by step.
The Problem Recap
You're trying to override Shopify.addItem to add cart request limits, but your code doesn't execute as expected. Even though you're loading your snippet after theme.js, you can access the Shopify object, but Shopify.addItem is undefined when your override runs. Later, the original function still shows up when you log the Shopify object.
Why This Happens
Most likely, Shopify.addItem isn't defined immediately when theme.js loads. Instead, it's being assigned after an asynchronous event (like DOMContentLoaded or a jQuery ready callback) inside theme.js. When your self-executing function runs, Shopify.addItem hasn't been created yet—so originalAddItem becomes undefined. Then, once theme.js finishes initializing, it overwrites your broken override with the real function.
Fix 1: Wait for the Function to Exist (Polling Method)
This reliable approach checks periodically until Shopify.addItem is available, then applies your override. It works even if you don't know exactly when the function is initialized:
(function() { function attemptOverride() { // Check if the original function exists if (typeof Shopify.addItem === 'function') { const originalAddItem = Shopify.addItem; Shopify.addItem = function(variant_id, quantity, callback) { console.log('in overridden function'); // Add your request limit logic here (e.g., debounce, throttle) // Example: Prevent multiple rapid requests if (this.lastAddRequest && Date.now() - this.lastAddRequest < 1000) { console.log('Request throttled: wait 1 second before adding again'); return; } this.lastAddRequest = Date.now(); // Call the original function with the same arguments return originalAddItem.apply(this, arguments); }; console.log('Shopify.addItem successfully overridden!'); } else { // Wait 100ms and check again setTimeout(attemptOverride, 100); } } // Start the override attempt attemptOverride(); })();
Fix 2: Hook Into the DOM Ready Event (If Applicable)
If you notice theme.js initializes Shopify.addItem inside a DOMContentLoaded or jQuery $(document).ready callback, you can run your override after that event finishes using a zero-delay timeout (which pushes your code to the end of the event loop):
// Wait for the DOM to be fully loaded document.addEventListener('DOMContentLoaded', function() { // Use setTimeout with 0 delay to ensure theme.js's ready code runs first setTimeout(function() { const originalAddItem = Shopify.addItem; Shopify.addItem = function(variant_id, quantity, callback) { console.log('in overridden function'); // Add your request limit logic here return originalAddItem.apply(this, arguments); }; }, 0); });
Fix 3: Override the Shopify Object's Property Definition
For more control, use Object.defineProperty to intercept when addItem is assigned. This works even if theme.js reassigns the function later:
(function() { let originalAddItem; Object.defineProperty(Shopify, 'addItem', { get: function() { return originalAddItem; }, set: function(newFunction) { // Store the original function originalAddItem = function(variant_id, quantity, callback) { console.log('in overridden function'); // Add your request limit logic here return newFunction.apply(this, arguments); }; }, configurable: true, enumerable: true }); })();
How to Verify It's Working
After applying the fix, test by running Shopify.addItem(yourVariantId) in the browser console—you should see your in overridden function log message, followed by the original function's in add Item log.
内容的提问来源于stack exchange,提问作者awebartisan

