模态框加载图片后运行jQuery:Guillotine插件在AngularJS中的适配问题
I feel your pain—Guillotine is great for cropping/scaling, but it’s super picky about having the image fully loaded and visible before it can do its thing, especially in modals that start hidden. Let’s walk through some AngularJS-specific fixes that should resolve this:
1. Custom Directive: Wait for Image Load + Modal Visibility
Angular’s directive system is perfect here because it lets us tie the plugin initialization directly to the element’s lifecycle, and account for modal visibility. Here’s a reusable directive:
angular.module('yourAppName').directive('guillotineReady', function() { return { restrict: 'A', link: function(scope, elem, attrs) { // Handle both cached and newly loaded images function checkAndInit() { const modal = elem.closest('.modal'); // Adjust selector to match your modal // Only initialize if modal is visible AND image has valid dimensions if (modal.is(':visible') && elem[0].naturalWidth > 0) { // Clean up existing instance first to avoid duplicates if (elem.data('guillotine')) { elem.guillotine('destroy'); } // Initialize Guillotine with your options elem.guillotine({ width: 500, // Example: set your desired container width height: 400, zoomStep: 0.1 // Add your other config options here }); } else if (!modal.is(':visible')) { // Wait for the modal to finish showing modal.one('shown.bs.modal', function() { // Use your modal's show event (Bootstrap example) checkAndInit(); }); } } // Listen for image load event elem.on('load', checkAndInit); // If image is already cached, trigger the check immediately if (elem[0].complete) { checkAndInit(); } // Clean up when directive is destroyed (modal closed) scope.$on('$destroy', function() { if (elem.data('guillotine')) { elem.guillotine('destroy'); } }); } }; });
Then use it in your modal template:
<div class="modal fade" ng-show="isModalOpen"> <img src="{{selectedImageUrl}}" guillotine-ready alt="Image to scale"> </div>
2. Common Pitfalls to Avoid
- Cached Images: The
loadevent won’t fire if the image is already in the browser cache—always checkelem[0].completeto handle this case. - Hidden Modal Dimensions: If the modal starts with
display: none, the image will have 0 width/height even if loaded. Waiting for the modal’sshownevent ensures the image is rendered properly. - Duplicate Instances: Always destroy existing Guillotine instances before reinitializing, especially if the modal can be opened multiple times.
3. Quick Fix: $timeout for Modal Rendering
If you prefer a simpler approach without a directive, use Angular’s $timeout to give the modal time to render after opening:
$scope.openImageModal = function(imageUrl) { $scope.selectedImageUrl = imageUrl; $scope.isModalOpen = true; $timeout(function() { const img = document.getElementById('modal-image'); if (img.complete && img.naturalWidth > 0) { $(img).guillotine({ /* your options */ }); } else { $(img).on('load', function() { $(this).guillotine({ /* your options */ }); }); } }, 150); // Small delay to let Angular render the modal and image };
And in the template:
<div class="modal" ng-show="isModalOpen"> <img id="modal-image" src="{{selectedImageUrl}}" alt="Image"> </div>
Let me know if you need help adapting any of this to your specific modal setup (like if you’re using UI Bootstrap modals instead of vanilla Bootstrap)!
内容的提问来源于stack exchange,提问作者Szymon

