使用Select2插件整合谷歌网站翻译器时触发栈溢出错误
I've run into this exact issue before when trying to customize Google Translate's default dropdown with Select2—here's how I fixed it:
Why This Happens
The error almost always comes from circular event triggers or repeated initialization between Google Translate's native dropdown and Select2. Google Translate dynamically injects its dropdown into the DOM, and if you're not careful with timing or event handling, the two components end up triggering each other's change events infinitely, blowing up the call stack.
Step-by-Step Fix
1. Wait for Google Translate to Fully Load Before Initializing Select2
Google Translate doesn't inject its dropdown immediately, so trying to initialize Select2 too early can lead to repeated attempts (and eventually stack overflow). Instead, hook into the googleTranslateElementInit function or use a retry loop to detect when the dropdown is ready:
// Wait for Google Translate to load its dropdown function initCustomTranslateDropdown() { const googleTranslateDropdown = document.querySelector('.goog-te-combo'); if (!googleTranslateDropdown) { // Retry if element isn't ready yet setTimeout(initCustomTranslateDropdown, 100); return; } // Hide the original Google Translate dropdown googleTranslateDropdown.style.display = 'none'; // Create a new select element for Select2 const customSelect = document.createElement('select'); customSelect.id = 'custom-translate-select'; // Copy options from Google's dropdown to our custom select Array.from(googleTranslateDropdown.options).forEach(option => { customSelect.appendChild(option.cloneNode(true)); }); // Insert our custom select next to Google's dropdown googleTranslateDropdown.parentNode.appendChild(customSelect); // Initialize Select2 $('#custom-translate-select').select2({ theme: 'your-theme-name', // Match your site's theme width: '100%' }); // Sync custom select with Google's dropdown (and prevent loops) $('#custom-translate-select').on('change', function() { const selectedValue = $(this).val(); // Only trigger if values don't match to avoid circular calls if (googleTranslateDropdown.value !== selectedValue) { googleTranslateDropdown.value = selectedValue; // Trigger Google Translate's change event manually googleTranslateDropdown.dispatchEvent(new Event('change')); } }); // Sync Google's dropdown changes back to our custom select googleTranslateDropdown.addEventListener('change', function() { const selectedValue = this.value; if ($('#custom-translate-select').val() !== selectedValue) { $('#custom-translate-select').val(selectedValue).trigger('change.select2'); } }); } // Call this function after Google Translate's init window.googleTranslateElementInit = function() { new google.translate.TranslateElement({ pageLanguage: 'en', // Your default language includedLanguages: 'es,fr,de', // Your target languages layout: google.translate.TranslateElement.InlineLayout.SIMPLE }, 'google_translate_element'); // Wait a bit more for the dropdown to be injected setTimeout(initCustomTranslateDropdown, 500); };
2. Avoid Repeated Initialization
Make sure your Select2 initialization code only runs once. If you're using a framework, wrap this logic in a mounted hook or a one-time execution block to prevent multiple calls that could stack up.
3. Disable Unnecessary Event Bubbling
If you still see stack overflow issues, add event.stopPropagation() in your change handlers to prevent the event from triggering the other component's handler unexpectedly:
$('#custom-translate-select').on('change', function(e) { e.stopPropagation(); // Rest of your sync logic... });
Quick Checks
- Never initialize Select2 directly on the original Google Translate dropdown—always use a separate custom select element.
- Double-check for other scripts that might be modifying the Google Translate dropdown or listening to its change events, as these could also cause loops.
This approach keeps the two components in sync without triggering infinite event loops, fixing the stack overflow error while preserving your custom Select2 theme.
内容的提问来源于stack exchange,提问作者sksallaj

