Daňové slevy 2024: Tímhle si letos snížíte daň z příjmů

20. 2. 2024
Doba čtení: 9 minut

Sdílet

Ilustrační fotografie.
Autor: Depositphotos Inc.
Ilustrační fotografie.
Konsolidační balíček ruší dvě slevy, u jiné dochází k úpravě podmínek. Co si můžete letos odečíst od daně z příjmů?

Všechny daňové slevy stanovuje § 35ba zákona o daních z příjmů (ZDP), § 35bb, § 35c a § 35 ZDP.

Sleva na poplatníka

Sleva na poplatníka je jediná sleva, na kterou nemusíte prokazovat nárok. (U zaměstnanců ji podmiňuje podpis Prohlášení poplatníka.) Navíc si ji všichni mohou uplatnit za celý rok i v případě, že nepracovali všech 12 měsíců. Musíte však mít aspoň nějaké zdanitelné příjmy (i když jen po část roku).

Výše slevy na poplatníka pro příjmy za rok 2023 je ve výši 30 840 Kč (měsíčně 2570 Kč) a ve stejné výši zůstává i pro příjmy za rok 2024.

Sleva na vyživovanou manželku/manžela

Slevu na vyživovanou manželku/manžela (dále jen manželku) mohou využít i registrované páry. Nárok na ni vzniká v případě, že s vámi žije daná osoba ve společné domácnosti a její příjmy (před odečtením výdajů) za minulý rok nepřesáhly hranici 68 000 Kč.

Do testovaného příjmu se započítává například:

  • hrubé příjmy od zaměstnavatele, příjmy z podnikání (před odečtením výdajů), příjmy z nájmu apod.,
  • všechny druhy důchodů,
  • nemocenské,
  • náhrada mzdy při pracovní neschopnosti,
  • ošetřování člena rodiny,
  • podpora v nezaměstnanosti,
  • peněžitá pomoc v mateřství.

Výčet není kompletní, jedná se o příjmy, u nichž se podle Finanční správy ČR nejčastěji chybuje.

Podle § 35ba se nezahrnují:

  • dávky státní sociální podpory (tedy i rodičovský příspěvek a porodné),
  • dávky pěstounské péče kromě odměny pěstouna (ta se započítává),
  • dávky osobám se zdravotním postižením,
  • dávky pomoci v hmotné nouzi,
  • příspěvek na péči, sociální služby,
  • státní příspěvky na penzijní připojištění a doplňkové penzijní spoření se státním příspěvkem,
  • státní příspěvky podle zákona o stavebním spoření,
  • stipendia studujícím soustavně se připravujícím na budoucí povolání.

U manželů, kteří mají majetek ve společném jmění manželů, se do vlastního příjmu manžela nezahrnuje příjem, který plyne druhému z manželů nebo se pro účely daně z příjmů považuje za příjem druhého z manželů.

Příjmy ze závislé činnosti za rok 2023, které byly vyplaceny do konce ledna 2024, se ještě počítají do příjmů za rok 2023. U sociálních dávek se započítávají jen dávky vyplacené v roce 2023.

Nová podmínka ohledně péče o dítě do 3 let (a vše s ní související) platí až pro příjmy od roku 2024.

Nově přibyla pro vznik nároku na slevu ještě podmínka, která nárok přiznává pouze v případě, že protějšek, na kterého si slevu uplatňujete, pečuje o dítě do tří let věku.

Konsolidační balíček nově podrobnosti o slevě přesunul do nového § 35bb, podle kterého je možné slevu na manžela (nově zákon uvádí jen obecný pojem manžel, ale zahrnuje samozřejmě obě pohlaví) uplatnit jen v případě, že poplatník žije ve společně hospodařící domácnosti s manželem a vyživovaným dítětem poplatníka, které nedovršilo věku 3 let, a manžel poplatníka nemá vlastní příjem přesahující za zdaňovací období 68000 Kč.

Do vlastního příjmu manžela pro účely slevy se dle nového paragrafu nezahrnují:

  • dávky osobám se zdravotním postižením, pomoci v hmotné nouzi, státní sociální podpory a pěstounské péče s výjimkou odměny pěstouna,
  • příspěvky na péči a na sociální služby,
  • státní příspěvky na penzijní připojištění se státním příspěvkem podle zákona upravujícího penzijní připojištění se státním příspěvkem, státní příspěvky na doplňkové penzijní spoření podle zákona upravujícího doplňkové penzijní spoření a státní podpory podle zákona upravujícího stavební spoření,
  • stipendia poskytovaná studujícím soustavně se připravujícím na budoucí povolání,
  • příjmy plynoucí z důvodu péče o blízkou nebo jinou osobu, která má nárok na příspěvek na péči podle zákona upravujícího sociální služby, který je od daně osvobozen,
  • příjmy, které vznikly jako důsledek porušení podmínek osvobození příjmu nebo uplatnění nezdanitelné části základu daně, a
  • příjmy, které plynou druhému z manželů nebo se pro účely daně z příjmů považují za příjem druhého z manželů v případě manželů, kteří mají společné jmění manželů.

