Můžete si vzít dovolenou, i když ji zaměstnavatel neschválí, ale vy za sebe zajistíte náhradu svým kolegou?

5. 6. 2025
Doba čtení: 6 minut

Sdílet

Ilustrační foto.
Autor: Depositphotos Inc.
Ilustrační foto.
Jak moc vám při výpovědi z práce, s níž nesouhlasíte, pomůže, že jste dosud, třeba i více než 10 let, byli vzorným pracovníkem? Rovnou vám řekneme, že v budoucnu možná skoro vůbec.

Firma rozvázala se zaměstnankyní pracovní poměr výpovědí podle § 52 písm. g) zákoníku práce pro závažné porušení povinnosti vyplývající z právních předpisů vztahujících se k jí vykonávané práci (čili pro závažné porušení pracovní kázně). 

Jejího porušení se dopustila zejména tím, že se dne 21. 1. 2022 se nedostavila do práce na svoji směnu, ačkoliv jí majitel i nadřízený vedoucí pracovník předem výslovně sdělili, že čerpání dovolené na tento den jí „nebylo dovoleno“. V dané době totiž bylo více pracovníků nemocných a za zaměstnankyni nebyla náhrada (čerpací stanice by tak musela být uzavřena a firmě by tím vznikla škoda).

Zaměstnankyně si svévolně vzala dovolenou, ale zajistila za sebe náhradu

Zaměstnankyně se výpovědi bránila soudní cestou, když se domáhala určení neplatnosti výpovědi. Nepolemizovala s tím, že do práce nepřišla, to bylo zřejmé všem. Potvrdila, že se daného dne nedostavila na plánovanou směnu z důvodů, o kterých zaměstnavatele předem informovala.

O dovoleno na 18. 1. 2022 požádala v předstihu s tím, že má za sebe zajištěnou náhradu (kolegyni, která se s ní na pracovišti střídala). Výslovný souhlas s čerpáním dovolené sice nedostala, benzínka však byla v uvedený den otevřená, neboť její obsluhu skutečně kolegyně zajišťovala. 

Soudy měly na přísnost výpovědi odlišný názor

Soud prvního stupně rozhodl, že výpověď je neplatná. Soud shledal, že zaměstnankyně k absenci na pracovišti dne 21. 1. 2022 žádné právem uznané důvody neměla, neboť dobu čerpání dovolené určuje zaměstnavatel způsobem popsaným v § 217 a § 218 zákoníku práce, a není o ní oprávněn rozhodovat sám zaměstnanec. 

Kdy vám dobu dovolené určuje zaměstnavatel a kdy rozhodujete o termínu jen vy? Přečtěte si také:

Kdy vám dobu dovolené určuje zaměstnavatel a kdy rozhodujete o termínu jen vy?

Proto soud rovněž shledal, že k porušení pracovní povinnosti ze strany zaměstnankyně touto absencí ve smyslu § 52 písm. g) zákoníku práce nepochybně došlo. 

Nicméně při posuzování intenzity porušení pracovní kázně spočívající v neomluveném zameškání práce soud prvního stupně zohlednil, že „nevyplynulo, že by v minulosti měla zaměstnankyně nějaké problémy s dodržováním pracovní kázně“. 

Soud také přihlédl k tomu, že předtím „v lednu 2022 odpracovala i směny navíc oproti fondu pracovní doby“. A především k tomu, že v daný den zajistila provoz stanice od 6 hod. do 17 hod. prostřednictvím své spolupracovnice. 

Dále také k tomu, že sice provoz čerpací stanice skončil dříve, než měl, ale v měsíci lednu 2022 byl provoz čerpací stanice oproti běžné provozní době (do 21:30 hod.) stejně ukončován dříve i v jiných případech – „jednalo se zjevně o déletrvající stav způsobený nedostatečným stavem zaměstnanců na provozovně“. 

Soud také vyjádřil pochopení pro důvod absence, který zaměstnankyně vysvětlila, a to pomoc dceři se stěhováním do Švýcarska.

Na tomto základě soud uzavřel, že nelze dovodit, že by „absence byla projevem nějaké mimořádné nezodpovědnosti či zvláště negativního přístupu k plnění jejích pracovních povinností“. Proto zhodnotil, že absence „nedosahuje intenzity závažného porušení povinnosti vztahujících se k vykonávané práci, měla intenzitu pouze méně závažného porušení těchto povinností, a výpovědní důvod dle § 52 písm. g) zákoníku práce tak není dán“.

Odvolací soud potvrdil rozsudek soudu prvního stupně, byl tedy též pro neplatnost výpovědi.

Zaměstnankyně byla vzornou, spolehlivou pracovnicí

Nejvyšší soud ČR v rozsudku ze dne 20. 3. 2025 zhodnotil, že nižší soudy, které projednávaly spor před ním, správně vzaly v úvahu, že „žalobkyně pracovala u zaměstnavatele bez jakýchkoliv problémů po dlouhou dobu 11 let“, že „pracovala v mimořádných směnách a zaskakovala za kolegy“ a „snažila se svému zaměstnavateli vycházet vstříc i nad rámec svých povinností“, jestliže „byla například mimořádně neplánovaně v práci na Nový rok, kdy jí volala vedoucí, že nikdo do práce nepřišel, a dále dne 4. 1. a 11. 1. v souvislosti s inventurami či 13. 1. a 17. 1., kdy zaměstnavatel nařídil mimořádné směny“ (spis. zn. 21 Cdo 816/2024)

Uvedené skutečnosti vypovídají o tom, že žalobkyně byla do doby posuzovaného neomluveného zameškání práce spolehlivou zaměstnankyní, která odpovědně přistupovala k plnění svých pracovních úkolů. Ovšem vyhozené pracovnici to stejně nepomohlo.

