Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// 首先需要先引入依赖:
// https://github.com/Triggertrap/sun-js
// https://bitbucket.org/pellepim/jstimezonedetect
var accurateDarkMode = true; // accurateDarkMode 用以设置是使用精确模式(需要用户授权)还是使用大概的模式(不用授权)
var DarkModeSwitcher = {
// TimeZone => [lat, lon]
mapTzGeo : {
'America/Denver': [39.7645187, -104.9951977],
'Europe/London': [51.5287352, -0.3817843],
'America/Chicago': [41.8339042, -88.0121562],
'America/Asuncion': [-25.2966809, -57.6681298],
'America/Montevideo': [-34.8207362, -56.3765247],
'Asia/Beirut': [33.8892846, 35.4692627],
'Pacific/Auckland': [-36.8621448, 174.5852782],
'America/Los_Angeles': [34.0207305, -118.6919292],
'America/New_York': [40.6976701, -74.2598739],
'America/Halifax': [43.7085882, -63.475903],
'America/Godthab': [64.1791647, -51.7768494],
'Asia/Dubai': [25.0757073, 54.9475461],
'Asia/Jakarta': [-6.2293867, 106.6894293],
'Asia/Shanghai': [31.2243084, 120.9162622],
'Australia/Sydney': [-33.8473567, 150.6517817],
'Asia/Tokyo': [35.5062896, 138.6484937],
'Asia/Dhaka': [23.7808875, 90.2792377],
'Asia/Baku': [40.3947695, 49.7148734],
'Australia/Brisbane': [-27.3798035, 152.4327106],
'Pacific/Noumea': [-22.2642742, 166.4098471],
'Pacific/Majuro': [7.1045756, 171.3526867],
'Pacific/Tongatapu': [-21.1695566, -175.3350296],
'Asia/Baghdad': [33.3118944, 44.2158179],
'Asia/Karachi': [25.1933895, 66.5949598],
'Africa/Johannesburg': [-26.1713505, 27.9699839],
'default': [39.9390731, 116.1172655] // BeiJing as default
},
// sunset、sunrise 为格式化至当日的 Date 对象
switchColorScheme: function(sunset, sunrise){
var current = new Date();
// 格式化为小时
var sunset_s = sunset.getHours()+sunset.getMinutes()/60;
var sunrise_s = sunrise.getHours()+sunrise.getMinutes()/60;
var current_s = current.getHours()+current.getMinutes()/60;
// 若不存在 cookie,根据时间判断,并设置 cookie
if(document.cookie.replace(/(?:(?:^|.*;\s*)theme_dark\s*=\s*([^;]*).*$)|^.*$/, '$1') === ''){
if(current_s > sunset_s || current_s < sunrise_s){
document.body.classList.add('theme-dark');
if(current_s > sunset_s) // 如果当前为夜晚,日出时间应该切换至第二日
sunrise = new Date(sunrise.getTime() + 3600000*24);
// 现在距日出还有 (s)
var toSunrise = (sunrise.getTime()-current.getTime())/1000;
// 设置 cookie
var cookieString = 'theme_dark=1;max-age='+parseInt(toSunrise)+';path=/';
document.cookie = cookieString;
alert('日落了,夜间模式已开启。');
}else{
document.body.classList.remove('theme-dark');
}
}else{
// 若存在 cookie,根据 cookie 判断
var night = document.cookie.replace(/(?:(?:^|.*;\s*)theme_dark\s*=\s*([^;]*).*$)|^.*$/, '$1') || '0';
if(night == '0'){
document.body.classList.remove('theme-dark');
}else if(night == '1'){
document.body.classList.add('theme-dark');
alert('日落了,夜间模式已开启。');
}
}
},
checkColorSchemeFallback: function(){
var TimeZone = jstz.determine();
TimeZone = TimeZone.name();
if(DarkModeSwitcher.mapTzGeo.hasOwnProperty(TimeZone)) TimeZone = DarkModeSwitcher.mapTzGeo[TimeZone];
else TimeZone = DarkModeSwitcher.mapTzGeo['default'];
sunset = new Date().sunset(TimeZone[0], TimeZone[1]);
sunrise = new Date().sunrise(TimeZone[0], TimeZone[1]);
// 全部转换至当天
sunset = new Date(new Date().setHours(sunset.getHours(), sunset.getMinutes(), 0));
sunrise = new Date(new Date().setHours(sunrise.getHours(), sunrise.getMinutes(), 0));
DarkModeSwitcher.switchColorScheme(sunset, sunrise);
},
checkColorScheme: function(){
if(getPrefersDarkModeState()){
document.body.classList.add('theme-dark');
document.cookie = 'theme_dark=1;max-age=7200;path=/';
alert('已为您开启深色模式。');
} else {
if(!accurateDarkMode){
DarkModeSwitcher.checkColorSchemeFallback();
}else{
if('geolocation' in navigator){
navigator.geolocation.getCurrentPosition(function(position){
sunset = new Date().sunset(position.coords.latitude, position.coords.longitude);
sunrise = new Date().sunrise(position.coords.latitude, position.coords.longitude);
// 全部转换至当天
sunset = new Date(new Date().setHours(sunset.getHours(), sunset.getMinutes(), 0));
sunrise = new Date(new Date().setHours(sunrise.getHours(), sunrise.getMinutes(), 0));
DarkModeSwitcher.checkColorScheme(sunset, sunrise);
}, function(){
DarkModeSwitcher.checkColorSchemeFallback();
});
}else{
DarkModeSwitcher.checkColorSchemeFallback();
}
}
}
}
};
DarkModeSwitcher.checkColorScheme();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.