Beginnen Sie Ihre grenzüberschreitende Reise
Kontaktieren Sie uns jetzt

Kundendienst für die Entwicklung von Websites

Kundenbetreuung

Mit den benutzerdefinierten Pinnwänden von WordPress können Sie mehrere Pinnwände so anpassen, dass sie sich automatisch drehen und einen Countdown-Timer einstellen, der dann in der Backend-Menünavigation hinzugefügt werden kann.
add_action('init', function() {
register_post_type('announcement_bar', [
'labels' => [
'name' => '公告栏',
'add_new_item' => '添加新公告',
'edit_item' => '编辑公告',
],
'public' => false,
'show_ui' => true,
'menu_icon' => 'dashicons-megaphone',
'supports' => ['title', 'page-attributes'],
]);
});
add_action('add_meta_boxes', function() {
add_meta_box('announcement_fields', '公告设置', function($post) {
$meta = get_post_meta($post->ID);
$val = function($key, $default = '') use ($meta) {
return isset($meta[$key][0]) ? esc_attr($meta[$key][0]) : $default;
};
?>
<p><label>链接地址:<input type="url" name="link" value="<?php echo $val('link'); ?>" style="width:100%"></label></p>
<p><label><input type="checkbox" name="enable_timer" value="1" <?php checked($val('enable_timer'), '1'); ?>> 启用倒计时</label></p>
<p><label>倒计时目标时间:<input type="datetime-local" name="timer_end" value="<?php echo $val('timer_end'); ?>"></label></p>
<?php
}, 'announcement_bar');
});
add_action('save_post', function($post_id) {
if (get_post_type($post_id) !== 'announcement_bar') return;
foreach (['link', 'timer_end'] as $field) {
if (isset($_POST[$field])) update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
}
update_post_meta($post_id, 'enable_timer', isset($_POST['enable_timer']) ? '1' : '0');
});
add_action('admin_menu', function() {
add_submenu_page(
'edit.php?post_type=announcement_bar',
'公告栏全局设置',
'公告栏设置',
'manage_options',
'announcement_bar_options',
function() {
if ($_POST && current_user_can('manage_options')) {
update_option('announcement_bar_enabled', isset($_POST['enabled']) ? 1 : 0);
update_option('announcement_bar_autoplay', isset($_POST['autoplay']) ? 1 : 0);
update_option('announcement_bar_interval', intval($_POST['interval']));
update_option('announcement_bar_bg', sanitize_hex_color($_POST['bg']));
update_option('announcement_bar_text', sanitize_hex_color($_POST['text']));
update_option('announcement_bar_timerbg', sanitize_hex_color($_POST['timerbg']));
update_option('announcement_bar_timertext', sanitize_hex_color($_POST['timertext']));
echo '<div class="updated"><p>设置已保存!</p></div>';
}
$bg = esc_attr(get_option('announcement_bar_bg', '#222222'));
$text = esc_attr(get_option('announcement_bar_text', '#ffffff'));
$timerbg = esc_attr(get_option('announcement_bar_timerbg', '#ff4444'));
$timertext = esc_attr(get_option('announcement_bar_timertext', '#ffffff'));
?>
<div class="wrap">
<h2>公告栏全局设置</h2>
<form method="post">
<table class="form-table">
<tr>
<th><label>启用公告栏</label></th>
<td><input type="checkbox" name="enabled" value="1" <?php checked(get_option('announcement_bar_enabled'), 1); ?>></td>
</tr>
<tr>
<th><label>启用轮播(所有设备)</label></th>
<td><input type="checkbox" name="autoplay" value="1" <?php checked(get_option('announcement_bar_autoplay'), 1); ?>></td>
</tr>
<tr>
<th><label>轮播间隔(毫秒)</label></th>
<td><input type="number" name="interval" value="<?php echo esc_attr(get_option('announcement_bar_interval', 5000)); ?>" min="1000" step="500"></td>
</tr>
<tr>
<th><label>背景颜色</label></th>
<td>
<input type="color" id="bg_color_picker" value="<?php echo $bg; ?>">
<input type="text" name="bg" id="bg_color_text" value="<?php echo $bg; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>字体颜色</label></th>
<td>
<input type="color" id="text_color_picker" value="<?php echo $text; ?>">
<input type="text" name="text" id="text_color_text" value="<?php echo $text; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>倒计时背景颜色</label></th>
<td>
<input type="color" id="timerbg_color_picker" value="<?php echo $timerbg; ?>">
<input type="text" name="timerbg" id="timerbg_color_text" value="<?php echo $timerbg; ?>" style="width:100px;">
</td>
</tr>
<tr>
<th><label>倒计时字体颜色</label></th>
<td>
<input type="color" id="timertext_color_picker" value="<?php echo $timertext; ?>">
<input type="text" name="timertext" id="timertext_color_text" value="<?php echo $timertext; ?>" style="width:100px;">
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded',function(){
var bgPicker=document.getElementById('bg_color_picker');
var bgText=document.getElementById('bg_color_text');
var textPicker=document.getElementById('text_color_picker');
var textText=document.getElementById('text_color_text');
var timerbgPicker=document.getElementById('timerbg_color_picker');
var timerbgText=document.getElementById('timerbg_color_text');
var timertextPicker=document.getElementById('timertext_color_picker');
var timertextText=document.getElementById('timertext_color_text');
if(bgPicker&&bgText){
bgPicker.addEventListener('input',function(){bgText.value=bgPicker.value;});
bgText.addEventListener('input',function(){bgPicker.value=bgText.value;});
}
if(textPicker&&textText){
textPicker.addEventListener('input',function(){textText.value=textPicker.value;});
textText.addEventListener('input',function(){textPicker.value=textText.value;});
}
if(timerbgPicker&&timerbgText){
timerbgPicker.addEventListener('input',function(){timerbgText.value=timerbgPicker.value;});
timerbgText.addEventListener('input',function(){timerbgPicker.value=timerbgText.value;});
}
if(timertextPicker&&timertextText){
timertextPicker.addEventListener('input',function(){timertextText.value=timertextPicker.value;});
timertextText.addEventListener('input',function(){timertextPicker.value=timertextText.value;});
}
});
</script>
<?php
}
);
});
add_action('wp_body_open', function() {
if (!get_option('announcement_bar_enabled')) return;
$bg_color = get_option('announcement_bar_bg', '#222222');
$text_color = get_option('announcement_bar_text', '#ffffff');
$timerbg = get_option('announcement_bar_timerbg', '#ff4444');
$timertext = get_option('announcement_bar_timertext', '#ffffff');
$autoplay = get_option('announcement_bar_autoplay') ? 'true' : '0';
$interval = intval(get_option('announcement_bar_interval', 5000));
$posts = get_posts([
'post_type' => 'announcement_bar',
'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
'numberposts' => -1
]);
if (!$posts) return;
echo '<div class="announcement-bar-swiper"><div class="swiper-wrapper">';
foreach ($posts as $post) {
$link = get_post_meta($post->ID, 'link', true);
$text = esc_html($post->post_title);
$enable_timer = get_post_meta($post->ID, 'enable_timer', true);
$timer_end = get_post_meta($post->ID, 'timer_end', true);
echo '<div class="swiper-slide bar-has-timer" style="color:'.$text_color.';background:'.$bg_color.';font-weight:bold;">';
echo '<div class="bar-center-wrap">';
echo '<span class="bar-main">'.($link ? '<a href="'.esc_url($link).'">'.$text.'</a>' : $text).'</span>';
if ($enable_timer && $timer_end) {
echo '<span class="bar-countdown" data-end="'.esc_attr($timer_end).'" data-bg="'.esc_attr($timerbg).'" data-txt="'.esc_attr($timertext).'"></span>';
}
echo '</div>';
echo '</div>';
}
echo '</div></div>';
});
add_action('wp_footer', function() {
$interval = intval(get_option('announcement_bar_interval', 5000));
$autoplay = get_option('announcement_bar_autoplay') ? 'true' : '0';
?>
<style>
.announcement-bar-swiper {
font-size: 14px; position: relative; overflow: hidden; z-index: 9999;
width: 100vw; max-width: 100vw;
}
.announcement-bar-swiper .swiper-wrapper { display: flex;}
.announcement-bar-swiper .swiper-slide {
display: flex; justify-content: center; align-items: center;
padding: 10px 20px; font-weight: bold; color: inherit;
white-space: normal; word-break: break-all;
font-size: 14px; box-sizing: border-box;
width: 100vw !important; max-width: 100vw; min-width: 100vw;
}
.announcement-bar-swiper .bar-center-wrap {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
}
.announcement-bar-swiper .bar-main { display: inline-block; }
.announcement-bar-swiper .swiper-slide * { color: inherit !important; font-size: inherit !important;}
.announcement-bar-swiper a { color: inherit !important; text-decoration: none;}
.announcement-bar-swiper .bar-countdown {
display: inline-flex;
align-items: center;
gap: 6px;
margin-left: 0;
line-height: 1;
}
.announcement-bar-swiper .bar-countdown .time-num {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 32px;
padding: 2px 8px;
border-radius: 0; /* 去掉圆角 */
font-family: monospace;
font-weight: bold;
font-size: inherit;
}
.announcement-bar-swiper .bar-countdown .time-label {
margin: 0 2px;
font-family: inherit;
background: none !important;
padding: 0;
min-width: unset;
border-radius: 0;
}
@media (max-width: 767.98px) {
.announcement-bar-swiper { padding-left:0; padding-right:0;}
.announcement-bar-swiper .swiper-wrapper {
display: flex !important;
flex-direction: row !important;
width: 100vw;
}
.announcement-bar-swiper .swiper-slide {
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 0 !important;
box-sizing: border-box;
padding-left: 20px !important;
padding-right: 20px !important;
width: 100vw !important;
max-width: 100vw !important;
min-width: 100vw !important;
margin: 0 !important;
}
.announcement-bar-swiper .bar-center-wrap {
width: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.announcement-bar-swiper .bar-main {
width:100%;
justify-content:center;
text-align: center;
padding-bottom: 0;
}
.announcement-bar-swiper .bar-countdown {
width: 100%;
margin: 0;
justify-content: center;
margin-bottom: 0;
}
}
@media (min-width: 768px) {
.announcement-bar-swiper .swiper-wrapper { display: flex;}
.announcement-bar-swiper .swiper-slide {flex-direction: row !important;}
.announcement-bar-swiper .bar-countdown {margin-left:10px;margin-top:0;}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var autoplay = <?php echo $autoplay; ?>;
var interval = <?php echo $interval; ?>;
if (typeof Swiper !== 'undefined') {
new Swiper('.announcement-bar-swiper', {
loop: false,
autoplay: autoplay ? { delay: interval } : false,
slidesPerView: 1,
centeredSlides: false,
spaceBetween: 0,
});
}
document.querySelectorAll('.bar-countdown').forEach(function(el){
const end = new Date(el.dataset.end).getTime();
const bg = el.dataset.bg || '#ff4444';
const txt = el.dataset.txt || '#fff';
function render(left){
const d = Math.floor(left / (1000*60*60*24));
const h = Math.floor((left / (1000*60*60)) % 24);
const m = Math.floor((left / (1000*60)) % 60);
const s = Math.floor((left / 1000) % 60);
el.innerHTML =
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(d).padStart(2,'0')+'</span>' +
'<span class="time-label">D</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(h).padStart(2,'0')+'</span>' +
'<span class="time-label">:</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(m).padStart(2,'0')+'</span>' +
'<span class="time-label">:</span>' +
'<span class="time-num" style="background:'+bg+';color:'+txt+';">'+String(s).padStart(2,'0')+'</span>';
}
function update(){
const now = new Date().getTime();
const left = Math.max(0, end - now);
render(left);
}
update();
setInterval(update, 1000);
});
});
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
<?php
});