All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 3s
1620 lines
61 KiB
HTML
1620 lines
61 KiB
HTML
{extend name="public/base" /}
|
||
{block name="style"}
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/header.css">
|
||
<link rel="stylesheet" href="__CSS__/before-after.min.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/swiper.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/footer.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/index.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/swiper.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/amd.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/yq.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/progress.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/readon.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/wift.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/m2.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/45w.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/fs.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/xn.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/ips.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/rgb.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/bly.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/bly.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/qb.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/xh.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/jk.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/th.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/lb.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/windows.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/bottom.css">
|
||
<link rel="stylesheet" href="__CSS__/topic_laptop/wift6.css">
|
||
<script type="text/javascript">
|
||
(function (doc, win)
|
||
{
|
||
|
||
var docEl = doc.documentElement;
|
||
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
|
||
var designWidth = 2560;
|
||
var designRemPx = 100;
|
||
function setRootFontSize ()
|
||
{
|
||
console.log('触发')
|
||
var clientWidth = docEl.clientWidth;
|
||
if (!clientWidth) return;
|
||
var fontSize = (clientWidth / designWidth) * designRemPx;
|
||
fontSize = Math.max(fontSize, 20);
|
||
fontSize = Math.min(fontSize, designRemPx);
|
||
docEl.style.fontSize = fontSize + 'px';
|
||
}
|
||
|
||
setRootFontSize();
|
||
win.addEventListener(resizeEvt, setRootFontSize);
|
||
doc.addEventListener('DOMContentLoaded', setRootFontSize);
|
||
})(document, window);
|
||
</script>
|
||
{/block}
|
||
{block name="main"}
|
||
{notempty name="data.top_focus_images"}
|
||
<div class="swiper-container auto-swiper-container" style="margin-top:60px;">
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="swiper-wrapper">
|
||
{volist name="data.top_focus_images" id="tfi"}
|
||
<a class="swiper-slide auto-swiper-slide" href="{$tfi.link}">
|
||
<img src="{$tfi.image}" alt="{$tfi.title}" />
|
||
</a>
|
||
{/volist}
|
||
</div>
|
||
{else/}
|
||
<div class="swiper-wrapper">
|
||
{volist name="data.top_focus_images" id="tfi"}
|
||
<div class="swiper-slide auto-swiper-slide">
|
||
<div class="swiper-container-texts" style="color:#fff">
|
||
<div class="swiper-container-texts-t">{$tfi.title}</div>
|
||
<div class="swiper-container-texts-p">{$tfi.desc||raw|htmlspecialchars_decode}</div>
|
||
<div class="swiper-container-texts-img">
|
||
<a href="{$tfi.link}">
|
||
<img src="__IMAGES__/topic_laptop/ljgd.png" alt="" loading="lazy" >
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<img src="{$tfi.image}" alt="{$tfi.title}" loading="lazy" />
|
||
</div>
|
||
{/volist}
|
||
</div>
|
||
{/eq}
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.perf"}
|
||
<div class="amd-box">
|
||
<div class="amd-img-box">
|
||
<div class="amd-img-1 opacity0" data-order="1" data-name="">
|
||
{notempty name="data.perf.0"}<img src="{$data.perf.0.image}" alt="{$data.perf.0.title}" class="amd-img-1-1" loading="lazy" >{/notempty}
|
||
</div>
|
||
<div class="amd-img-2 opacity0" data-order="2" data-name="">
|
||
<div class="amd-img-2-1">{notempty name="data.perf.1"}<img src="{$data.perf.1.image}" alt="{$data.perf.1.title}" loading="lazy" >{/notempty}</div>
|
||
<div class="amd-img-2-2">{notempty name="data.perf.2"}<img src="{$data.perf.2.image}" alt="{$data.perf.2.title}" loading="lazy" >{/notempty}</div>
|
||
</div>
|
||
<div class="amd-img-3 opacity0" data-order="3" data-name="">
|
||
<div class="amd-img-3-left">
|
||
{notempty name="data.perf.3"}<img src="{$data.perf.3.image}" alt="{$data.perf.3.title}" class="amd-img-3-1-left" loading="lazy" >{/notempty}
|
||
</div>
|
||
<div class="amd-img-3-right">
|
||
<div class="amd-img-3-1-right">
|
||
{notempty name="data.perf.4"}<img src="{$data.perf.4.image}" alt="{$data.perf.4.title}" loading="lazy" >{/notempty}
|
||
</div>
|
||
<!-- {notempty name="data.perf.4"}<img src="{$data.perf.4.image}" alt="{$data.perf.4.title}">{/notempty} -->
|
||
<div class="amd-img-3-2-right">
|
||
{notempty name="data.perf.5"}<img src="{$data.perf.5.image}" alt="{$data.perf.5.title}" loading="lazy" >{/notempty}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="amd-img-4 opacity0" data-order="4" data-name="">
|
||
{notempty name="data.perf.6"}<img src="{$data.perf.6.image}" alt="{$data.perf.6.title}" loading="lazy" >{/notempty}
|
||
</div>
|
||
<div class="amd-img-5 opacity0" data-order="5" data-name="">
|
||
{notempty name="data.perf.7"}<img src="{$data.perf.7.image}" alt="{$data.perf.7.title}" loading="lazy" >{/notempty}
|
||
{notempty name="data.perf.8"}<img src="{$data.perf.8.image}" alt="{$data.perf.8.title}" loading="lazy" >{/notempty}
|
||
</div>
|
||
<div class="amd-img-6 opacity0" data-order="6" data-name="">
|
||
{notempty name="data.perf.9"}<img src="{$data.perf.9.image}" alt="{$data.perf.9.title}" loading="lazy" >{/notempty}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.cpu"}
|
||
{assign name="cpu_first_section" value=":array_shift($data.cpu)" /}
|
||
<div class="fullscreen-img-container" style="background: url('{$cpu_first_section.image|default=\'\'}');background-size:100% auto">
|
||
<div class="overlay-text opacity0" data-order="7">
|
||
<div>{$cpu_first_section.title|default=''}</div>
|
||
<p>{$cpu_first_section.short_title|default=''}</p>
|
||
</div>
|
||
<div class="float-cards opacity0" data-order="8" >
|
||
{volist name="data.cpu" id="co"}
|
||
<img class="float-card" src="{$co.image}" alt="{$co.title}" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
<div class="bottom-desc">
|
||
{$cpu_first_section.desc|default=''|raw}
|
||
</div>
|
||
{/notempty}
|
||
<div class="container">
|
||
<div class="progress-title">{:lang_i18n('CineBench R23 多核跑分')}</div>
|
||
<div class="progress-section">
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m4-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label">
|
||
<span class="device-name colorLinearGradient">Ryzen7 7735HS:</span>
|
||
<span class="value m4-max colorLinearGradient">13766</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container w1368">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m2-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label w1368">
|
||
<span class="device-name font32 colorCBCFD8">Ryzen5 7640HS:</span>
|
||
<span class="value gray font32 color8A8787">12950</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container w1243">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m1-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label w1243">
|
||
<span class="device-name font32 colorCBCFD8">{:lang_i18n('锐龙9 6900HX')}:</span>
|
||
<span class="value gray font32 color8A8787">13183</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container w964">
|
||
<div class="progress-bar w964">
|
||
<div class="progress-fill baseline" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label w964">
|
||
<span class="device-name baseline font32 colorCBCFD8">{:lang_i18n('酷睿i5-12450H')}:</span>
|
||
<span class="value gray font32 color8A8787">10200</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container w681">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill baseline" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label w681 ">
|
||
<span class="device-name baseline font32 colorCBCFD8">Ryzen5 6600H:</span>
|
||
<span class="value gray font32 color8A8787">10297</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="progress-p">{:lang_i18n('*此跑分为ORICO实验室测定所得,请以实际使用为准')}</div>
|
||
</div>
|
||
{notempty name="data.gpu"}
|
||
{assign name="gpu_first_section" value=":array_shift($data.gpu)"/}
|
||
<div class="readon-box" style="background: url('{$gpu_first_section.image|default=\'\'}');background-size:100% auto">
|
||
<div class="readon-text opacity0" data-order="9">
|
||
<div class="readon-t">{$gpu_first_section.title|default=''|raw}</div>
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="readon-js1">{$gpu_first_section.short_title|default=''|raw}</div>
|
||
<div class="readon-img1 opacity0" data-order="10">
|
||
<img src="{$gpu_first_section.extra_image|default=''}" alt="" loading="lazy" >
|
||
</div>
|
||
{else/}
|
||
<div class="readon-js">{$gpu_first_section.short_title|default=''|raw}</div>
|
||
<div class="readon-img opacity0" data-order="10">
|
||
<img src="{$gpu_first_section.extra_image|default=''}" alt="" loading="lazy" >
|
||
</div>
|
||
{/eq}
|
||
|
||
</div>
|
||
<div class="readon-img-box opacity0" data-order="11">
|
||
{volist name="data.gpu" id="go"}
|
||
<img src="{$go.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
<div class="container">
|
||
<div class="progress-title" style="padding-top: 0;">{:lang_i18n('3DMARK Time Spy显卡得分')}</div>
|
||
<div class="progress-section">
|
||
<div class="progress-item">
|
||
<div class="progress-bar-container">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m4-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label">
|
||
<span class="device-name colorLinearGradient">Ryzen7 7735HS:</span>
|
||
<span class="value m4-max colorLinearGradient">1700</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item w1274">
|
||
<div class="progress-bar-container ">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m2-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label">
|
||
<span class="device-name font32 colorCBCFD8">NVIDIA GTX 750:</span>
|
||
<span class="value gray font32 color8A8787">1000</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item w1274">
|
||
<div class="progress-bar-container ">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill m1-max" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label ">
|
||
<span class="device-name font32 colorCBCFD8">i7-13620H:</span>
|
||
<span class="value gray font32 color8A8787">1000</span>
|
||
</div>
|
||
</div>
|
||
<div class="progress-item w1000">
|
||
<div class="progress-bar-container ">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill baseline" data-value="100"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label">
|
||
<span class="device-name baseline font32 colorCBCFD8">Ryzen5 6600H:</span>
|
||
<span class="value gray font32 color8A8787">950</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="progress-p1">{:lang_i18n('*此跑分为ORICO实验室测定所得,请以实际使用为准')}</div>
|
||
</div>
|
||
{notempty name="data.ram"}
|
||
<div class="wift" >
|
||
|
||
<div class="wift-bg" style="background: url('{$data.ram.image}');background-size:100% auto;">
|
||
<div class="wift-test">
|
||
<div class="wift-t opacity0" data-order="12">{$data.ram.title|raw}</div>
|
||
<div class="opacity0" data-order="13">
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="wift-bg-p1">{$data.ram.short_title|raw}</div>
|
||
{else/}
|
||
<div class="wift-bg-p">{$data.ram.short_title|raw}</div>
|
||
{/eq}
|
||
</div>
|
||
</div>
|
||
<div class="wift-bg-img opacity0" data-order="14">
|
||
{$data.ram.desc|raw}
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.hard_drive"}
|
||
<div class="m2">
|
||
{assign name="hard_drive_first" value=":array_shift($data.hard_drive)"/}
|
||
<div class="m2-bg" style="background: url('{$hard_drive_first.image|default=\'\'}');background-size:100% auto">
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="m2-bg-t1 opacity0" data-order="15">{$hard_drive_first.title|default=''|raw}</div>
|
||
{else/}
|
||
<div class="m2-bg-t opacity0" data-order="15">{$hard_drive_first.title|default=''|raw}</div>
|
||
{/eq}
|
||
<div class="m2-img-box opacity0" data-order="16">
|
||
{volist name="data.hard_drive" id="ho"}
|
||
<img src="{$ho.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
|
||
<div class="fs">
|
||
{notempty name="data.cooling_system"}
|
||
{notempty name="$data.cooling_system.0"}
|
||
<div class="dl opacity0" data-order="17">
|
||
<div class="dl-t">{$data.cooling_system.0.title|raw}</div>
|
||
<p class="dl-p">{$data.cooling_system.0.short_title|raw}</p>
|
||
</div>
|
||
{/notempty}
|
||
<div class="fs-box">
|
||
{notempty name="data.cooling_system.0"}
|
||
<img src="{$data.cooling_system.0.image|default=''}" alt="" class="fs-img" loading="lazy" >
|
||
<video
|
||
src="{$data.cooling_system.0.video|default=''}"
|
||
class="fs-video" muted loop playsinline autoplay
|
||
preload="auto"
|
||
style="display: none;width: 100%;">
|
||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||
</video>
|
||
<div class="fs-ts">{$data.cooling_system.0.desc|raw}</div>
|
||
{/notempty}
|
||
<div class="fs-box-img opacity0" data-order="18">
|
||
<div class="fs-h-img">
|
||
{notempty name="data.cooling_system.1"}<img src="{$data.cooling_system.1.image}" alt="" loading="lazy" >{/notempty}
|
||
{notempty name="data.cooling_system.2"}<img src="{$data.cooling_system.2.image}" alt="" loading="lazy" >{/notempty}
|
||
</div>
|
||
<div class="fs-b-img" style="min-height: 20px;">
|
||
{notempty name="data.cooling_system.3"}<img src="{$data.cooling_system.3.image}" alt="" loading="lazy" >{/notempty}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.apps"}
|
||
<div class="xn">
|
||
<div class="xn-t opacity0" data-order="19">{$data.apps.title|default=''}</div>
|
||
<div class="xn-container">
|
||
<div class="xn-image-section">
|
||
<img src="{$data.apps.image|default=''}" alt="" class="zoom-image first-image" loading="lazy">
|
||
</div>
|
||
</div>
|
||
<div class="xn-p">{$data.apps.desc|default=''|raw}</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.screen_soft_light"}
|
||
{assign name="soft_light_first" value=":array_shift($data.screen_soft_light)"/}
|
||
<div class="ips" style="background: url('{$soft_light_first.image|default=\'\'}');background-size:100% auto">
|
||
<div class="ips-text opacity0" data-order="20">
|
||
{notempty name="soft_light_first"}
|
||
<div class="ips-t">{$soft_light_first.title|raw}</div>
|
||
<div class="ips-p">{$soft_light_first.short_title|raw}</div>
|
||
{/notempty}
|
||
|
||
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="ips-img1 opacity0" data-order="21">
|
||
{volist name="data.screen_soft_light" id="so"}
|
||
<img src="{$so.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
{else/}
|
||
<div class="ips-img opacity0" data-order="21">
|
||
{volist name="data.screen_soft_light" id="so"}
|
||
<img src="{$so.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
{/eq}
|
||
|
||
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.screen_color_gamut"}
|
||
{assign name="color_gamut_first" value=":array_shift($data.screen_color_gamut)"/}
|
||
<div class="rgb" style="background: url('{$color_gamut_first.image|default=\'\'}');background-size:100% auto">
|
||
{notempty name="color_gamut_first"}
|
||
<div class="rgb-text opacity0" data-order="22">
|
||
<div class="rgb-t">{$color_gamut_first.title|raw}</div>
|
||
<div class="rgb-p">{$color_gamut_first.short_title|raw}</div>
|
||
</div>
|
||
{/notempty}
|
||
<div class="rgb-img opacity0" data-order="23">
|
||
{volist name="data.screen_color_gamut" id="so"}
|
||
<img src="{$so.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.screen_anti_glare"}
|
||
<div class="bly">
|
||
{assign name="anti_glare_first" value=":array_shift($data.screen_anti_glare)"/}
|
||
{notempty name="anti_glare_first"}
|
||
<div class="bly-text opacity0" data-order="24">
|
||
<div class="bly-t">{$anti_glare_first.title|raw}</div>
|
||
<div class="bly-p">{$anti_glare_first.short_title|raw}</div>
|
||
</div>
|
||
{/notempty}
|
||
<div class="beforeafter ba-slider">
|
||
{assign name="anti_glare_left" value=":array_shift($data.screen_anti_glare)"/}
|
||
<img src="{$anti_glare_left.image|default=''}" loading="lazy" >
|
||
<div class="resize">
|
||
{assign name="anti_glare_right" value=":array_shift($data.screen_anti_glare)"/}
|
||
<img src="{$anti_glare_right.image|default=''}" loading="lazy" >
|
||
</div>
|
||
<span class="handle"></span>
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.exterior_texture"}
|
||
<div class="qb">
|
||
<div class="qb-text opacity0" data-order="25">
|
||
{assign name="exterior_texture_first" value=":array_shift($data.exterior_texture)"/}
|
||
<div class="qb-t">{$exterior_texture_first.title|default=''|raw}</div>
|
||
<div class="qb-p">{$exterior_texture_first.short_title|default=''|raw}</div>
|
||
<div class="swiper-container auto-swiper-container">
|
||
<div class="swiper-wrapper">
|
||
{volist name="data.exterior_texture" id="eo"}
|
||
<a class="swiper-slide auto-swiper-slide">
|
||
<img src="{$eo.image}" alt="{$eo.title}" href="{$eo.link}" loading="lazy" >
|
||
</a>
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.network_card"}
|
||
{assign name="netword_card_first" value=":array_shift($data.network_card)"/}
|
||
<div class="wift6" style="background: url('{$netword_card_first.image|default=\'\'}');background-size:100% auto">
|
||
<div class="wift6-text opacity0" data-order="26">
|
||
<div class="wift6-t">{$netword_card_first.title|default=''|raw}</div>
|
||
<div class="wift6-p">{$netword_card_first.short_title|default=''|raw}</div>
|
||
</div>
|
||
<div class="wift6-img opacity0" data-order="27">
|
||
{volist name="data.network_card" id="no"}
|
||
<img src="{$no.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.battery_life"}
|
||
{assign name="battery_life_first" value=":array_shift($data.battery_life)"/}
|
||
<div class="xh" style="background: url('{$battery_life_first.image|default=\'\'}');background-size:100% auto">
|
||
<div class="xh-text opacity0" data-order="28">
|
||
<div class="xh-t">{$battery_life_first.title|default=''|raw}</div>
|
||
<div class="xh-p">{$battery_life_first.short_title|default=''|raw}</div>
|
||
</div>
|
||
<div class="xh-img opacity0" data-order="29">
|
||
{volist name="data.battery_life" id="bo"}
|
||
<img src="{$bo.image}" alt="" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
<div class="xh-b-p">{$battery_life_first.desc|default=''|raw}</div>
|
||
</div>
|
||
{/notempty}
|
||
<div class="zoom-container" id="zoomContainer">
|
||
<div class="zoom-text">
|
||
<div>{:lang_i18n("接口大满贯")}</div>
|
||
<p>{:lang_i18n("标配多种接口,会议室连接电脑、U盘传输文件、TF卡读取等,全都轻松搞定")}</p>
|
||
</div>
|
||
<div class="img-wrapper">
|
||
<img src="__IMAGES__/topic_laptop/jk.png" alt="接口图" class="bg-img" id="bgImg" loading="lazy" >
|
||
</div>
|
||
<div class="annotation anno-delay-1" style="top: 53.5%; left: 42%;"><span style="text-align: center;">{:lang_i18n('肯辛通锁孔')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 57%; left: 37%;"><span style="text-align: center;">{:lang_i18n('千兆网口')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 60.3%; left: 31%;"><span style="text-align: center;">{:lang_i18n('USB-A<br/>(5Gbps)')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top:63.4%; left:25%;"><span style="text-align: center;">{:lang_i18n('USB-A<br/>(480Mbps)')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 66%; left: 20.5%;"><span style="text-align: center;">{:lang_i18n('3.5mm<br/>耳麦合一')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 68%; left: 16%;"><span style="text-align: center;">{:lang_i18n('TF口3.0')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 63.5%; left: 70.5%;"><span style="text-align: center;">{:lang_i18n('USB-A<br/>(5Gbps)')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 66.5%; left: 76%;"><span style="text-align: center;">{:lang_i18n('USB-C<br/>(5Gbps)')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 59.5%; left: 64%;"><span style="text-align: center;">{:lang_i18n('HDMI')}</span></div>
|
||
<div class="annotation anno-delay-1" style="top: 57%; left: 59%;"><span style="text-align: center;">{:lang_i18n('全功能<br/>USB-C')}</span></div>
|
||
</div>
|
||
{notempty name="data.scene_focus_images"}
|
||
<div class="lb">
|
||
<div class="carousel-wrapper">
|
||
<div class="carousel-arrow arrow-left">
|
||
<img src="__IMAGES__/topic_laptop/l1.png" alt="左箭头" loading="lazy" >
|
||
</div>
|
||
<div class="carousel-container">
|
||
<div class="carousel-imgs">
|
||
{volist name="data.scene_focus_images" id="so"}
|
||
<img src="{$so.image}" alt="{$so.title}" class="carousel-img" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
<div class="carousel-arrow arrow-right">
|
||
<img src="__IMAGES__/topic_laptop/r1.png" alt="右箭头" loading="lazy" >
|
||
</div>
|
||
</div>
|
||
<div class="carousel-texts">
|
||
{volist name="data.scene_focus_images" id="so"}
|
||
<div class="carousel-text {if $key == 0}active{/if}" data-index="{$key}" loading="lazy" >
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="carousel-text-t1">{$so.title}</div>
|
||
<div class="carousel-text-p1">{$so.short_title}</div>
|
||
{else/}
|
||
<div class="carousel-text-t">{$so.title}</div>
|
||
<div class="carousel-text-p">{$so.short_title}</div>
|
||
{/eq}
|
||
</div>
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.camare_microphone_security"}
|
||
{assign name="camare_microphone" value=":array_shift($data.camare_microphone_security)"/}
|
||
{assign name="security" value=":array_shift($data.camare_microphone_security)"/}
|
||
<div class="tabs-container">
|
||
<div class="tab-t active opacity0" data-index="0" data-order="30">{$camare_microphone.title|default=''}</div>
|
||
<div class="tab-t opacity0" data-index="1" data-order="30">{$security.title|default=''}</div>
|
||
<div class="tab-content">
|
||
{notempty name="camare_microphone"}
|
||
<div class="tab-panel active">
|
||
<div class="tab-panel-img">
|
||
<img src="{$camare_microphone.image}" alt="{$camare_microphone.title}" class="content-image" loading="lazy" >
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="security"}
|
||
<div class="tab-panel">
|
||
<video
|
||
src="{$security.video}"
|
||
id="securityVideo" class="content-video" muted loop playsinline autoplay
|
||
style="width: 100%;margin:0 auto;max-width: 1440px;">
|
||
您的浏览器不支持HTML5视频播放,请升级浏览器
|
||
</video>
|
||
</div>
|
||
{/notempty}
|
||
</div>
|
||
<div class="tabs-header-box">
|
||
<div class="tabs-header">
|
||
{notempty name="camare_microphone"}<div class="tab-item active" data-index="0">{$camare_microphone.short_title|default=''}</div>{/notempty}
|
||
{notempty name="security"}<div class="tab-item" data-index="1">{$security.short_title|default=''}</div>{/notempty}
|
||
<div class="tab-indicator"></div>
|
||
</div>
|
||
</div>
|
||
{notempty name="camare_microphone"}
|
||
<div class="tabs-p active" data-index="0">{$camare_microphone.desc|default=''|raw}</div>
|
||
{/notempty}
|
||
{notempty name="security"}
|
||
<div class="tabs-p" data-index="1">{$security.desc|default=''|raw}</div>
|
||
{/notempty}
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.unified_preinstall"}
|
||
<div class="windows" style="background: url('{$data.unified_preinstall.image|default=\'\'}');background-size:100% auto"></div>
|
||
{/notempty}
|
||
{notempty name="data.product_testing"}
|
||
<div class="bottom-img-box">
|
||
<div class="bottom-img opacity0" data-order="31">
|
||
{volist name="data.product_testing" id="po"}
|
||
<img src="{$po.image}" alt="{$po.title}" loading="lazy" >
|
||
{/volist}
|
||
</div>
|
||
</div>
|
||
{/notempty}
|
||
{notempty name="data.webpage_footnotes"}
|
||
<div class="bottom-text">
|
||
{eq name=":cookie('think_lang')" value="en-us"}
|
||
<div class="bottom-p1">{$data.webpage_footnotes.desc|raw|htmlspecialchars_decode}</div>
|
||
{else/}
|
||
<div class="bottom-p">{$data.webpage_footnotes.desc|raw|htmlspecialchars_decode}</div>
|
||
{/eq}
|
||
</div>
|
||
{/notempty}
|
||
{/block}
|
||
{block name="script"}
|
||
<script src="__JS__/before-after.min.js" type="text/javascript"></script>
|
||
<script type="text/javascript">
|
||
// 轮播初始化
|
||
let swiper;
|
||
window.onload = function ()
|
||
{
|
||
if (typeof Swiper === 'undefined') {
|
||
console.error('Swiper加载失败,请刷新页面重试');
|
||
return;
|
||
}
|
||
swiper = new Swiper('.auto-swiper-container', {
|
||
autoplay: {
|
||
delay: 3000,
|
||
disableOnInteraction: false,
|
||
},
|
||
loop: true,
|
||
slidesPerView: 1,
|
||
spaceBetween: 0,
|
||
pagination: false,
|
||
navigation: false,
|
||
scrollbar: false,
|
||
on: {
|
||
resize: function ()
|
||
{
|
||
this.update();
|
||
},
|
||
},
|
||
});
|
||
window.dispatchEvent(new Event('scroll'));
|
||
};
|
||
|
||
// 滚动淡入动效(核心优化:18-19号顺序执行)
|
||
(function ()
|
||
{
|
||
const TRIGGER_RATIO = 0.1;
|
||
let lastScrollY = window.scrollY;
|
||
let isResizing = false;
|
||
let resizeTimer = null;
|
||
let is18Animated = false; // 18号执行标记
|
||
|
||
const els = Array.from(document.querySelectorAll('[data-order]')).sort((a, b) => a.dataset.order - b.dataset.order);
|
||
const elState = new Map();
|
||
els.forEach(el =>
|
||
{
|
||
elState.set(el, {
|
||
isInView: false,
|
||
isFadedIn: false,
|
||
is18: el.dataset.order === '18',
|
||
is19: el.dataset.order === '19'
|
||
});
|
||
});
|
||
|
||
const isElementInView = (el) =>
|
||
{
|
||
const rect = el.getBoundingClientRect();
|
||
const viewportHeight = window.innerHeight;
|
||
const viewportWidth = window.innerWidth;
|
||
|
||
const intersects = (
|
||
rect.bottom > 0 &&
|
||
rect.top < viewportHeight &&
|
||
rect.right > 0 &&
|
||
rect.left < viewportWidth
|
||
);
|
||
|
||
if (!intersects) return false;
|
||
|
||
const visibleHeight = Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0);
|
||
const visibleWidth = Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0);
|
||
const visibleRatio = (visibleHeight * visibleWidth) / (rect.height * rect.width);
|
||
|
||
// 18号降低阈值,19号必须等18号执行完
|
||
const state = elState.get(el);
|
||
if (state.is18) return visibleRatio >= 0.3;
|
||
if (state.is19) return visibleRatio >= 0.5 && is18Animated;
|
||
return visibleRatio >= TRIGGER_RATIO;
|
||
};
|
||
|
||
const isElementAboveViewport = (el) =>
|
||
{
|
||
const rect = el.getBoundingClientRect();
|
||
return rect.bottom <= 0 || isElementInView(el);
|
||
};
|
||
|
||
const fadeInElement = (el) =>
|
||
{
|
||
if (elState.get(el).isFadedIn) return;
|
||
el.classList.add('fade-in');
|
||
elState.get(el).isFadedIn = true;
|
||
// 标记18号执行完成
|
||
if (elState.get(el).is18) is18Animated = true;
|
||
};
|
||
|
||
const hideElement = (el) =>
|
||
{
|
||
if (isResizing) return;
|
||
if (!elState.get(el).isFadedIn) return;
|
||
el.classList.remove('fade-in');
|
||
elState.get(el).isFadedIn = false;
|
||
};
|
||
|
||
const debounce = (fn, delay = 16) =>
|
||
{
|
||
let timer = null;
|
||
return (isResize = false) =>
|
||
{
|
||
clearTimeout(timer);
|
||
isResizing = isResize;
|
||
timer = setTimeout(() =>
|
||
{
|
||
fn();
|
||
if (isResize) {
|
||
isResizing = false;
|
||
els.forEach(el =>
|
||
{
|
||
const isFaded = elState.get(el).isFadedIn;
|
||
const isAbove = isElementAboveViewport(el);
|
||
if (isFaded) el.classList.add('fade-in');
|
||
if (!isFaded && isAbove) fadeInElement(el);
|
||
});
|
||
}
|
||
}, delay);
|
||
};
|
||
};
|
||
|
||
const refreshAllElementsState = () =>
|
||
{
|
||
els.forEach(el =>
|
||
{
|
||
const isFaded = elState.get(el).isFadedIn;
|
||
const isAbove = isElementAboveViewport(el);
|
||
if (isFaded) {
|
||
el.classList.add('fade-in');
|
||
}
|
||
if (!isFaded && isAbove) {
|
||
fadeInElement(el);
|
||
}
|
||
});
|
||
};
|
||
|
||
const handleScroll = debounce((isResize) =>
|
||
{
|
||
if (isResize) return;
|
||
|
||
const currentScrollY = window.scrollY;
|
||
const isScrollUp = currentScrollY < lastScrollY;
|
||
const isScrollDown = currentScrollY > lastScrollY;
|
||
|
||
els.forEach(el =>
|
||
{
|
||
const prevInView = elState.get(el).isInView;
|
||
const currentInView = isElementInView(el);
|
||
elState.set(el, { ...elState.get(el), isInView: currentInView });
|
||
|
||
if (isScrollDown) {
|
||
if (currentInView && !prevInView) {
|
||
fadeInElement(el);
|
||
}
|
||
}
|
||
|
||
if (isScrollUp) {
|
||
if (!currentInView && prevInView) {
|
||
hideElement(el);
|
||
}
|
||
}
|
||
});
|
||
|
||
lastScrollY = currentScrollY;
|
||
});
|
||
|
||
const handleResize = () =>
|
||
{
|
||
clearTimeout(resizeTimer);
|
||
isResizing = true;
|
||
resizeTimer = setTimeout(() =>
|
||
{
|
||
isResizing = false;
|
||
refreshAllElementsState();
|
||
}, 200);
|
||
};
|
||
|
||
const initAllAboveElements = () =>
|
||
{
|
||
setTimeout(() =>
|
||
{
|
||
els.forEach(el =>
|
||
{
|
||
if (isElementAboveViewport(el)) {
|
||
fadeInElement(el);
|
||
}
|
||
});
|
||
}, 100);
|
||
};
|
||
|
||
window.addEventListener('scroll', () => handleScroll(false), { passive: true });
|
||
window.addEventListener('resize', handleResize);
|
||
window.addEventListener('load', initAllAboveElements);
|
||
document.addEventListener('DOMContentLoaded', initAllAboveElements);
|
||
})();
|
||
|
||
// 接口模块动画
|
||
(function ()
|
||
{
|
||
const TRIGGER_RATIO = 0.1;
|
||
let lastScrollY = window.scrollY;
|
||
let isResizing = false;
|
||
let resizeTimer = null;
|
||
|
||
const zoomContainer = document.getElementById('zoomContainer');
|
||
const annotations = document.querySelectorAll('.annotation');
|
||
const bgImg = document.getElementById('bgImg');
|
||
|
||
const elState = new Map();
|
||
if (zoomContainer) {
|
||
elState.set(zoomContainer, {
|
||
isInView: false,
|
||
isFadedIn: false
|
||
});
|
||
}
|
||
|
||
const isElementInView = (el) =>
|
||
{
|
||
const rect = el.getBoundingClientRect();
|
||
const viewportHeight = window.innerHeight;
|
||
const viewportWidth = window.innerWidth;
|
||
|
||
const intersects = (
|
||
rect.bottom > 0 &&
|
||
rect.top < viewportHeight &&
|
||
rect.right > 0 &&
|
||
rect.left < viewportWidth
|
||
);
|
||
|
||
if (!intersects) return false;
|
||
|
||
const visibleHeight = Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0);
|
||
const visibleWidth = Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0);
|
||
const visibleRatio = (visibleHeight * visibleWidth) / (rect.height * rect.width);
|
||
|
||
return visibleRatio >= TRIGGER_RATIO;
|
||
};
|
||
|
||
const isElementAboveViewport = (el) =>
|
||
{
|
||
const rect = el.getBoundingClientRect();
|
||
return rect.bottom <= 0 || isElementInView(el);
|
||
};
|
||
|
||
const fadeInInterface = (el) =>
|
||
{
|
||
if (!el || elState.get(el).isFadedIn) return;
|
||
annotations.forEach(anno => anno.classList.add('anno-show'));
|
||
bgImg.classList.add('zoom-out');
|
||
elState.get(el).isFadedIn = true;
|
||
};
|
||
|
||
const hideInterface = (el) =>
|
||
{
|
||
if (isResizing) return;
|
||
if (!el || !elState.get(el).isFadedIn) return;
|
||
annotations.forEach(anno => anno.classList.remove('anno-show'));
|
||
bgImg.classList.remove('zoom-out');
|
||
elState.get(el).isFadedIn = false;
|
||
};
|
||
|
||
const debounce = (fn, delay = 16) =>
|
||
{
|
||
let timer = null;
|
||
return (isResize = false) =>
|
||
{
|
||
clearTimeout(timer);
|
||
isResizing = isResize;
|
||
timer = setTimeout(() =>
|
||
{
|
||
fn();
|
||
isResizing = false;
|
||
}, delay);
|
||
};
|
||
};
|
||
|
||
const handleScroll = debounce((isResize) =>
|
||
{
|
||
if (isResize) return;
|
||
|
||
const currentScrollY = window.scrollY;
|
||
const isScrollUp = currentScrollY < lastScrollY;
|
||
const isScrollDown = currentScrollY > lastScrollY;
|
||
|
||
if (!zoomContainer) return;
|
||
|
||
const prevInView = elState.get(zoomContainer).isInView;
|
||
const currentInView = isElementInView(zoomContainer);
|
||
elState.set(zoomContainer, { ...elState.get(zoomContainer), isInView: currentInView });
|
||
|
||
if (isScrollDown) {
|
||
if (currentInView && !prevInView) {
|
||
fadeInInterface(zoomContainer);
|
||
}
|
||
}
|
||
|
||
if (isScrollUp) {
|
||
if (!currentInView && prevInView) {
|
||
hideInterface(zoomContainer);
|
||
}
|
||
}
|
||
|
||
lastScrollY = currentScrollY;
|
||
});
|
||
|
||
const handleResize = () =>
|
||
{
|
||
clearTimeout(resizeTimer);
|
||
isResizing = true;
|
||
resizeTimer = setTimeout(() =>
|
||
{
|
||
isResizing = false;
|
||
if (zoomContainer && elState.get(zoomContainer).isFadedIn) {
|
||
annotations.forEach(anno => anno.classList.add('anno-show'));
|
||
bgImg.classList.add('zoom-out');
|
||
}
|
||
}, 200);
|
||
};
|
||
|
||
const initInterfaceElement = () =>
|
||
{
|
||
setTimeout(() =>
|
||
{
|
||
if (zoomContainer && isElementAboveViewport(zoomContainer)) {
|
||
fadeInInterface(zoomContainer);
|
||
}
|
||
}, 100);
|
||
};
|
||
|
||
window.addEventListener('scroll', () => handleScroll(false), { passive: true });
|
||
window.addEventListener('resize', handleResize);
|
||
window.addEventListener('load', initInterfaceElement);
|
||
document.addEventListener('DOMContentLoaded', initInterfaceElement);
|
||
})();
|
||
|
||
// 进度条动画
|
||
function animateProgressBars (container)
|
||
{
|
||
if (container._isAnimating) return;
|
||
container._isAnimating = true;
|
||
|
||
const progressFills = container.querySelectorAll('.progress-fill');
|
||
progressFills.forEach(fill =>
|
||
{
|
||
clearTimeout(fill._animateTimer);
|
||
fill.style.width = '0';
|
||
fill._animateTimer = setTimeout(() =>
|
||
{
|
||
const targetValue = fill.getAttribute('data-value');
|
||
fill.style.width = targetValue + '%';
|
||
setTimeout(() =>
|
||
{
|
||
container._isAnimating = false;
|
||
}, 500);
|
||
}, 100);
|
||
});
|
||
}
|
||
|
||
function isElementInView (el)
|
||
{
|
||
const rect = el.getBoundingClientRect();
|
||
const viewportHeight = window.innerHeight;
|
||
const viewportWidth = window.innerWidth;
|
||
|
||
const intersects = (
|
||
rect.bottom > 0 &&
|
||
rect.top < viewportHeight &&
|
||
rect.right > 0 &&
|
||
rect.left < viewportWidth
|
||
);
|
||
|
||
if (!intersects) return false;
|
||
|
||
const visibleHeight = Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0);
|
||
const visibleWidth = Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0);
|
||
const visibleRatio = (visibleHeight * visibleWidth) / (rect.height * rect.width);
|
||
|
||
return visibleRatio >= 0.1;
|
||
}
|
||
|
||
function isProgressContainerAbove (container)
|
||
{
|
||
const rect = container.getBoundingClientRect();
|
||
return rect.bottom <= 0 || isElementInView(container);
|
||
}
|
||
|
||
const debounce = (fn, delay = 16) =>
|
||
{
|
||
let timer = null;
|
||
return (isResize = false) =>
|
||
{
|
||
clearTimeout(timer);
|
||
timer = setTimeout(() => fn(isResize), delay);
|
||
};
|
||
};
|
||
|
||
const progressContainers = document.querySelectorAll('.container');
|
||
const progressAnimatedMap = new Map();
|
||
const progressPermanentMap = new Map();
|
||
|
||
progressContainers.forEach(container =>
|
||
{
|
||
progressAnimatedMap.set(container, false);
|
||
progressPermanentMap.set(container, false);
|
||
});
|
||
|
||
const handleProgressScroll = debounce((isResize) =>
|
||
{
|
||
if (isResize) return;
|
||
|
||
progressContainers.forEach(container =>
|
||
{
|
||
if (progressPermanentMap.get(container)) return;
|
||
|
||
const isAnimated = progressAnimatedMap.get(container);
|
||
if (isElementInView(container) && !isAnimated) {
|
||
animateProgressBars(container);
|
||
progressAnimatedMap.set(container, true);
|
||
progressPermanentMap.set(container, true);
|
||
}
|
||
});
|
||
});
|
||
|
||
let progressResizeTimer = null;
|
||
const handleProgressResize = () =>
|
||
{
|
||
clearTimeout(progressResizeTimer);
|
||
progressResizeTimer = setTimeout(() =>
|
||
{
|
||
progressContainers.forEach(container =>
|
||
{
|
||
const isPermanent = progressPermanentMap.get(container);
|
||
if (isPermanent) {
|
||
const progressFills = container.querySelectorAll('.progress-fill');
|
||
progressFills.forEach(fill =>
|
||
{
|
||
clearTimeout(fill._animateTimer);
|
||
const targetValue = fill.getAttribute('data-value');
|
||
fill.style.width = targetValue + '%';
|
||
});
|
||
}
|
||
});
|
||
}, 200);
|
||
};
|
||
|
||
const initAllProgressContainers = () =>
|
||
{
|
||
setTimeout(() =>
|
||
{
|
||
progressContainers.forEach(container =>
|
||
{
|
||
if (!progressPermanentMap.get(container) && isProgressContainerAbove(container)) {
|
||
animateProgressBars(container);
|
||
progressAnimatedMap.set(container, true);
|
||
progressPermanentMap.set(container, true);
|
||
}
|
||
});
|
||
}, 100);
|
||
};
|
||
|
||
window.addEventListener('scroll', () => handleProgressScroll(false), { passive: true });
|
||
window.addEventListener('resize', handleProgressResize);
|
||
document.addEventListener('DOMContentLoaded', initAllProgressContainers);
|
||
|
||
// 视频/图片切换(核心优化:恢复自动播放+防卡顿)
|
||
(function() {
|
||
const allVideos = document.querySelectorAll('.fs-video');
|
||
const fsBox = document.querySelector('.fs-box');
|
||
let isVideoPlaying = false;
|
||
let videoTip = null;
|
||
|
||
// 初始化视频提示
|
||
const initVideoTip = () => {
|
||
if (!fsBox || videoTip) return;
|
||
videoTip = document.createElement('div');
|
||
videoTip.className = 'video-tip';
|
||
videoTip.innerText = '点击播放视频';
|
||
fsBox.appendChild(videoTip);
|
||
videoTip.style.display = 'none';
|
||
};
|
||
|
||
// 停止所有视频
|
||
function stopAllVideos ()
|
||
{
|
||
allVideos.forEach((video) =>
|
||
{
|
||
video.pause();
|
||
video.style.display = 'none';
|
||
const img = video.parentElement.querySelector('.fs-img');
|
||
if (img) img.style.display = 'block';
|
||
});
|
||
isVideoPlaying = false;
|
||
if (videoTip) videoTip.style.display = 'none';
|
||
}
|
||
|
||
// 播放指定视频
|
||
const playTargetVideo = (video) => {
|
||
if (!video) return;
|
||
stopAllVideos();
|
||
const img = video.parentElement.querySelector('.fs-img');
|
||
img.style.display = 'none';
|
||
video.style.display = 'block';
|
||
|
||
// 强制静音+播放
|
||
video.muted = true;
|
||
video.play().then(() => {
|
||
isVideoPlaying = true;
|
||
if (videoTip) videoTip.style.display = 'none';
|
||
}).catch((err) => {
|
||
console.log('视频自动播放失败:', err);
|
||
video.style.display = 'block';
|
||
img.style.display = 'none';
|
||
if (videoTip) videoTip.style.display = 'block';
|
||
// 点击视频手动播放
|
||
video.addEventListener('click', () => {
|
||
video.play();
|
||
isVideoPlaying = true;
|
||
if (videoTip) videoTip.style.display = 'none';
|
||
}, { once: true });
|
||
});
|
||
};
|
||
|
||
// 可视区判断(优化18号触发)
|
||
const isFsBoxInView = () => {
|
||
if (!fsBox) return false;
|
||
const rect = fsBox.getBoundingClientRect();
|
||
return rect.top < window.innerHeight * 0.8 && rect.bottom > window.innerHeight * 0.2;
|
||
};
|
||
|
||
// 滚动处理(防抖+节流)
|
||
let lastVideoScrollTime = 0;
|
||
const handleVideoScroll = () => {
|
||
const now = Date.now();
|
||
if (now - lastVideoScrollTime < 50) return; // 节流50ms
|
||
lastVideoScrollTime = now;
|
||
|
||
if (isFsBoxInView() && !isVideoPlaying) {
|
||
const video = fsBox.querySelector('.fs-video');
|
||
playTargetVideo(video);
|
||
} else if (!isFsBoxInView() && isVideoPlaying) {
|
||
stopAllVideos();
|
||
}
|
||
};
|
||
|
||
// 页面交互后自动播放
|
||
document.addEventListener('click', () => {
|
||
if (isFsBoxInView() && !isVideoPlaying) {
|
||
const video = fsBox.querySelector('.fs-video');
|
||
playTargetVideo(video);
|
||
}
|
||
}, { once: true });
|
||
|
||
// 缩放处理
|
||
let isVideoResizing = false;
|
||
let videoResizeTimer = null;
|
||
const handleVideoResize = () => {
|
||
clearTimeout(videoResizeTimer);
|
||
isVideoResizing = true;
|
||
videoResizeTimer = setTimeout(() => {
|
||
isVideoResizing = false;
|
||
if (isVideoPlaying) {
|
||
const playingVideo = document.querySelector('.fs-video[style*="display: block"]');
|
||
if (playingVideo) {
|
||
const img = playingVideo.parentElement.querySelector('.fs-img');
|
||
img.style.display = 'none';
|
||
playingVideo.style.display = 'block';
|
||
}
|
||
}
|
||
}, 200);
|
||
};
|
||
|
||
// 初始化
|
||
initVideoTip();
|
||
window.addEventListener('scroll', handleVideoScroll, { passive: true });
|
||
window.addEventListener('resize', handleVideoResize);
|
||
// 页面加载完成后尝试播放
|
||
window.addEventListener('load', () => {
|
||
if (isFsBoxInView()) {
|
||
const video = fsBox.querySelector('.fs-video');
|
||
playTargetVideo(video);
|
||
}
|
||
});
|
||
})();
|
||
|
||
// 图片放大动效
|
||
document.addEventListener('DOMContentLoaded', function ()
|
||
{
|
||
const zoomImages = document.querySelectorAll('.zoom-image');
|
||
let isResizing = false;
|
||
let resizeTimer = null;
|
||
|
||
const isImageAboveViewport = (image) =>
|
||
{
|
||
const rect = image.getBoundingClientRect();
|
||
return rect.bottom <= 0 || (rect.top < window.innerHeight * (2 / 3) && rect.bottom > 0);
|
||
};
|
||
|
||
const debounce = (fn) =>
|
||
{
|
||
let timer = null;
|
||
return () =>
|
||
{
|
||
clearTimeout(timer);
|
||
timer = setTimeout(() =>
|
||
{
|
||
if (!isResizing) fn();
|
||
}, 16);
|
||
};
|
||
};
|
||
|
||
const handleScroll = debounce(() =>
|
||
{
|
||
zoomImages.forEach(image =>
|
||
{
|
||
const imageRect = image.getBoundingClientRect();
|
||
const windowHeight = window.innerHeight;
|
||
const triggerPoint = windowHeight * (2 / 3);
|
||
|
||
if (imageRect.top < triggerPoint && imageRect.bottom > 0) {
|
||
image.classList.add('active');
|
||
} else {
|
||
image.classList.remove('active');
|
||
}
|
||
});
|
||
});
|
||
|
||
const handleResize = () =>
|
||
{
|
||
clearTimeout(resizeTimer);
|
||
isResizing = true;
|
||
resizeTimer = setTimeout(() =>
|
||
{
|
||
isResizing = false;
|
||
zoomImages.forEach(image =>
|
||
{
|
||
if (image.classList.contains('active')) {
|
||
image.classList.add('active');
|
||
}
|
||
});
|
||
}, 200);
|
||
};
|
||
|
||
const initZoomImages = () =>
|
||
{
|
||
zoomImages.forEach(image =>
|
||
{
|
||
if (isImageAboveViewport(image)) {
|
||
image.classList.add('active');
|
||
}
|
||
});
|
||
};
|
||
|
||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||
window.addEventListener('resize', handleResize);
|
||
window.addEventListener('load', initZoomImages);
|
||
document.addEventListener('DOMContentLoaded', initZoomImages);
|
||
window.dispatchEvent(new Event('scroll'));
|
||
});
|
||
|
||
// 图片对比滑块
|
||
$(document).ready(function ()
|
||
{
|
||
$('.ba-slider').beforeAfter({
|
||
startPercent: 50,
|
||
handle: '.handle',
|
||
resize: '.resize'
|
||
});
|
||
});
|
||
|
||
// Tab切换
|
||
const tabItems = document.querySelectorAll('.tab-item');
|
||
const tabPanels = document.querySelectorAll('.tab-panel');
|
||
const tabPs = document.querySelectorAll('.tabs-p');
|
||
const tabT = document.querySelectorAll('.tab-t');
|
||
const indicator = document.querySelector('.tab-indicator');
|
||
const securityVideo = document.getElementById('securityVideo');
|
||
console.log(tabT,'=========tabT=============')
|
||
let prevIndex = 0;
|
||
const tabRects = [];
|
||
|
||
function cacheTabRects ()
|
||
{
|
||
tabRects.length = 0;
|
||
tabItems.forEach(item =>
|
||
{
|
||
tabRects.push({
|
||
left: item.offsetLeft,
|
||
width: item.offsetWidth
|
||
});
|
||
});
|
||
const initRect = tabRects[0];
|
||
indicator.style.width = initRect.width + 'px';
|
||
indicator.style.transform = `translateX(${initRect.left}px)`;
|
||
}
|
||
|
||
cacheTabRects();
|
||
|
||
function resetVideo ()
|
||
{
|
||
if (securityVideo) {
|
||
securityVideo.pause();
|
||
securityVideo.currentTime = 0;
|
||
}
|
||
}
|
||
|
||
function playVideo ()
|
||
{
|
||
if (securityVideo) {
|
||
securityVideo.muted = true;
|
||
securityVideo.play().catch(err =>
|
||
{
|
||
console.log('自动播放失败,请手动点击播放:', err);
|
||
});
|
||
}
|
||
}
|
||
|
||
tabItems.forEach(item =>
|
||
{
|
||
item.addEventListener('click', () =>
|
||
{
|
||
const index = parseInt(item.dataset.index);
|
||
if (index === prevIndex) return;
|
||
|
||
tabItems[prevIndex].classList.remove('active');
|
||
item.classList.add('active');
|
||
|
||
tabPanels[prevIndex].classList.remove('active');
|
||
tabPanels[index].classList.add('active');
|
||
|
||
tabPs[prevIndex].classList.remove('active');
|
||
tabPs[index].classList.add('active');
|
||
|
||
tabT[prevIndex].classList.remove('active');
|
||
tabT[index].classList.add('active');
|
||
console.log(tabT,'=tabT=')
|
||
if (index === 1) {
|
||
playVideo();
|
||
} else if (prevIndex === 1) {
|
||
resetVideo();
|
||
}
|
||
|
||
const rect = tabRects[index];
|
||
indicator.style.width = rect.width + 'px';
|
||
indicator.style.transform = `translateX(${rect.left}px)`;
|
||
|
||
prevIndex = index;
|
||
});
|
||
});
|
||
|
||
window.addEventListener('resize', () =>
|
||
{
|
||
cacheTabRects();
|
||
const currentRect = tabRects[prevIndex];
|
||
indicator.style.width = currentRect.width + 'px';
|
||
indicator.style.transform = `translateX(${currentRect.left}px)`;
|
||
});
|
||
|
||
tabItems.forEach(item =>
|
||
{
|
||
item.addEventListener('touchstart', (e) =>
|
||
{
|
||
e.preventDefault();
|
||
item.click();
|
||
}, { passive: false });
|
||
});
|
||
|
||
document.addEventListener('DOMContentLoaded', () =>
|
||
{
|
||
resetVideo();
|
||
});
|
||
|
||
|
||
// document.addEventListener('DOMContentLoaded', () => {
|
||
// // 1. 获取元素(匹配你的结构)
|
||
// const carouselImgs = document.querySelector('.carousel-imgs');
|
||
// const imgItems = document.querySelectorAll('.carousel-img');
|
||
// const leftArrow = document.querySelector('.arrow-left');
|
||
// const rightArrow = document.querySelector('.arrow-right');
|
||
// const textItems = document.querySelectorAll('.carousel-text');
|
||
// const carouselContainer = document.querySelector('.carousel-container');
|
||
|
||
// // 容错处理
|
||
// if (!carouselImgs || imgItems.length === 0) {
|
||
// console.warn('轮播图片为空,初始化终止');
|
||
// return;
|
||
// }
|
||
|
||
// // 2. 核心变量(仅索引,无尺寸计算)
|
||
// const imgCount = imgItems.length;
|
||
// let currentIndex = 0;
|
||
// let autoPlayTimer = null;
|
||
// let isResizing = false; // 缩放锁,避免重复触发
|
||
|
||
// // 3. 切换到指定索引(核心:百分比偏移,无尺寸计算)
|
||
// const goToIndex = (index) => {
|
||
// // 边界处理
|
||
// if (index < 0) index = imgCount - 1;
|
||
// if (index >= imgCount) index = 0;
|
||
|
||
// // 关键:用百分比偏移,彻底避开rem/px计算误差
|
||
// carouselImgs.style.transform = `translateX(-${index * 100}%)`;
|
||
// currentIndex = index;
|
||
|
||
// // 更新文字激活态
|
||
// textItems.forEach((item, idx) => {
|
||
// item.classList.toggle('active', idx === currentIndex);
|
||
// });
|
||
// };
|
||
|
||
// // 4. 左右切换逻辑
|
||
// const slideNext = () => goToIndex(currentIndex + 1);
|
||
// const slidePrev = () => goToIndex(currentIndex - 1);
|
||
|
||
// // 5. 自动播放逻辑
|
||
// const autoPlay = () => {
|
||
// clearInterval(autoPlayTimer);
|
||
// autoPlayTimer = setInterval(slideNext, 3000); // 3秒切换,可改
|
||
// };
|
||
|
||
// // 6. 绑定事件
|
||
// // 箭头点击
|
||
// leftArrow?.addEventListener('click', () => {
|
||
// slidePrev();
|
||
// autoPlay(); // 点击后重启自动播放
|
||
// });
|
||
// rightArrow?.addEventListener('click', () => {
|
||
// slideNext();
|
||
// autoPlay();
|
||
// });
|
||
|
||
// // 文字指示器点击
|
||
// textItems.forEach((item, idx) => {
|
||
// item.addEventListener('click', () => {
|
||
// goToIndex(idx);
|
||
// autoPlay();
|
||
// });
|
||
// });
|
||
|
||
// // 鼠标悬停暂停
|
||
// carouselContainer?.addEventListener('mouseenter', () => {
|
||
// clearInterval(autoPlayTimer);
|
||
// });
|
||
// carouselContainer?.addEventListener('mouseleave', autoPlay);
|
||
|
||
// // 7. 窗口缩放响应(核心:仅重新定位,无计算)
|
||
// const handleResize = () => {
|
||
// if (isResizing) return;
|
||
// isResizing = true;
|
||
|
||
// // 缩放时直接重新定位当前索引(百分比偏移无需计算)
|
||
// goToIndex(currentIndex);
|
||
|
||
// // 解锁
|
||
// setTimeout(() => {
|
||
// isResizing = false;
|
||
// }, 100);
|
||
// };
|
||
|
||
// // 防抖监听窗口缩放
|
||
// let resizeTimer;
|
||
// window.addEventListener('resize', () => {
|
||
// clearTimeout(resizeTimer);
|
||
// resizeTimer = setTimeout(handleResize, 150);
|
||
// });
|
||
|
||
// // 8. 初始化
|
||
// goToIndex(0); // 初始定位到第一张
|
||
// autoPlay(); // 启动自动播放
|
||
|
||
// // 9. 页面卸载清理定时器
|
||
// window.addEventListener('beforeunload', () => {
|
||
// clearInterval(autoPlayTimer);
|
||
// });
|
||
// });
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
// 1. 获取元素
|
||
const carouselImgs = document.querySelector('.carousel-imgs');
|
||
const imgItems = document.querySelectorAll('.carousel-img');
|
||
const leftArrow = document.querySelector('.arrow-left');
|
||
const rightArrow = document.querySelector('.arrow-right');
|
||
const textItems = document.querySelectorAll('.carousel-text');
|
||
const carouselContainer = document.querySelector('.carousel-container');
|
||
|
||
// 容错处理
|
||
if (!carouselImgs || imgItems.length === 0) {
|
||
console.warn('轮播图片为空,初始化终止');
|
||
return;
|
||
}
|
||
|
||
// 2. 核心配置
|
||
const imgCount = imgItems.length; // 真实图片数量(如3张:1/2/3)
|
||
let currentRealIndex = 0; // 真实图片索引(0=1, 1=2, 2=3)
|
||
let isTransitioning = false; // 过渡锁,防止动画冲突
|
||
const transitionDuration = 500; // 过渡时长(ms),需与CSS一致
|
||
let autoPlayTimer = null;
|
||
|
||
// 3. 初始化无缝DOM:仅复制第一张到末尾(适配3→1右侧滑入)
|
||
const initSeamless = () => {
|
||
// 复制第一张图片(1)到轮播容器末尾
|
||
const firstImgCopy = imgItems[0].cloneNode(true);
|
||
carouselImgs.appendChild(firstImgCopy);
|
||
// 初始定位:无过渡,显示真实第一张
|
||
carouselImgs.style.transition = 'none';
|
||
carouselImgs.style.transform = `translateX(0%)`;
|
||
void carouselImgs.offsetWidth; // 强制重绘
|
||
// 开启过渡
|
||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||
};
|
||
initSeamless();
|
||
|
||
// 4. 核心切换函数(保证3→1时1从右侧滑入)
|
||
const slideToNext = () => {
|
||
if (isTransitioning) return;
|
||
isTransitioning = true;
|
||
|
||
// 步骤1:计算目标偏移,执行滑动动画
|
||
const targetTranslateX = -(currentRealIndex + 1) * 100;
|
||
carouselImgs.style.transform = `translateX(${targetTranslateX}%)`;
|
||
|
||
// 步骤2:监听过渡结束,处理无缝逻辑
|
||
const handleEnd = () => {
|
||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||
isTransitioning = false;
|
||
|
||
// 如果滑到了复制的第一张(3→1的视觉终点)
|
||
if (currentRealIndex === imgCount - 1) {
|
||
// 瞬间切回真实第一张(无过渡,用户无感知)
|
||
carouselImgs.style.transition = 'none';
|
||
carouselImgs.style.transform = `translateX(0%)`;
|
||
void carouselImgs.offsetWidth;
|
||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||
currentRealIndex = 0; // 重置为真实第一张
|
||
} else {
|
||
currentRealIndex += 1; // 正常切换,索引+1
|
||
}
|
||
|
||
// 更新文字指示器激活态
|
||
textItems.forEach((item, idx) => {
|
||
item.classList.toggle('active', idx === currentRealIndex);
|
||
});
|
||
};
|
||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||
};
|
||
|
||
// 5. 反向切换(1→3,可选保留)
|
||
const slideToPrev = () => {
|
||
if (isTransitioning) return;
|
||
isTransitioning = true;
|
||
|
||
// 1→3时,先瞬间切到复制的3位置,再滑入
|
||
if (currentRealIndex === 0) {
|
||
carouselImgs.style.transition = 'none';
|
||
carouselImgs.style.transform = `translateX(-${imgCount * 100}%)`;
|
||
void carouselImgs.offsetWidth;
|
||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||
currentRealIndex = imgCount - 1;
|
||
}
|
||
|
||
const targetTranslateX = -currentRealIndex * 100;
|
||
carouselImgs.style.transform = `translateX(${targetTranslateX}%)`;
|
||
|
||
const handleEnd = () => {
|
||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||
isTransitioning = false;
|
||
// 更新文字指示器
|
||
textItems.forEach((item, idx) => {
|
||
item.classList.toggle('active', idx === currentRealIndex);
|
||
});
|
||
};
|
||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||
};
|
||
|
||
// 6. 自动播放:严格1→2→3→1循环
|
||
const autoPlay = () => {
|
||
clearInterval(autoPlayTimer);
|
||
autoPlayTimer = setInterval(() => {
|
||
if (!isTransitioning) slideToNext();
|
||
}, 3000); // 3秒切换一次,可调整
|
||
};
|
||
|
||
// 7. 事件绑定
|
||
// 右箭头:下一张(核心,保证3→1右侧滑入)
|
||
rightArrow?.addEventListener('click', () => {
|
||
slideToNext();
|
||
autoPlay(); // 点击后重启自动播放
|
||
});
|
||
// 左箭头:上一张(可选,如需取消可注释)
|
||
leftArrow?.addEventListener('click', () => {
|
||
slideToPrev();
|
||
autoPlay();
|
||
});
|
||
|
||
// 文字指示器点击
|
||
textItems.forEach((item, idx) => {
|
||
item.addEventListener('click', () => {
|
||
if (isTransitioning || currentRealIndex === idx) return;
|
||
isTransitioning = true;
|
||
|
||
// 直接滑到目标图片
|
||
carouselImgs.style.transform = `translateX(-${idx * 100}%)`;
|
||
currentRealIndex = idx;
|
||
|
||
// 过渡结束解锁
|
||
const handleEnd = () => {
|
||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||
isTransitioning = false;
|
||
};
|
||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||
|
||
autoPlay();
|
||
});
|
||
});
|
||
|
||
// 鼠标悬停暂停/恢复
|
||
carouselContainer?.addEventListener('mouseenter', () => {
|
||
clearInterval(autoPlayTimer);
|
||
});
|
||
carouselContainer?.addEventListener('mouseleave', autoPlay);
|
||
|
||
// 8. 初始化
|
||
// 激活第一个文字指示器
|
||
textItems.forEach((item, idx) => {
|
||
item.classList.toggle('active', idx === 0);
|
||
});
|
||
autoPlay(); // 启动自动播放
|
||
|
||
// 9. 页面卸载清理定时器
|
||
window.addEventListener('beforeunload', () => {
|
||
clearInterval(autoPlayTimer);
|
||
});
|
||
});
|
||
</script>
|
||
{/block}
|