Výše slevy činí 24 840 Kč nebo 49 680 Kč v případě, že je váš protějšek držitelem průkazu ZTP/P. Zvýšenou slevu můžete uplatnit od chvíle, kdy Úřad práce ČR rozhodne o vydání průkazu ZTP/P (pak nárok prokážete oznámením o rozhodnutí), o nároku tedy nerozhoduje to, zda už průkaz fyzicky vlastníte.

Pokud došlo ke sňatku nebo registraci teprve minulý rok, máte nárok na 1/12 z roční výše slevy za každý měsíc, ve kterém byla daná osoba vaší manželkou/manželem či registrovaným partnerem/partnerkou už na začátku měsíce. To samé se uplatňuje i u podmínky péče o dítě (ačkoli s platností až pro příjmy za rok 2024): v roce narození a v roce dosažení 3 let věku dítěte uplatňujete vždy 1/12 roční slevy za každý měsíc, na jehož počátku jsou tyto podmínky splněny.

Daňovou slevu na vyživovanou manželku můžete uplatnit jen po skončení zdaňovacího období v rámci zúčtování daní zaměstnavatelem, nebo při podání daňového přiznání. Nárok dokládáte čestným prohlášením o výši příjmů vaší polovičky a od příštího roku – podle informací pracovníka finančního úřadu – také potvrzením od úřadu práce o pobírání rodičovského příspěvku.

Změny v daních 2024: Které z nich vás ovlivní už při nadcházejícím přiznání a zúčtování daní? Přečtěte si také:

Změny v daních 2024: Které z nich vás ovlivní už při nadcházejícím přiznání a zúčtování daní?

Sleva za umístění dítěte: letos naposledy

Sleva za umístění dítěte nemá pevně danou částku, jen horní strop, který vyplývá z úrovně minimální mzdy pro daný rok. Pro příjmy za rok 2023 platí, že je možné odečíst slevu maximálně ve výši 17 300 Kč

Konkrétní výše slevy závisí na tom, kolik jste za uplynulý rok zaplatili na tzv. školkovném při umístění dítěte v zařízení péče o děti předškolního věku (např. mateřská škola, registrovaná dětská skupina apod.). Podmínkou pro uplatnění je, že s vámi dítě žije ve společné domácnosti. Slevu si může uplatnit jen jeden z rodičů.

Sleva se uplatňuje jen za celý rok po jeho skončení buď v rámci zúčtování daní zaměstnavatelem, nebo při podání daňového přiznání. Výše nároku se prokazuje potvrzením od provozovatele zařízení.

Školkovné si poplatníci od daně odečtou letos naposledy (za příjmy za rok 2023). Podle ministra financí Zbyňka Stanjury tento benefit stejně uplatňovali hlavně středně- až vysokopříjmové skupiny obyvatel, protože ty nízkopříjmové ho nemohly využít pro nízký základ daně.

Sleva na děti (daňové zvýhodnění)

Pravidla daňového zvýhodnění upravuje § 35c zákona o daních z příjmů. Snížit si o ně daň může poplatník, který s vyživovaným dítětem žije ve společné domácnosti (vždy ale jen jeden z rodičů).

Zaměstnanci si mohou daňové zvýhodnění uplatňovat i na měsíční bázi, podnikatelé pouze najednou až v rámci daňového přiznání.

Výše daňové slevy činí:

  • 15 204 Kč ročně na první dítě (1267 Kč měsíčně),
  • 22 320 Kč na druhé dítě (1860 Kč měsíčně),
  • 27 840 Kč na třetí a další dítě (2320 měsíčně).

I u daňové slevy na dítě platí, že se zvyšuje na dvojnásobek, pokud je potomek držitelem průkazu ZTP/P (a opět platí, že lze vyšší slevu nárokovat i bez průkazu ZTP/P, pouze s rozhodnutím úřadu o jeho přiznání). V takovém případě je sleva ve výši:

  • 30 408 Kč na první dítě (2534 Kč měsíčně),
  • 44 640 Kč na druhé dítě (3720 Kč měsíčně),
  • 55 680 Kč na třetí a další dítě (4640 měsíčně).

Vyživovaným dítětem je nezletilé dítě, které s vámi žije ve společné domácnosti až do měsíce jeho 18. narozenin (včetně). Dále pak i zletilé dítě do 26 let věku (včetně), které se soustavně připravuje na budoucí povolání a nepobírá invalidní důchod třetího stupně. V měsíci, kdy dítě dosáhne 18. nebo 26. roku, se sleva neuplatňuje v případě, že se narodilo první den v měsíci.

Slevu na čerstvě narozené dítě je možné uplatnit už za měsíc, ve kterém se narodilo, ať už je to kterýkoli den v měsíci.

Kompletně vyživované dítě definuje zákon v § 35c odst. 6.

Pro prokázání nároku na slevu na dítě musíte dodat rodný list (jen poprvé) a dále případně potvrzení o studiu. Je-li dítě držitelem průkazu ZTP/P, dokládáte také tento průkaz či potvrzení o jeho přiznání.

