oglasi: brez praznega prostora okrog kreative
AdSense odzivni enoti vnaprej doloci visino po sirini zaslona. Ce je postrezena kreativa nizja, ostane pod njo prazen rezerviran pas znotraj okvirja - to je bilo vidno na clanku pod DonCarlos oglasom. - AdSense komponenta po zapolnitvi poravna visino <ins> na dejansko visino oglasnega okvirja (ob 0/300/1000/2500 ms, ob vsaki spremembi DOM enote in ob resize). Nic se ne odreze, visina je natanko taksna kot oglas. MutationObserver zdaj tece tudi pri enotah brez onAdStatus. - InArticleAd: odstranjen minHeight 260 px, ki je rezerviral prostor tudi ce je bila kreativa nizja. - MultiplexAd: odstranjen min-h-[250px] iz istega razloga.
This commit is contained in:
@@ -44,11 +44,30 @@ export default function AdSense({
|
|||||||
|
|
||||||
// Google postavi data-ad-status na "filled", "unfilled" ali "unfill-optimized".
|
// Google postavi data-ad-status na "filled", "unfilled" ali "unfill-optimized".
|
||||||
// Ce statusa ni, se zanesemo na dejansko visino. Odlocimo se enkrat.
|
// Ce statusa ni, se zanesemo na dejansko visino. Odlocimo se enkrat.
|
||||||
|
// AdSense odzivni enoti vnaprej doloci visino po sirini zaslona. Ce je
|
||||||
|
// postrezena kreativa nizja, ostane pod njo prazen rezerviran pas znotraj
|
||||||
|
// okvirja. Visino <ins> zato poravnamo na dejansko visino oglasnega okvirja.
|
||||||
|
// Nic se ne odreze - visina je natanko taksna kot oglas.
|
||||||
|
let fitTimers: ReturnType<typeof setTimeout>[] = [];
|
||||||
|
const fitToCreative = () => {
|
||||||
|
const f = ins?.querySelector("iframe") as HTMLIFrameElement | null;
|
||||||
|
if (!ins || !f) return;
|
||||||
|
const h = f.getBoundingClientRect().height;
|
||||||
|
if (h > 10 && Math.abs(ins.getBoundingClientRect().height - h) > 2) {
|
||||||
|
ins.style.height = `${Math.ceil(h)}px`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const scheduleFit = () => {
|
||||||
|
fitTimers.forEach(clearTimeout);
|
||||||
|
fitTimers = [0, 300, 1000, 2500].map((d) => setTimeout(fitToCreative, d));
|
||||||
|
};
|
||||||
|
|
||||||
const decide = (filled: boolean) => {
|
const decide = (filled: boolean) => {
|
||||||
if (decided) return;
|
if (decided) return;
|
||||||
decided = true;
|
decided = true;
|
||||||
obs?.disconnect();
|
obs?.disconnect();
|
||||||
if (timer) clearTimeout(timer);
|
if (timer) clearTimeout(timer);
|
||||||
|
if (filled) scheduleFit();
|
||||||
onAdStatus?.(filled);
|
onAdStatus?.(filled);
|
||||||
};
|
};
|
||||||
// Visina samega <ins> ni dokaz - nekatere enote imajo rezerviran prostor.
|
// Visina samega <ins> ni dokaz - nekatere enote imajo rezerviran prostor.
|
||||||
@@ -76,11 +95,15 @@ export default function AdSense({
|
|||||||
pushed.current = true;
|
pushed.current = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
if (!onAdStatus || !ins) return;
|
if (!ins) return;
|
||||||
obs = new MutationObserver(check);
|
// Opazujemo tudi pri enotah brez onAdStatus - potrebujemo jih za poravnavo
|
||||||
|
// visine na kreativo.
|
||||||
|
obs = new MutationObserver(() => { check(); fitToCreative(); });
|
||||||
obs.observe(ins, { attributes: true, childList: true, subtree: true, attributeFilter: ["data-ad-status", "style"] });
|
obs.observe(ins, { attributes: true, childList: true, subtree: true, attributeFilter: ["data-ad-status", "style"] });
|
||||||
timer = setTimeout(() => decide(hasFrame()), 3000);
|
timer = setTimeout(() => decide(hasFrame()), 3000);
|
||||||
|
window.addEventListener("resize", scheduleFit);
|
||||||
check();
|
check();
|
||||||
|
scheduleFit();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (eager || !ins || typeof IntersectionObserver === "undefined") {
|
if (eager || !ins || typeof IntersectionObserver === "undefined") {
|
||||||
@@ -100,6 +123,8 @@ export default function AdSense({
|
|||||||
io?.disconnect();
|
io?.disconnect();
|
||||||
obs?.disconnect();
|
obs?.disconnect();
|
||||||
if (timer) clearTimeout(timer);
|
if (timer) clearTimeout(timer);
|
||||||
|
fitTimers.forEach(clearTimeout);
|
||||||
|
window.removeEventListener("resize", scheduleFit);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -204,7 +229,6 @@ export function InArticleAd() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={shown ? "my-6 rounded-md overflow-hidden bg-card border border-card-border" : ""}
|
className={shown ? "my-6 rounded-md overflow-hidden bg-card border border-card-border" : ""}
|
||||||
style={shown ? { minHeight: "260px" } : undefined}
|
|
||||||
>
|
>
|
||||||
{shown && (
|
{shown && (
|
||||||
<div className="text-[9px] text-muted-foreground/40 text-center pt-1 uppercase tracking-widest">Anzeige</div>
|
<div className="text-[9px] text-muted-foreground/40 text-center pt-1 uppercase tracking-widest">Anzeige</div>
|
||||||
@@ -230,7 +254,7 @@ export function MultiplexAd() {
|
|||||||
slot="4593001335"
|
slot="4593001335"
|
||||||
format="autorelaxed"
|
format="autorelaxed"
|
||||||
style={{ display: "block" }}
|
style={{ display: "block" }}
|
||||||
className={shown ? "w-full min-h-[250px]" : "w-full"}
|
className="w-full"
|
||||||
onAdStatus={setFilled}
|
onAdStatus={setFilled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user