fix(adsense): Anchor/Vignette solo visibles cuando AdSense llena slot
- Anchor Ads: Cambiar de visibility:hidden a transform:translateY() para que AdSense pueda medir dimensiones del slot - Vignette Ads: Solo mostrar overlay cuando data-ad-status="filled" - Mover card Exclusiones a columna izquierda en admin 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,7 @@ final class AdsensePlacementFormBuilder
|
|||||||
$html .= $this->buildDiagramSection();
|
$html .= $this->buildDiagramSection();
|
||||||
$html .= $this->buildPostLocationsGroup($componentId);
|
$html .= $this->buildPostLocationsGroup($componentId);
|
||||||
$html .= $this->buildInContentAdsGroup($componentId);
|
$html .= $this->buildInContentAdsGroup($componentId);
|
||||||
|
$html .= $this->buildExclusionsGroup($componentId);
|
||||||
$html .= ' </div>';
|
$html .= ' </div>';
|
||||||
|
|
||||||
// COLUMNA DERECHA (5 cols)
|
// COLUMNA DERECHA (5 cols)
|
||||||
@@ -56,7 +57,6 @@ final class AdsensePlacementFormBuilder
|
|||||||
$html .= $this->buildRailAdsGroup($componentId);
|
$html .= $this->buildRailAdsGroup($componentId);
|
||||||
$html .= $this->buildAnchorAdsGroup($componentId);
|
$html .= $this->buildAnchorAdsGroup($componentId);
|
||||||
$html .= $this->buildVignetteAdsGroup($componentId);
|
$html .= $this->buildVignetteAdsGroup($componentId);
|
||||||
$html .= $this->buildExclusionsGroup($componentId);
|
|
||||||
$html .= ' </div>';
|
$html .= ' </div>';
|
||||||
|
|
||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
|
|||||||
@@ -594,7 +594,8 @@ final class AdsensePlacementRenderer
|
|||||||
// === CSS via CSSGenerator ===
|
// === CSS via CSSGenerator ===
|
||||||
$cssRules = [];
|
$cssRules = [];
|
||||||
|
|
||||||
// Base anchor styles - OCULTO POR DEFECTO hasta que AdSense llene el slot
|
// Base anchor styles - FUERA DE PANTALLA por defecto (NO usar visibility:hidden)
|
||||||
|
// Usamos transform para mover fuera de la pantalla, asi AdSense puede medir el slot
|
||||||
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad', [
|
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad', [
|
||||||
'position' => 'fixed',
|
'position' => 'fixed',
|
||||||
'left' => '0',
|
'left' => '0',
|
||||||
@@ -603,32 +604,31 @@ final class AdsensePlacementRenderer
|
|||||||
'background' => '#f8f9fa',
|
'background' => '#f8f9fa',
|
||||||
'border-color' => '#dee2e6',
|
'border-color' => '#dee2e6',
|
||||||
'box-shadow' => '0 -2px 10px rgba(0,0,0,0.1)',
|
'box-shadow' => '0 -2px 10px rgba(0,0,0,0.1)',
|
||||||
'transition' => 'height 0.3s ease, transform 0.3s ease, opacity 0.3s ease',
|
'transition' => 'height 0.3s ease, transform 0.3s ease',
|
||||||
'display' => 'flex',
|
'display' => 'flex',
|
||||||
'align-items' => 'center',
|
'align-items' => 'center',
|
||||||
'justify-content' => 'center',
|
'justify-content' => 'center',
|
||||||
'opacity' => '0',
|
|
||||||
'visibility' => 'hidden',
|
|
||||||
'pointer-events' => 'none',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Mostrar anchor cuando AdSense llena el slot
|
|
||||||
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.ad-loaded', [
|
|
||||||
'opacity' => '1',
|
|
||||||
'visibility' => 'visible',
|
|
||||||
'pointer-events' => 'auto',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Anchor TOP: fuera de pantalla hacia arriba, visible cuando se carga
|
||||||
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-top', [
|
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-top', [
|
||||||
'top' => '0',
|
'top' => '0',
|
||||||
'border-bottom-width' => '1px',
|
'border-bottom-width' => '1px',
|
||||||
'border-bottom-style' => 'solid',
|
'border-bottom-style' => 'solid',
|
||||||
|
'transform' => 'translateY(-100%)',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Anchor BOTTOM: fuera de pantalla hacia abajo, visible cuando se carga
|
||||||
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-bottom', [
|
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-bottom', [
|
||||||
'bottom' => '0',
|
'bottom' => '0',
|
||||||
'border-top-width' => '1px',
|
'border-top-width' => '1px',
|
||||||
'border-top-style' => 'solid',
|
'border-top-style' => 'solid',
|
||||||
|
'transform' => 'translateY(100%)',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Mostrar anchor cuando AdSense llena el slot (desliza a posicion visible)
|
||||||
|
$cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.ad-loaded', [
|
||||||
|
'transform' => 'translateY(0)',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Controls container
|
// Controls container
|
||||||
|
|||||||
@@ -254,31 +254,68 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Muestra el vignette
|
* Muestra el vignette SOLO si AdSense lleno el slot
|
||||||
*/
|
*/
|
||||||
function showVignette() {
|
function showVignette() {
|
||||||
if (!canShow() || triggered) return;
|
if (!canShow() || triggered) return;
|
||||||
|
|
||||||
triggered = true;
|
triggered = true;
|
||||||
|
|
||||||
// Mostrar overlay
|
// Buscar el elemento ins de AdSense dentro del overlay
|
||||||
overlay.classList.add('active');
|
var ins = overlay.querySelector('ins.adsbygoogle');
|
||||||
document.body.style.overflow = 'hidden';
|
if (!ins) return;
|
||||||
|
|
||||||
// Incrementar contadores
|
// Funcion para mostrar el overlay cuando el ad esta listo
|
||||||
pageShowCount++;
|
function showIfFilled() {
|
||||||
var sessionCount = parseInt(sessionStorage.getItem(STORAGE_KEYS.sessionCount) || '0');
|
var status = ins.getAttribute('data-ad-status');
|
||||||
sessionStorage.setItem(STORAGE_KEYS.sessionCount, (sessionCount + 1).toString());
|
if (status === 'filled') {
|
||||||
|
// AdSense lleno el slot - mostrar overlay
|
||||||
|
overlay.classList.add('active');
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
|
||||||
// Manejar delay del boton cerrar
|
// Incrementar contadores
|
||||||
var closeBtn = overlay.querySelector('.roi-vignette-close');
|
pageShowCount++;
|
||||||
if (closeBtn && closeBtn.classList.contains('delayed')) {
|
var sessionCount = parseInt(sessionStorage.getItem(STORAGE_KEYS.sessionCount) || '0');
|
||||||
var delay = parseInt(closeBtn.dataset.delay || '0') * 1000;
|
sessionStorage.setItem(STORAGE_KEYS.sessionCount, (sessionCount + 1).toString());
|
||||||
|
return true;
|
||||||
setTimeout(function() {
|
} else if (status === 'unfilled') {
|
||||||
closeBtn.classList.remove('delayed');
|
// AdSense no tiene anuncio - no mostrar nada
|
||||||
}, delay);
|
triggered = false; // Permitir reintento mas tarde
|
||||||
|
return true; // Detener observacion
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verificar si ya tiene estado
|
||||||
|
if (showIfFilled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Observar cambios en data-ad-status
|
||||||
|
var observer = new MutationObserver(function(mutations) {
|
||||||
|
mutations.forEach(function(mutation) {
|
||||||
|
if (mutation.type === 'attributes' && mutation.attributeName === 'data-ad-status') {
|
||||||
|
if (showIfFilled()) {
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(ins, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['data-ad-status']
|
||||||
|
});
|
||||||
|
|
||||||
|
// Timeout de seguridad: despues de 5s desconectar observer
|
||||||
|
setTimeout(function() {
|
||||||
|
observer.disconnect();
|
||||||
|
// Si no se lleno, permitir reintento
|
||||||
|
var status = ins.getAttribute('data-ad-status');
|
||||||
|
if (status !== 'filled') {
|
||||||
|
triggered = false;
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user