Co neměly soudy přičíst zaměstnankyni k dobru

Ve prospěch zaměstnankyně naopak podle názoru NS ČR odvolací soud nesprávně zohlednil, že „v době, kdy o čerpání dovolené žádala, evidovala přesčasy a nevyčerpanou dovolenou z minulého roku“ a že „lze do jisté míry chápat zájem žalobkyně na určitou časovou kontinuitu a celistvost dovolené, když lze stěží smysluplně strávit dovolenou v délce 4 dnů, pokud je zaměstnanec po dvou z těchto dní nucen nastoupit na směnu do práce a následně může čerpat zbývající 2 dny“. 

Až na dvě výjimky rozhoduje o době čerpání dovolené výhradně zaměstnavatel

Soud podle názoru NS ČR nevzal náležitě v úvahu, že dobu čerpání dovolené určuje výhradně zaměstnavatel. Z tohoto pravidla existují dvě výjimky. 

Jedna platí pro situaci, kdy jde o čerpání loňské dovolené, kterou neurčil zaměstnavatel ani do 30. 6. následujícího kalendářního roku. 

Druhá výjimka upravená zákoníkem práce se vztahuje na případy, kdy chce zaměstnankyně čerpat dovolenou bezprostředně v návaznosti na mateřskou dovolenou). Ale ani o jednu z těchto výjimek nešlo.

Jen na okraj vám připomínáme případ zaměstnance, který opravdu měl právo určit si termín (dobu čerpání) dovolené, ale nezvládl to formálně. 

Zaměstnanec si sám rozhodl o čerpání dovolené. Měl na to právo, stejně ale dostal vyhazov na hodinu Přečtěte si také:

Zaměstnanec si sám rozhodl o čerpání dovolené. Měl na to právo, stejně ale dostal vyhazov na hodinu

Zaměstnavatel je povinen přihlížet k zájmům zaměstnance

Zaměstnavatel je sice podle § 217 odst. 1 věty druhé zákoníku práce při svém rozhodování (o tom, kdy bude mít pracovník dovolenou – na kdy mu ji určí nebo schválí, když o ni požádá) povinen přihlížet k oprávněným zájmům zaměstnance. 

Tato povinnost však neznamená, že by zaměstnavatel musel určit čerpání dovolené vždy, kdy o to zaměstnanec požádá, vykládá Nejvyšší soud ČR: Zaměstnavatel je totiž oprávněn zohlednit též provozní důvody (své provozní potřeby).  Právě proto v této souvislosti nelze přehlédnout zjištěný déletrvající nedostatek zaměstnanců na provozovně, kde zaměstnankyně pracovala, který vedl k jejímu uzavření.

Zaměstnavatel řekl výslovně: NE dovolené, zaměstnankyně to proto měla respektovat a dostavit se do práce.

Nejvyšší soud zhodnotil, že při posouzení intenzity porušení pracovní povinnosti soudy nedostatečně zohlednily, že se nemluveného zameškání práce dne 21. 1. 2022 dopustila poté, co nerespektovala zaměstnavatelem opakovaně vyslovený nesouhlas s čerpáním dovolené (vyslovený nejprve nadřízenou a poté i samotným zaměstnavatelem) a i přes jeho vyslovení se neschválené pracovní volno v rozsahu nařízené směny rozhodla čerpat.

Nižší soudy tak náležitě nevzaly v úvahu, že pracovník je podroben řídicí a organizační pravomoci zaměstnavatele, která je nejen výrazem základního definičního znaku závislé práce spočívajícího v nadřízenosti zaměstnavatele a podřízenosti zaměstnance (§ 2 odst. 1 zákoníku práce).

Zaměstnanec musí poslouchat

Zaměstnavatel svoji řídící a organizační pravomoc vykonává jednostranně a pracovník je povinen ji respektovat. Důvěra zaměstnavatele v jeho spolehlivost, schopnost a ochotu podrobit se řídicí a organizační pravomoci zaměstnavatele je tedy ve vztazích mezi nimi nezbytná a bez ní si naplnění pracovněprávního vztahu představit nelze. 

I jeden den absence může stačit k vyhazovu z práce

Neomluvené zameškání práce v rozsahu jedné směny, jehož se zaměstnanec dopustil neoprávněným čerpáním pracovního volna přes zjevný nesouhlas zaměstnavatele (který například odmítl udělit souhlas s čerpáním dovolené nebo pracovního volna bez náhrady mzdy, popř. s výměnou nařízené pracovní směny s jiným zaměstnancem), proto postačuje pro závěr o závažném porušení povinnosti zaměstnance vyplývající z právních předpisů vztahujících se k jím vykonávané práci.

A je hodně silné vyjádření Nejvyššího soudu, když uvážíme, jak se jinak posuzují (nebo posuzovaly) neomluvené absence.

Školení pro účetní - podzimní novinky

Za jak dlouhou neomluvenou absenci dostanete vyhazov na hodinu? Přečtěte si také:

Za jak dlouhou neomluvenou absenci dostanete vyhazov na hodinu?

Nejvyšší soud proto rozhodl, že výpověď je platná (když změnil rozsudek odvolacího soudu tak, že rozsudek soudu prvního stupně se mění a žaloba na určení, že výpověď z pracovního poměru je neplatná, se zamítá).

Nemohu proto než potvrdit tendenci, že Nejvyšší soud v pracovně-právních sporech mezi zaměstnanci a zaměstnavateli vůči zaměstnancům přitvrzuje. Uvidíme, jak se přístup bude vyvíjet dále.

Autor článku

Nenadávejte právníkům, zákony netvoří zdaleka jen oni. Oni je pak jen zašmodrchávají ve prospěch svých klientů, třeba zrovna vás. Budu se však snažit vám je vysvětlovat.

'; 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 »