// Wait for the document to fully load
window.onload = function() {
// Select the video element (if there are multiple videos, target it more precisely)
var video = document.querySelector('video');
// Remove the controls
video.removeAttribute('controls');
// Mute the video
video.muted = true;
// Set the video to loop
video.loop = true;
// Apply rounded corners via CSS
video.style.borderRadius = '15px'; // Adjust the pixel value as needed
// Autoplay the video if desired
video.autoplay = true;
};
这个能用
window.onload = function() {
var video = document.querySelector('video');
video.removeAttribute('controls');
video.muted = true;
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
console.log("Video is now muted and looping, and controls are removed.");
};;
09/23 update
<script>
window.onload = function() {
var videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video) {
// Set attributes and styles for each video
video.removeAttribute('controls');
video.muted = true;
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
// Preload video to reduce delay in starting
video.setAttribute('preload', 'auto');
console.log("Video is now muted and looping, and controls are removed.");
// Listen for the video to be ready to play
video.addEventListener('canplay', function() {
video.play();
});
});
};
</script>
修改为:
<script>
document.addEventListener('DOMContentLoaded', function() {
var videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video) {
// Set attributes and styles for each video
video.removeAttribute('controls');
video.muted = true;
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
// Preload video to reduce delay in starting
video.setAttribute('preload', 'auto');
// Try to immediately play the video
video.play().catch(function(error) {
console.error("Error playing video:", error);
});
console.log("Video is now muted, looping, controls are removed, and autoplay is set.");
});
});
</script>
update: the above doesn;’t load well when route change
function handleRouteChange() {
updateCodeElements();
updateImageSource();
// Find all videos inside elements with class 'notion-video'
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
// Apply video settings
video.muted = true; // Mute the video
video.removeAttribute('controls'); // Remove the controls
video.loop = true; // Set loop to true
video.style.borderRadius = '20px'; // Apply border-radius style
video.autoplay = true; // Ensure video autoplays
video.setAttribute('preload', 'auto'); // Preload the video
console.log("Applying settings to video " + (index + 1));
// Listen for video readiness
video.addEventListener('canplay', function() {
console.log("Video " + (index + 1) + " is ready to play.");
video.play().catch(err => console.error("Error playing video", err));
});
// Error handling for video loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
});
});
// Theme toggle logic
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener
themeToggleButton.addEventListener('click', onThemeChange); // Add new listener
}
}
function setupRouteChangeHandler() {
// Check if the route change handler is available and set it up
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Run the script based on the page load state
if (document.readyState === 'complete' || document.readyState === 'interactive') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
backup
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
function handleRouteChange() {
updateCodeElements();
updateImageSource();
// Find all videos inside elements with class 'notion-video'
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
// Apply video settings
video.muted = true; // Mute the video
video.removeAttribute('controls'); // Remove the controls
video.loop = true; // Set loop to true
video.style.borderRadius = '20px'; // Apply border-radius style
video.autoplay = true; // Ensure video autoplays
video.setAttribute('preload', 'auto'); // Preload the video
console.log("Applying settings to video " + (index + 1));
// Listen for video readiness
video.addEventListener('canplay', function() {
console.log("Video " + (index + 1) + " is ready to play.");
video.play().catch(err => console.error("Error playing video", err));
});
// Error handling for video loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
});
});
// Theme toggle logic
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener
themeToggleButton.addEventListener('click', onThemeChange); // Add new listener
}
}
function setupRouteChangeHandler() {
// Check if the route change handler is available and set it up
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Run the script based on the page load state
if (document.readyState === 'complete' || document.readyState === 'interactive') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
second version(from chagpt)
<script>
// Define your main function that runs on both page load and route changes
function YourFunction() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
}
// Function to update code elements (icons, text trimming)
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
// Function to update image source and apply filter based on theme
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
console.log('Image source successfully set.');
} else {
console.log('Target image not found.');
}
}
// Function to update video settings (muted, autoplay, etc.)
function updateVideoSettings() {
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
video.addEventListener('canplay', function() {
video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
});
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
});
});
}
// Handles theme change logic
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
// Route change handler that calls the main function
const handleRouteChange = () => {
YourFunction(); // Call your main function that updates videos, images, and code elements
};
// Sets up the route change handler to trigger on navigation events
const setupRouteChangeHandler = () => {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange); // Handle route changes
} else {
console.log('window.events.on is not available.');
}
};
// Ensure the script runs on page load and on route changes
if (document.readyState === 'complete') {
handleRouteChange(); // Call your function on initial load if document is already complete
setupRouteChangeHandler(); // Set up route change handling
} else {
window.onload = () => {
handleRouteChange(); // Call your function on initial load when window is loaded
setupRouteChangeHandler(); // Set up route change handling
};
}
</script>
back up
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function updateVideoSettings() {
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
// Set attributes and styles for each video
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
// Ensure video plays when ready
video.addEventListener('canplay', function() {
video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
});
// Error handling for video loading
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
});
});
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
third version from chat gpt
<script>
function YourFunction() {
updateCodeElements(); // Update icons and text content
updateImageSource(); // Update the image source and filter based on the theme
updateVideoSettings(); // Apply video settings like autoplay, mute, and preload
}
// Function to update code elements (icons, text trimming)
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
// Function to update image source and apply filter based on theme
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
// Detect theme and apply corresponding filter
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter applied.');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter removed.');
}
console.log('Image source successfully set.');
} else {
console.log('Target image not found.');
}
}
// Function to update video settings (muted, autoplay, etc.)
function updateVideoSettings() {
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
video.muted = true; // Mute video
video.removeAttribute('controls'); // Remove controls
video.loop = true; // Loop video
video.style.borderRadius = '20px'; // Set border radius
video.autoplay = true; // Autoplay
video.setAttribute('preload', 'auto'); // Preload to reduce delay
console.log(`Video ${index + 1} settings applied: muted, looping, no controls.`);
// Ensure video starts playing when it's ready
video.addEventListener('canplay', function() {
video.play().catch(err => console.error(`Error playing video ${index + 1}:`, err));
});
// Handle video loading errors
video.addEventListener('error', function(event) {
console.error(`Error loading video ${index + 1}:`, event);
});
});
}
// Theme change handler to dynamically update the image source and filter
function onThemeChange() {
updateImageSource();
}
// Route change handler
const handleRouteChange = () => {
YourFunction(); // Call the main function to update everything on route change
listenForThemeToggle(); // Ensure the theme toggle button works properly
};
// Ensure theme toggle works without page refresh
function listenForThemeToggle() {
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Prevent duplicate listeners
themeToggleButton.addEventListener('click', onThemeChange); // Add listener to handle theme change
}
}
// Set up the route change handler and ensure videos are updated accordingly
const setupRouteChangeHandler = () => {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange); // Handle route changes
} else {
console.log('window.events.on is not available.');
}
};
// Ensure the script runs on both initial page load and route changes
if (document.readyState === 'complete') {
handleRouteChange(); // Trigger function on initial load
setupRouteChangeHandler(); // Set up handling for route changes
} else {
window.onload = () => {
handleRouteChange(); // Trigger function when page is fully loaded
setupRouteChangeHandler(); // Set up handling for route changes
};
}
</script>
orginal mistakes:
Hello
The way that Super works is that Scripts are loaded and run once, and not on page navigation to optimize the page speed, but you can trigger this to happen.
Please adapt your script using this:
<script>
function YourFunction() {
// Add your function here as appropriate
};
const handleRouteChange = () => {
YourFunction(); // Call your function(s) as required on route change
};
const setupRouteChangeHandler = () => {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
};
// Check if document is already loaded
if (document.readyState === 'complete') {
handleRouteChange(); // Call your function on initial load if document is already complete
setupRouteChangeHandler(); // Set up route change handling
} else {
window.onload = () => {
handleRouteChange(); // Call your function on initial load when window is loaded
setupRouteChangeHandler(); // Set up route change handling
};
}
</script>
如果document is read,那么handleroutechange,并且setup handler (文档的所有内容已经加载完成,包括dom和外部资源,检测到已经完成后,执行操作)
如果window正在loading,那么handleroutechange,并且setuproutechange handeler (页面正在加载时,脚本监听window onload,加载时也可以执行代码)
window.onload只有在页面全部加载完时才能触发
try to edit:
function applyVideoSettings(video) {
// Remove controls, mute the video, and set it to loop
video.removeAttribute('controls');
video.muted = true;
video.loop = true;
video.style.borderRadius = '20px'; // Apply corner radius
video.autoplay = true; // Autoplay
video.setAttribute('preload', 'auto'); // Preload video
console.log("Applied video settings: muted, looping, controls removed, and autoplay.");
// Ensure video plays when ready
video.addEventListener('canplay', function() {
video.play().catch(err => console.error("Error playing video: ", err));
});
// Error handling for video loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video: ", event);
});
}
function handleRouteChange() {
// Get all video elements
const videos = document.querySelectorAll('.notion-video video');
// Apply video settings for each video
videos.forEach(function(video) {
applyVideoSettings(video);
});
console.log("Route change handled and video settings applied.");
}
// Set up route change handling, which triggers on every route change
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure it runs on page load as well
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
<script>
document.addEventListener('DOMContentLoaded', function() {
var videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video) {
// Ensure video preloading and play behavior
video.setAttribute('preload', 'auto');
// Try to play the video when it's ready
video.addEventListener('canplay', function() {
video.play().catch(function(err) {
console.error("Error playing video: ", err);
});
});
// Handle video loading errors
video.addEventListener('error', function(event) {
console.error("Error loading video: ", event);
});
console.log("Video settings applied and play attempted on subpage.");
});
});
</script>
<script>
// Function to apply video settings (muting, looping, etc.)
function applyVideoSettings(video) {
video.removeAttribute('controls'); // Remove controls
video.muted = true; // Mute video
video.loop = true; // Loop video
video.style.borderRadius = '20px'; // Apply corner radius
video.autoplay = true; // Set to autoplay
video.setAttribute('preload', 'auto'); // Preload video
// Ensure video plays when ready
video.addEventListener('canplay', function() {
video.play().catch(err => console.error("Error playing video:", err));
});
// Error handling for video loading
video.addEventListener('error', function(event) {
console.error("Error loading video:", event);
});
}
// Update code elements (for example, add icons or adjust styles)
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
// Update image source based on the current theme
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter applied.');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter removed.');
}
console.log('Image source successfully set.');
} else {
console.log('Target image not found.');
}
}
// Handle theme toggle change
function onThemeChange() {
updateImageSource();
}
// Handle route change and call the necessary functions
const handleRouteChange = () => {
// Update code elements and image sources
updateCodeElements();
updateImageSource();
// Apply video settings for each video
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video) {
applyVideoSettings(video);
});
// Handle the theme toggle button event listener
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange); // Add new listener
}
console.log("Route change handled and all updates applied.");
};
// Setup route change handler
const setupRouteChangeHandler = () => {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
};
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange(); // Call the function on initial load
setupRouteChangeHandler(); // Set up route change handling
} else {
window.onload = () => {
handleRouteChange(); // Call the function on initial load when the window is loaded
setupRouteChangeHandler(); // Set up route change handling
};
}
</script>
在subpage写的办法不好用,只能去主page
window.onload = function() {
var videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video) {
// Set attributes and styles for each video
video.removeAttribute('controls');
video.muted = true;
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
// Preload video to reduce delay in starting
video.setAttribute('preload', 'auto');
console.log("Video is now muted and looping, and controls are removed.");
// Listen for the video to be ready to play
video.addEventListener('canplay', function() {
video.play();
});
});
};
目前能用的代码备份
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
又改了,重新troubleshooting,这一次的backup
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function updateVideoSettings() {
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.autoplay = true;
video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
video.addEventListener('canplay', function() {
video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
});
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
});
});
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
最后能用的版本!!!(全部备份)
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function updateVideoSettings() {
const videos = document.querySelectorAll('.notion-video video');
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
// Force video to load its resource
video.load();
// Function to handle video play with fallback
function tryPlayVideo() {
video.play().then(() => {
console.log("Video " + (index + 1) + " is playing.");
}).catch(err => {
console.error("Error playing video " + (index + 1) + ": ", err);
});
}
// Add canplay and canplaythrough listeners
video.addEventListener('canplay', function() {
console.log("canplay event fired for video " + (index + 1));
tryPlayVideo(); // Try playing when canplay is fired
});
video.addEventListener('canplaythrough', function() {
console.log("canplaythrough event fired for video " + (index + 1));
tryPlayVideo(); // Try playing when canplaythrough is fired
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
// Check the video's source to see if it's correctly set
console.log("Video " + (index + 1) + " source: ", video.src);
});
// Try playing immediately after DOMContentLoaded
document.addEventListener('DOMContentLoaded', function() {
console.log("DOM fully loaded, trying to play video " + (index + 1));
tryPlayVideo();
});
});
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
add avoide fullscreen plaing functions
another code to limit maxplaying videos:
function updateVideoSettings(maxPlayingVideos = 1) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
// Event listener for when a video starts playing
video.addEventListener('play', function() {
// Add the current video to the list of playing videos
currentlyPlaying.push(video);
// If the number of playing videos exceeds the limit, pause the oldest one
if (currentlyPlaying.length > maxPlayingVideos) {
let videoToPause = currentlyPlaying.shift(); // Remove and get the oldest video
videoToPause.pause();
console.log("Paused a video to maintain limit.");
}
});
// Event listener for when a video is paused
video.addEventListener('pause', function() {
// Remove the paused video from the currently playing list
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
});
// Force video to load its resource
video.load();
});
}
新的备份: with safari优化与视频自动暂停
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
// Check if the video is not already playing
if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play();
currentlyPlaying.push(video);
console.log("Playing video.");
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
video.pause();
console.log("Paused video because it left the viewport.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
});
}, {
threshold: 0.5 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
// Observe each video to detect when it enters/leaves the viewport
observer.observe(video);
// Force video to load its resource
video.load();
// Function to handle video play with fallback
function tryPlayVideo() {
video.play().then(() => {
console.log("Video " + (index + 1) + " is playing.");
}).catch(err => {
console.error("Error playing video " + (index + 1) + ": ", err);
});
}
// Add canplay and canplaythrough listeners
video.addEventListener('canplay', function() {
console.log("canplay event fired for video " + (index + 1));
tryPlayVideo(); // Try playing when canplay is fired
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
// Check the video's source to see if it's correctly set
console.log("Video " + (index + 1) + " source: ", video.src);
});
});
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
新的控制video开始播放地办法:
function updateVideoSettings(maxPlayingVideos = 1) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
// Start playing the video only when it's visible
if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play(); // Start playing the video
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
// Optional: Remove the observer after the video starts playing if you don't want to track it further
observer.unobserve(video);
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
video.pause();
console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
});
}, {
threshold: 0.5 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Start preloading the video on page load
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " is preloading but will not autoplay until it enters the viewport.");
// Observe each video to detect when it enters/leaves the viewport
observer.observe(video);
});
}
preload error:
function updateVideoSettings(maxPlayingVideos = 2) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Create an Intersection Observer to detect when a video is about to enter the viewport (starts preloading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// Start preloading when the video is about to enter the viewport (50% visible)
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto'); // Start preloading the video
console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is fully in the viewport
if (entry.isIntersecting) {
// Start playing the video only when it's fully visible
if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play(); // Start playing the video
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
// Optional: Remove the observer after the video starts playing if you don't want to track it further
playObserver.unobserve(video);
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
video.pause();
console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
});
}, {
threshold: 0.5 // Only play the video when at least 50% is visible
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");
// Observe each video to detect when it's approaching the viewport (for preloading)
preloadObserver.observe(video);
// Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
playObserver.observe(video);
});
}
function updateVideoSettings(maxPlayingVideos = 2) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// Start preloading when the video is about to enter the viewport (50% visible)
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto'); // Start preloading the video
console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
// Start playing the video only when it's visible
if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play(); // Start playing the video
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
// Optional: Remove the observer after the video starts playing if you don't want to track it further
playObserver.unobserve(video);
}
} else {
// When the video leaves the viewport, we don't pause it to allow it to keep loading
console.log("Video " + (Array.from(videos).indexOf(video) + 1) + " is still loading even though it left the viewport.");
// Remove it from currently playing but allow it to keep buffering or loading in the background
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
});
}, {
threshold: 0.5 // Only play the video when at least 50% is visible
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");
// Observe each video to detect when it's approaching the viewport (for preloading)
preloadObserver.observe(video);
// Observe each video to detect when it fully enters/leaves the viewport (for playing)
playObserver.observe(video);
});
}
新的办法也可以有用,但是video就不暂停了
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function updateVideoSettings(maxPlayingVideos = 2) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// Start preloading when the video is about to enter the viewport (50% visible)
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto'); // Start preloading the video
console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
// Start playing the video only when it's visible
if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play(); // Start playing the video
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
// Optional: Remove the observer after the video starts playing if you don't want to track it further
playObserver.unobserve(video);
}
} else {
// When the video leaves the viewport, we don't pause it to allow it to keep loading
console.log("Video " + (Array.from(videos).indexOf(video) + 1) + " is still loading even though it left the viewport.");
// Remove it from currently playing but allow it to keep buffering or loading in the background
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
});
}, {
threshold: 0.5 // Only play the video when at least 50% is visible
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");
// Observe each video to detect when it's approaching the viewport (for preloading)
preloadObserver.observe(video);
// Observe each video to detect when it fully enters/leaves the viewport (for playing)
playObserver.observe(video);
// Function to handle video play with fallback
function tryPlayVideo() {
video.play().then(() => {
console.log("Video " + (index + 1) + " is playing.");
}).catch(err => {
console.error("Error playing video " + (index + 1) + ": ", err);
});
}
// Add canplay and canplaythrough listeners
video.addEventListener('canplay', function() {
console.log("canplay event fired for video " + (index + 1));
tryPlayVideo(); // Try playing when canplay is fired
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
// Check the video's source to see if it's correctly set
console.log("Video " + (index + 1) + " source: ", video.src);
});
});
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
加上暂停
function updateVideoSettings(maxPlayingVideos = 2) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
// Track videos that have finished loading
const fullyLoadedVideos = new Set();
// Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// Start preloading when the video is about to enter the viewport (50% visible)
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto'); // Start preloading the video
console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
// Start playing the video only if it's fully loaded and visible
if (fullyLoadedVideos.has(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play(); // Start playing the video
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
}
} else {
// Pause the video only if it has finished loading
if (fullyLoadedVideos.has(video) && !video.paused) {
video.pause();
console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport after loading.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
});
}, {
threshold: 0.5 // Only play/pause the video when at least 50% is visible
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");
// Listen for the 'canplaythrough' event, which indicates the video has finished loading
video.addEventListener('canplaythrough', function() {
fullyLoadedVideos.add(video); // Mark the video as fully loaded
console.log("Video " + (index + 1) + " has finished loading.");
});
// Observe each video to detect when it's approaching the viewport (for preloading)
preloadObserver.observe(video);
// Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
playObserver.observe(video);
});
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
const fullyLoadedVideos = new Set();
// Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto');
console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting) {
if (fullyLoadedVideos.has(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play();
currentlyPlaying.push(video);
console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
}
} else {
if (fullyLoadedVideos.has(video) && !video.paused) {
video.pause();
console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport after loading.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
});
}, {
threshold: 0.1 // Lower threshold to play when 10% is visible
});
videos.forEach(function(video, index) {
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
// Listen for the 'canplay' event (fired earlier than 'canplaythrough')
video.addEventListener('canplay', function() {
fullyLoadedVideos.add(video);
console.log("Video " + (index + 1) + " is ready to play.");
});
preloadObserver.observe(video);
playObserver.observe(video);
});
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
const fullyLoadedVideos = new Set();
// Helper function to check if the video is in the viewport
function isInViewport(video) {
const rect = video.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// Function to play the video if it is in the viewport and fully loaded
function attemptPlay(video, index) {
if (isInViewport(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play();
currentlyPlaying.push(video);
console.log(`Playing video ${index + 1} because it is in the viewport and fully loaded.`);
}
}
// Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
const preloadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
video.setAttribute('preload', 'auto');
console.log(`Preloading video ${Array.from(videos).indexOf(video) + 1} as it approaches the viewport.`);
preloadObserver.unobserve(video); // No need to keep observing for preload
}
});
}, {
threshold: 0.1 // Start preloading when 10% of the video is visible
});
// Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
const playObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
const index = Array.from(videos).indexOf(video); // Get the index of the video
if (entry.isIntersecting) {
console.log(`Video ${index + 1} entered the viewport.`);
// Try to play the video if it's fully loaded
attemptPlay(video, index);
} else {
if (!video.paused && fullyLoadedVideos.has(video)) {
video.pause();
console.log(`Paused video ${index + 1} because it left the viewport after loading.`);
const currentlyPlayingIndex = currentlyPlaying.indexOf(video);
if (currentlyPlayingIndex > -1) {
currentlyPlaying.splice(currentlyPlayingIndex, 1);
}
}
}
});
}, {
threshold: 0.1 // Lower threshold to play when 10% is visible
});
videos.forEach(function(video, index) {
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
// Troubleshooting for 'canplaythrough' event and auto-play when fully loaded and in viewport
video.addEventListener('canplaythrough', function() {
fullyLoadedVideos.add(video);
console.log(`canplaythrough event fired for video ${index + 1}. Video is fully buffered and ready to play.`);
// Try to play the video as soon as it finishes buffering if it's in the viewport
attemptPlay(video, index);
});
// Observe each video to detect when it's approaching the viewport (for preloading)
preloadObserver.observe(video);
// Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
playObserver.observe(video);
});
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
const fullyLoadedVideos = new Set(); // Videos that have fired canplay
const partiallyLoadedVideos = new Set(); // Videos that are still loading
// Helper function to check if the video is in the viewport
function isInViewport(video) {
const rect = video.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// Function to play the video if it is in the viewport and fully loaded
function attemptPlay(video, index) {
if (isInViewport(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
video.play();
currentlyPlaying.push(video);
console.log(`Playing video ${index + 1} because it is in the viewport and fully loaded.`);
}
}
// Intersection Observer to detect when the video is about to enter the viewport
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
const video = entry.target;
const index = Array.from(videos).indexOf(video);
// If the video is about to enter the viewport (e.g., 50% visible)
if (entry.isIntersecting) {
console.log(`Video ${index + 1} is about to enter the viewport.`);
// If the video is fully loaded, try to play it
if (fullyLoadedVideos.has(video)) {
attemptPlay(video, index);
} else if (!fullyLoadedVideos.has(video)) {
// If the video isn't fully loaded, keep loading and remove observer
partiallyLoadedVideos.add(video);
console.log(`Video ${index + 1} is still loading, keeping it in memory to load.`);
}
} else {
// When the video is out of the viewport, stop observing but allow it to keep loading
if (!fullyLoadedVideos.has(video)) {
// If video is not fully loaded, allow it to keep loading but stop observing
observer.unobserve(video);
console.log(`Stopped observing video ${index + 1}, it is out of the viewport but will keep loading.`);
} else if (fullyLoadedVideos.has(video)) {
// Pause the video if it was playing and is fully loaded
if (!video.paused) {
video.pause();
console.log(`Paused video ${index + 1} because it left the viewport.`);
const currentlyPlayingIndex = currentlyPlaying.indexOf(video);
if (currentlyPlayingIndex > -1) {
currentlyPlaying.splice(currentlyPlayingIndex, 1);
}
}
}
}
});
}, {
threshold: 0.5 // Detect when 50% of the video is visible (about to enter viewport)
});
// Iterate over all videos and apply event listeners
videos.forEach(function(video, index) {
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'none'); // Delay preloading until it's in the viewport
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
// Event listener for 'canplay' event (fired when enough data is buffered to start)
video.addEventListener('canplay', function() {
fullyLoadedVideos.add(video);
console.log(`canplay event fired for video ${index + 1}. Video is ready to play.`);
attemptPlay(video, index); // Attempt to play immediately if it is ready and in the viewport
});
// Use the observer to detect when the video is about to enter the viewport
observer.observe(video);
});
}
新的尝试 新的logic看看能不能用
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false; // Flag to track the first video play
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
// If the video is in the viewport
if (entry.isIntersecting) {
if (video.readyState >= 3) { // If the video has enough data to play
playVideo(video);
} else {
console.log("Video " + video.src + " has not finished loading but is in the viewport.");
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
pauseVideo(video, false);
console.log("Paused video " + video.src + " because it left the viewport.");
}
}
});
}, {
threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " is set up for autoplay, muted, and looped.");
// If it's the first video, play it immediately after preloading
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video);
console.log("First video " + video.src + " is playing immediately after preloading.");
firstVideoPlayed = true;
});
} else {
// For other videos, observe when they enter/leave the viewport
observer.observe(video);
video.load(); // Preload the video when the page is loaded
}
// Play video logic
function playVideo(video) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log("Video " + video.src + " is playing.");
currentlyPlaying.push(video);
}).catch(err => {
console.error("Error playing video " + video.src + ": ", err);
// Allow user to manually play the video if it failed to autoplay
video.addEventListener('click', () => {
toggleVideoPlayPause(video);
});
});
}
}
// Pause video logic, with manual flag to track if paused by user
function pauseVideo(video, userPaused) {
if (!video.paused) {
video.pause();
console.log("Video " + video.src + " is paused.");
if (userPaused) {
console.log("Video " + video.src + " was paused by the user.");
}
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
// Toggle play/pause for manual control
function toggleVideoPlayPause(video) {
if (video.paused) {
playVideo(video);
} else {
pauseVideo(video, true);
}
}
// Video loaded event
video.addEventListener('canplaythrough', function() {
console.log("Video " + (index + 1) + " has fully loaded and is ready for playback.");
});
// Looping video, video will restart automatically after finishing
video.addEventListener('ended', function() {
console.log("Video " + (index + 1) + " finished playing and will loop.");
playVideo(video); // Automatically play the video again as it is looped
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
// Check the video's source to see if it's correctly set
console.log("Video " + (index + 1) + " source: ", video.src);
});
// Allow user to manually control play/pause by clicking on the video
video.addEventListener('click', function() {
toggleVideoPlayPause(video);
});
});
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${video.src} intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
// If the video is in the viewport
if (entry.isIntersecting) {
if (video.readyState >= 3) { // If the video has enough data to play
playVideo(video);
} else {
console.log("Video " + video.src + " is in the viewport but has not finished loading.");
// Add canplay event listener in case it finishes loading
video.addEventListener('canplay', () => {
console.log("Video " + video.src + " has finished loading in the viewport, starting playback.");
playVideo(video);
});
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
pauseVideo(video);
console.log("Paused video " + video.src + " because it left the viewport.");
}
}
});
}, {
threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log("Video " + (index + 1) + " is set up for autoplay, muted, and looped.");
// If it's the first video, play it immediately after preloading
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video);
console.log("First video " + video.src + " is playing immediately after preloading.");
firstVideoPlayed = true;
});
} else {
// For other videos, observe when they enter/leave the viewport
console.log("Observing video " + (index + 1) + " for intersection changes.");
observer.observe(video); // Start observing the video
video.load(); // Preload the video when the page is loaded
}
// Allow user to manually control play/pause by clicking on the video
video.addEventListener('click', function() {
toggleVideoPlayPause(video);
});
// Video loaded event
video.addEventListener('canplaythrough', function() {
console.log("Video " + (index + 1) + " has fully loaded and is ready for playback.");
});
// Looping video, video will restart automatically after finishing
video.addEventListener('ended', function() {
console.log("Video " + (index + 1) + " finished playing and will loop.");
playVideo(video); // Automatically play the video again as it is looped
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error("Error loading video " + (index + 1), event);
console.log("Video " + (index + 1) + " source: ", video.src);
});
});
// Play video logic
function playVideo(video) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log("Video " + video.src + " is playing.");
currentlyPlaying.push(video);
}).catch(err => {
console.error("Error playing video " + video.src + ": ", err);
});
}
}
// Pause video logic
function pauseVideo(video) {
if (!video.paused) {
video.pause();
console.log("Video " + video.src + " is paused.");
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
// Toggle play/pause for manual control
function toggleVideoPlayPause(video) {
if (video.paused) {
playVideo(video);
} else {
pauseVideo(video);
}
}
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index; // Use data attribute to get the video index
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
// If the video is in the viewport
if (entry.isIntersecting) {
if (video.readyState >= 3) { // If the video has enough data to play
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
// Add canplay event listener in case it finishes loading
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
});
}
} else {
// If the video leaves the viewport, pause it
\
这个版本能用,除了暂停有点奇怪
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index; // Use data attribute to get the video index
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
// If the video is in the viewport
if (entry.isIntersecting) {
if (video.readyState >= 3) { // If the video has enough data to play
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
// Add canplay event listener in case it finishes loading
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
});
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set a data attribute for the video index
video.dataset.index = index + 1;
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
// If it's the first video, play it immediately after preloading
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
});
} else {
// For other videos, observe when they enter/leave the viewport
console.log(`Observing video ${index + 1} for intersection changes.`);
observer.observe(video); // Start observing the video
video.load(); // Preload the video when the page is loaded
}
// Allow user to manually control play/pause by clicking on the video
video.addEventListener('click', function() {
toggleVideoPlayPause(video, index + 1);
});
// Video loaded event
video.addEventListener('canplaythrough', function() {
console.log(`Video ${index + 1} (src: ${video.src}) has fully loaded and is ready for playback.`);
});
// Looping video, video will restart automatically after finishing
video.addEventListener('ended', function() {
console.log(`Video ${index + 1} (src: ${video.src}) finished playing and will loop.`);
playVideo(video, index + 1); // Automatically play the video again as it is looped
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error(`Error loading video ${index + 1} (src: ${video.src}): `, event);
});
});
// Play video logic
function playVideo(video, videoIndex) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
currentlyPlaying.push(video);
}).catch(err => {
console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
});
}
}
// Pause video logic
function pauseVideo(video, videoIndex) {
if (!video.paused) {
video.pause();
console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
// Toggle play/pause for manual control
function toggleVideoPlayPause(video, videoIndex) {
if (video.paused) {
playVideo(video, videoIndex);
} else {
pauseVideo(video, videoIndex);
}
}
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
function handleRouteChange() {
updateCodeElements();
updateImageSource();
updateVideoSettings();
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// Create an Intersection Observer to detect when a video enters/exits the viewport
const observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index; // Use data attribute to get the video index
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
// If the video is in the viewport
if (entry.isIntersecting) {
if (video.readyState >= 3) { // If the video has enough data to play
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
// Add canplay event listener in case it finishes loading
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
});
}
} else {
// If the video leaves the viewport, pause it
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
});
videos.forEach(function(video, index) {
// Set a data attribute for the video index
video.dataset.index = index + 1;
// Set video attributes
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
// If it's the first video, play it immediately after preloading
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
});
} else {
// For other videos, observe when they enter/leave the viewport
console.log(`Observing video ${index + 1} for intersection changes.`);
observer.observe(video); // Start observing the video
video.load(); // Preload the video when the page is loaded
}
// Allow user to manually control play/pause by clicking on the video
video.addEventListener('click', function() {
toggleVideoPlayPause(video, index + 1);
});
// Video loaded event
video.addEventListener('canplaythrough', function() {
console.log(`Video ${index + 1} (src: ${video.src}) has fully loaded and is ready for playback.`);
});
// Looping video, video will restart automatically after finishing
video.addEventListener('ended', function() {
console.log(`Video ${index + 1} (src: ${video.src}) finished playing and will loop.`);
playVideo(video, index + 1); // Automatically play the video again as it is looped
});
// Enhanced error handling for loading issues
video.addEventListener('error', function(event) {
console.error(`Error loading video ${index + 1} (src: ${video.src}): `, event);
});
});
// Play video logic
function playVideo(video, videoIndex) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
currentlyPlaying.push(video);
}).catch(err => {
console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
});
}
}
// Pause video logic
function pauseVideo(video, videoIndex) {
if (!video.paused) {
video.pause();
console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
// Toggle play/pause for manual control
function toggleVideoPlayPause(video, videoIndex) {
if (video.paused) {
playVideo(video, videoIndex);
} else {
pauseVideo(video, videoIndex);
}
}
}
// Call the function to set up the videos
if (document.readyState === 'complete') {
updateVideoSettings();
} else {
window.addEventListener('load', function() {
updateVideoSettings();
});
}
let observer; // Define the observer globally to manage its lifecycle
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// If there's an existing observer, disconnect it to prevent duplication
if (observer) {
console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
observer.disconnect();
}
// Create a new Intersection Observer
observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index;
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
if (entry.isIntersecting) {
if (video.readyState >= 3) {
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
}, { once: true }); // Ensure the listener is only added once
}
} else {
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1
});
videos.forEach(function(video, index) {
video.dataset.index = index + 1;
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto');
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
});
} else {
observer.observe(video);
video.load();
}
// Log whenever a click event listener is added
console.log(`Attaching click event listener to video ${index + 1}`);
// Remove any existing click listeners before adding new ones to avoid duplication
video.removeEventListener('click', () => toggleVideoPlayPause(video, index + 1));
// Add click listener to toggle play/pause
video.addEventListener('click', () => {
console.log(`Click event triggered for video ${index + 1}`);
toggleVideoPlayPause(video, index + 1);
});
});
function playVideo(video, videoIndex) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
currentlyPlaying.push(video);
}).catch(err => {
console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
});
}
}
function pauseVideo(video, videoIndex) {
if (!video.paused) {
video.pause();
console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
function toggleVideoPlayPause(video, videoIndex) {
if (video.paused) {
playVideo(video, videoIndex);
} else {
pauseVideo(video, videoIndex);
}
}
}
function handleRouteChange() {
console.log('Route change detected, updating elements and listeners.');
updateCodeElements(); // Assuming this updates code elements
updateImageSource(); // Assuming this updates image sources
updateVideoSettings(); // Updating video settings and listeners
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
console.log('Attaching theme change event listener to the toggle button.');
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
console.log('Listening for route changes using window.events.on.');
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
console.log('Document is fully loaded.');
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
console.log('Window onload event fired.');
handleRouteChange();
setupRouteChangeHandler();
};
}
备份! 又好了
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
let observer; // Define the observer globally to manage its lifecycle
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let currentlyPlaying = [];
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// If there's an existing observer, disconnect it to prevent duplication
if (observer) {
console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
observer.disconnect();
}
// Create a new Intersection Observer
observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index;
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
if (entry.isIntersecting) {
if (video.readyState >= 3) {
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
}, { once: true }); // Ensure the listener is only added once
}
} else {
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1
});
videos.forEach(function(video, index) {
video.dataset.index = index + 1;
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto');
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
});
} else {
observer.observe(video);
video.load();
}
// Log whenever a click event listener is added
console.log(`Attaching click event listener to video ${index + 1}`);
// Remove any existing click listeners before adding new ones to avoid duplication
video.removeEventListener('click', () => toggleVideoPlayPause(video, index + 1));
// Add click listener to toggle play/pause
video.addEventListener('click', () => {
console.log(`Click event triggered for video ${index + 1}`);
toggleVideoPlayPause(video, index + 1);
});
});
function playVideo(video, videoIndex) {
if (!currentlyPlaying.includes(video)) {
video.play().then(() => {
console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
currentlyPlaying.push(video);
}).catch(err => {
console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
});
}
}
function pauseVideo(video, videoIndex) {
if (!video.paused) {
video.pause();
console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1);
}
}
}
function toggleVideoPlayPause(video, videoIndex) {
if (video.paused) {
playVideo(video, videoIndex);
} else {
pauseVideo(video, videoIndex);
}
}
}
function handleRouteChange() {
console.log('Route change detected, updating elements and listeners.');
updateCodeElements(); // Assuming this updates code elements
updateImageSource(); // Assuming this updates image sources
updateVideoSettings(); // Updating video settings and listeners
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
console.log('Attaching theme change event listener to the toggle button.');
themeToggleButton.addEventListener('click', onThemeChange);
}
}
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
console.log('Listening for route changes using window.events.on.');
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
console.log('Document is fully loaded.');
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
console.log('Window onload event fired.');
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>
尝试地优化
let observer; // Define the observer globally to manage its lifecycle
let currentlyPlaying = [];
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// If there's an existing observer, disconnect it to prevent duplication
if (observer) {
console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
observer.disconnect();
}
// Create a new Intersection Observer
observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index;
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
if (entry.isIntersecting) {
if (video.readyState >= 3) {
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
}, { once: true }); // Ensure the listener is only added once
}
} else {
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1
});
videos.forEach(function (video, index) {
video.dataset.index = index + 1;
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto');
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
}, { once: true });
} else {
observer.observe(video); // Start observing the video
video.load();
}
// Manage click event listener to toggle play/pause
manageEventListener(video, index);
});
}
// Function to manage click event listeners on videos
function manageEventListener(video, index) {
const listener = () => {
console.log(`Click event triggered for video ${index + 1}`);
toggleVideoPlayPause(video, index + 1);
备份!
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<script>
function updateCodeElements() {
const codeElements = document.querySelectorAll('.code');
codeElements.forEach(el => {
el.classList.add('material-symbols-outlined');
el.classList.add('icon-color');
el.textContent = el.textContent.trim();
console.log("Updated element:", el, "with icon:", el.textContent);
});
}
function updateImageSource() {
const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";
if (targetImage) {
targetImage.src = imageSrc;
if (document.documentElement.classList.contains('theme-dark')) {
targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
} else if (document.documentElement.classList.contains('theme-light')) {
targetImage.style.filter = 'none';
console.log('Theme is light. Image filter set to: none');
}
if (targetImage.src === imageSrc) {
console.log('Image source successfully set.');
} else {
console.log('Failed to set image source.');
}
} else {
console.log('Target image not found.');
}
}
function onThemeChange() {
setTimeout(updateImageSource, 0);
}
let observer; // Define the observer globally to manage its lifecycle
let currentlyPlaying = [];
function updateVideoSettings(maxPlayingVideos = 3) {
const videos = document.querySelectorAll('.notion-video video');
let firstVideoPlayed = false;
console.log("Initializing IntersectionObserver...");
// If there's an existing observer, disconnect it to prevent duplication
if (observer) {
console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
observer.disconnect();
}
// Create a new Intersection Observer
observer = new IntersectionObserver((entries) => {
console.log("Observer callback triggered. Checking entries...");
entries.forEach(entry => {
const video = entry.target;
const videoIndex = video.dataset.index;
// Log the intersection ratio and whether the video is intersecting
console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
if (entry.isIntersecting) {
if (video.readyState >= 3) {
playVideo(video, videoIndex);
} else {
console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
video.addEventListener('canplay', () => {
console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
playVideo(video, videoIndex);
}, { once: true }); // Ensure the listener is only added once
}
} else {
if (!video.paused) {
pauseVideo(video, videoIndex);
console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
}
}
});
}, {
threshold: 0.1
});
videos.forEach(function (video, index) {
video.dataset.index = index + 1;
video.muted = true;
video.removeAttribute('controls');
video.loop = true;
video.style.borderRadius = '20px';
video.setAttribute('preload', 'auto');
video.setAttribute('playsinline', 'true');
video.setAttribute('webkit-playsinline', 'true');
console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);
if (index === 0 && !firstVideoPlayed) {
video.load();
video.addEventListener('canplay', () => {
playVideo(video, index + 1);
console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
firstVideoPlayed = true;
}, { once: true });
} else {
observer.observe(video); // Start observing the video
video.load();
}
// Manage click event listener to toggle play/pause
manageEventListener(video, index);
});
}
// Function to manage click event listeners on videos
function manageEventListener(video, index) {
const listener = () => {
console.log(`Click event triggered for video ${index + 1}`);
toggleVideoPlayPause(video, index + 1);
};
// Remove any existing click listener to prevent duplication
video.removeEventListener('click', listener);
// Add the click event listener
video.addEventListener('click', listener);
console.log(`Attached click event listener to video ${index + 1}`);
}
// Play video logic
function playVideo(video, videoIndex) {
if (currentlyPlaying.length < 3 && !currentlyPlaying.includes(video)) { // Limit the number of videos playing simultaneously
video.play().then(() => {
console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
currentlyPlaying.push(video);
}).catch(err => {
console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
});
}
}
// Pause video logic
function pauseVideo(video, videoIndex) {
if (!video.paused) {
video.pause();
console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
const index = currentlyPlaying.indexOf(video);
if (index > -1) {
currentlyPlaying.splice(index, 1); // Remove video from currently playing list
}
}
}
// Toggle play/pause for manual control
function toggleVideoPlayPause(video, videoIndex) {
if (video.paused) {
playVideo(video, videoIndex);
} else {
pauseVideo(video, videoIndex);
}
}
// Function to clean up event listeners and observers when navigating away or rerunning the script
function cleanupEventListeners(videos) {
videos.forEach(video => {
// Remove any click event listeners
video.removeEventListener('click', toggleVideoPlayPause);
console.log(`Removed event listeners for video ${video.dataset.index}`);
});
}
// Function to handle route changes
function handleRouteChange() {
console.log('Route change detected, updating elements and listeners.');
updateCodeElements(); // Assuming this updates code elements
updateImageSource(); // Assuming this updates image sources
updateVideoSettings(); // Updating video settings and listeners
const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
if (themeToggleButton) {
themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
console.log('Attaching theme change event listener to the toggle button.');
themeToggleButton.addEventListener('click', onThemeChange);
}
}
// Set up route change handler and initialize observers/listeners
function setupRouteChangeHandler() {
if (window.events && window.events.on) {
console.log('Listening for route changes using window.events.on.');
window.events.on('routeChangeComplete', handleRouteChange);
} else {
console.log('window.events.on is not available.');
}
}
// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
console.log('Document is fully loaded.');
handleRouteChange();
setupRouteChangeHandler();
} else {
window.onload = () => {
console.log('Window onload event fired.');
handleRouteChange();
setupRouteChangeHandler();
};
}
</script>