Protože si může slevu na dítě uplatnit jen jeden z rodičů, budete potřebovat také potvrzení od zaměstnavatele druhého z rodičů, jestli si a v jaké výši ten (ne)uplatňuje daňové zvýhodnění na některé z vašich dětí. OSVČ dokládají místo tohoto potvrzení čestné prohlášení.

Daňový bonus

Daňové zvýhodnění vás může jako jediná daňová sleva po odečtení od daně dostat až „do minusu“. Jestliže vám po odečtení daňového zvýhodnění vyjde záporné číslo, budete žádat finanční úřad o přeplatek, protože vám vznikl tzv. daňový bonus.

Abyste na něj získali nárok, musíte mít za předchozí rok zdanitelné příjmy ze zaměstnání či podnikání nejméně ve výši šestinásobku minimální mzdy. Pro příjmy za rok 2023 jde o částku 103 800 Kč (pro příjmy za rok 2024 pak o částku 113 400 Kč). Výše daňového bonusu už není na měsíční ani roční bázi nijak zastropovaná.

Konsolidační balíček schválili senátoři. Které změny ovlivní vaše peněženky? Přečtěte si také:

Konsolidační balíček schválili senátoři. Které změny ovlivní vaše peněženky?

Sleva na invaliditu

Poplatníci v invalidním důchodu mají nárok na daňovou slevu ve výši 2520 Kč ročně v případě invalidity I. a II. stupně.

Jsou-li zařazeni do III. stupně, mají nárok na slevu ve výši dvojnásobku, tedy 5040 Kč ročně. V případě, že byste byli během měsíce přeřazeni do jiného stupně invalidity s důsledkem změny výše slevy, rozhoduje za daný měsíc o její výši stav na jeho počátku.

Oprávnění uplatnit slevu prokážete potvrzením o přiznání důchodu a potvrzením o výplatě důchodu od České správy sociálního zabezpečení.

Sleva pro držitele průkazu ZTP/P

Slevu ve výši 16 140 Kč za rok si může uplatnit držitel průkazu ZTP/P. Nelze ji automaticky nárokovat za celý rok, ale jen za měsíce (pak tedy ve výši 1/12 z částky 16 140 Kč za každý měsíc splnění podmínek), na jejichž počátku spadal poplatník do kategorie ZTP/P. Slevu dokládáte průkazem ZTP/P nebo rozhodnutím Úřadu práce ČR o jeho přiznání. Pro vznik nároku tedy není nutné mít průkaz už fyzicky u sebe.

Sleva na studenta: letos naposledy

Na daňovou slevu ve výši 4020 Kč ročně mají nárok ti, kteří se soustavně připravují na budoucí povolání studiem (v případě vysoké školy platí pro prezenční, distanční i kombinovanou formu) a ještě nedosáhli 26 let. O dva roky déle (sleva se dá uplatnit nejpozději za měsíc dovršení daného věku) si mohou slevu odečítat od daně studenti na doktorském studiu prezenční formou.

Opět platí, že o nároku v daném měsíci rozhoduje stav platný na jeho počátku, tedy zda jste byli na počátku měsíce studenty. Slevu prokážete potvrzením o studiu.

Jde o další slevu, která se ruší a pro příjmy za rok 2023 ji můžete uplatnit naposledy. Stanjura rušení slevy vysvětloval tím, že na ni paradoxně dosáhnou jen ti, kteří mají při studiu vyšší příjmy. Těm ostatním totiž zdanění eliminuje v plné míře sleva na poplatníka.

Sleva za zastavenou exekuci

Od roku 2022 platí nová daňová sleva, kterou je možné zohlednit v zúčtování daní či přiznání. Vznikla kvůli zastavování marně vymáhaných exekucí (vymáhání nebylo úspěšné ani zčásti) trvajících přes 3 roky a týkajících se pohledávek do 1500 Kč (bez příslušenství dluhu).

bitcoin_smenarna

Věřitelé, kterým byla takto zastavena exekuce, si mohou podle § 35 odst. 4 zákona o daních z příjmů uplatnit daňovou slevu ve výši náhrady za vymáhanou pohledávku (bez příslušenství). Musí však prokázat, v jaké výši byla náhrada za zastavenou exekuci přiznána (přiznává ji exekutor při zastavení exekuce) a předložit usnesení o zastavení exekuce.

Náhrada odpovídá 30 % z vymáhané pohledávky. Vzhledem k tomu, že ta činí max. 1500 Kč, může maximální sleva za jednu zastavenou exekuci činit nejvýše 450 Kč.

Jak podáváte své daňové přiznání k dani z příjmů fyzických osob?

Zřídil vám stát datovku, a vy stále podáváte daně na papíře? Hrozí vám pokuta Přečtěte si také:

Zřídil vám stát datovku, a vy stále podáváte daně na papíře? Hrozí vám pokuta

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
Upozorníme vás na články, které by vám neměly uniknout (maximálně 2x týdně).
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »