qb-pc-sdk 1.1.5 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,10 +16,10 @@ npm install qb-pc-sdk
16
16
 
17
17
  ### CDN 方式
18
18
 
19
- 无需安装,直接在 HTML 中引入一个文件即可:
19
+ 无需安装,直接在 HTML 中引入一个文件即可(使用 jsdelivr CDN,国内访问更快更稳定):
20
20
 
21
21
  ```html
22
- <script src="https://unpkg.com/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
23
23
  ```
24
24
 
25
25
  ## 使用方法
@@ -104,7 +104,8 @@ new AdSDK({
104
104
  <div id="ad-container"></div>
105
105
 
106
106
  <!-- 只需引入一个文件,会自动加载底层 SDK 和封装 SDK -->
107
- <script src="https://unpkg.com/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
107
+ <!-- 使用 jsdelivr CDN(国内访问更快更稳定) -->
108
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
108
109
 
109
110
  <!-- 使用 SDK -->
110
111
  <script>
@@ -163,13 +164,116 @@ new AdSDK({
163
164
  如果需要使用特定版本,可以指定版本号:
164
165
 
165
166
  ```html
166
- <!-- 使用最新版本 -->
167
- <script src="https://unpkg.com/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
167
+ <!-- 使用最新版本(推荐使用 jsdelivr CDN,国内访问更快更稳定) -->
168
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
168
169
 
169
170
  <!-- 使用指定版本 -->
170
- <script src="https://unpkg.com/qb-pc-sdk@1.1.3/qb-pc-sdk.js"></script>
171
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@1.1.3/qb-pc-sdk.js"></script>
171
172
  ```
172
173
 
174
+ ### 方式三:WordPress 即插即用模式(推荐用于建站平台)
175
+
176
+ 专为 WordPress 等建站平台设计的**零代码接入方式**,客户只需复制粘贴即可使用,无需任何技术背景。
177
+
178
+ #### 基本用法
179
+
180
+ 在需要展示广告的位置插入以下代码:
181
+
182
+ ```html
183
+ <ins class="qb-adsbyqubian"
184
+ style="display:block; width:400px; height:220px;"
185
+ data-app-id="your-app-id"
186
+ data-placement-id="your-placement-id">
187
+ </ins>
188
+ <!-- 使用 jsdelivr CDN(国内访问更快更稳定) -->
189
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js" async></script>
190
+ <script>(window.qbAds = window.qbAds || []).push({});</script>
191
+ ```
192
+
193
+ #### 多个广告位
194
+
195
+ 支持在同一个页面中插入多个广告位,每个广告位使用独立的 `<ins>` 标签:
196
+
197
+ ```html
198
+ <!-- 广告位 1:横幅广告 (728x90) -->
199
+ <ins class="qb-adsbyqubian"
200
+ style="display:block; width:728px; height:90px;"
201
+ data-app-id="your-app-id"
202
+ data-placement-id="your-placement-id-1">
203
+ </ins>
204
+
205
+ <!-- 广告位 2:中等尺寸 (400x220) -->
206
+ <ins class="qb-adsbyqubian"
207
+ style="display:block; width:400px; height:220px;"
208
+ data-app-id="your-app-id"
209
+ data-placement-id="your-placement-id-2">
210
+ </ins>
211
+
212
+ <!-- 广告位 3:窄条横幅 (780x60) -->
213
+ <ins class="qb-adsbyqubian"
214
+ style="display:block; width:780px; height:60px;"
215
+ data-app-id="your-app-id"
216
+ data-placement-id="your-placement-id-3">
217
+ </ins>
218
+
219
+ <!-- 脚本只需引入一次,放在页面底部即可 -->
220
+ <!-- 使用 jsdelivr CDN(国内访问更快更稳定) -->
221
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js" async></script>
222
+ <script>(window.qbAds = window.qbAds || []).push({});</script>
223
+ ```
224
+
225
+ #### 可选回调配置(高级用法)
226
+
227
+ 如果需要监听广告加载、点击等事件,可以在 `push` 中传入回调函数:
228
+
229
+ ```html
230
+ <script>
231
+ (window.qbAds = window.qbAds || []).push({
232
+ onAdLoaded: function(ad, instance, element) {
233
+ console.log('✅ 广告加载成功', element);
234
+ // 可以在这里进行统计等操作
235
+ },
236
+ onAdError: function(err, msg, element) {
237
+ console.error('❌ 广告加载失败', err, msg, element);
238
+ // 可以在这里进行错误处理
239
+ },
240
+ onAdExpose: function(element) {
241
+ console.log('👀 广告曝光', element);
242
+ // 可以在这里进行曝光统计
243
+ },
244
+ onAdClick: function(element) {
245
+ console.log('🖱️ 广告被点击', element);
246
+ // 可以在这里进行点击统计
247
+ }
248
+ });
249
+ </script>
250
+ ```
251
+
252
+ #### 参数说明
253
+
254
+ | 参数 | 说明 | 必填 | 示例 |
255
+ |------|------|------|------|
256
+ | `class="qb-adsbyqubian"` | 必需的类名,用于标识广告位 | ✅ | `class="qb-adsbyqubian"` |
257
+ | `data-app-id` | 您的应用 ID | ✅ | `data-app-id="1999336062823956569"` |
258
+ | `data-placement-id` | 广告位 ID | ✅ | `data-placement-id="1999381081819709520"` |
259
+ | `style` | 广告位尺寸样式 | 建议 | `style="display:block; width:400px; height:220px;"` |
260
+
261
+ #### 特点
262
+
263
+ - ✅ **零代码接入**:客户只需复制粘贴,无需技术背景
264
+ - ✅ **自动适配**:广告会根据容器尺寸自动适配布局(横幅、中等、小尺寸)
265
+ - ✅ **即插即用**:支持动态添加的广告位(SPA、Ajax 等场景)
266
+ - ✅ **多广告位**:支持在同一个页面中插入多个广告位
267
+ - ✅ **事件回调**:支持监听广告加载、点击、曝光等事件
268
+
269
+ #### 注意事项
270
+
271
+ 1. **脚本引入**:`<script src="...">` 只需引入一次,建议放在页面底部或 `</body>` 标签之前
272
+ 2. **初始化调用**:`(window.qbAds = window.qbAds || []).push({})` 只需调用一次,建议放在最后一个广告位之后
273
+ 3. **容器尺寸**:建议为每个 `<ins>` 标签设置明确的 `width` 和 `height`
274
+ 4. **类名要求**:必须包含 `class="qb-adsbyqubian"`,否则广告不会被识别
275
+ 5. **参数必填**:`data-app-id` 和 `data-placement-id` 必须填写正确,否则广告无法加载
276
+
173
277
  ## API
174
278
 
175
279
  ### 构造函数
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qb-pc-sdk",
3
- "version": "1.1.5",
4
- "description": "趣变广告 SDK 封装器 - https",
3
+ "version": "1.1.7",
4
+ "description": "趣变广告 SDK 封装器 - 国内cdn接入",
5
5
  "main": "index.js",
6
6
  "files": [
7
7
  "index.js",
package/qb-pc-sdk.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * 自动加载底层 SDK 和封装 SDK,只需引入一个文件即可使用
4
4
  *
5
5
  * 使用方式:
6
- * <script src="https://unpkg.com/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
6
+ * <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
7
7
  *
8
8
  * 然后直接使用 window.AdSDK
9
9
  */
@@ -39,7 +39,8 @@
39
39
  };
40
40
 
41
41
  const version = getCurrentVersion();
42
- const baseUrl = 'https://unpkg.com';
42
+ // 使用 jsdelivr CDN(国内访问更快更稳定)
43
+ const baseUrl = 'https://cdn.jsdelivr.net/npm';
43
44
 
44
45
  // 动态加载脚本
45
46
  const loadScript = function(url, callback) {
@@ -310,6 +310,21 @@
310
310
  .q-ad-wrapper.q-ad-small .q-ad-title { font-size: 12px; }
311
311
  .q-ad-wrapper.q-ad-small .q-ad-desc { font-size: 10px; margin-bottom: 4px; }
312
312
  .q-ad-wrapper.q-ad-small .q-cta-btn { padding: 3px 10px; font-size: 10px; }
313
+ /* Banner样式(横向细长条广告)优化 */
314
+ .q-ad-wrapper.q-ad-banner { flex-direction: row !important; align-items: stretch; }
315
+ .q-ad-wrapper.q-ad-banner .q-media-container { width: auto !important; flex: 0 0 auto !important; min-width: 0; height: 100% !important; max-width: 40% !important; min-width: 120px; position: relative; }
316
+ .q-ad-wrapper.q-ad-banner .q-ad-img, .q-ad-wrapper.q-ad-banner .q-ad-video { width: 100% !important; height: 100% !important; object-fit: cover !important; }
317
+ .q-ad-wrapper.q-ad-banner .q-content-container { flex: 1 !important; padding: 6px 10px !important; justify-content: center !important; min-width: 0; display: flex !important; flex-direction: column !important; width: auto !important; }
318
+ .q-ad-wrapper.q-ad-banner .q-ad-title { font-size: 14px !important; margin: 0 0 3px 0 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; flex-shrink: 0; }
319
+ .q-ad-wrapper.q-ad-banner .q-ad-desc { font-size: 11px !important; margin: 0 0 4px 0 !important; -webkit-line-clamp: 1 !important; line-height: 1.3 !important; overflow: hidden !important; text-overflow: ellipsis !important; display: -webkit-box !important; -webkit-box-orient: vertical !important; flex-shrink: 0; }
320
+ .q-ad-wrapper.q-ad-banner .q-cta-btn { padding: 4px 12px !important; font-size: 11px !important; align-self: flex-start !important; flex-shrink: 0; margin-top: auto !important; }
321
+ .q-ad-wrapper.q-ad-banner .q-ad-tag { right: auto !important; left: 5px !important; }
322
+ /* 超窄Banner样式(高度小于80px) */
323
+ .q-ad-wrapper.q-ad-banner.q-ad-banner-narrow .q-media-container { max-width: 35% !important; min-width: 100px !important; }
324
+ .q-ad-wrapper.q-ad-banner.q-ad-banner-narrow .q-content-container { padding: 4px 8px !important; }
325
+ .q-ad-wrapper.q-ad-banner.q-ad-banner-narrow .q-ad-title { font-size: 13px !important; margin-bottom: 2px !important; }
326
+ .q-ad-wrapper.q-ad-banner.q-ad-banner-narrow .q-ad-desc { font-size: 10px !important; margin-bottom: 3px !important; display: none !important; }
327
+ .q-ad-wrapper.q-ad-banner.q-ad-banner-narrow .q-cta-btn { padding: 3px 10px !important; font-size: 10px !important; }
313
328
  `;
314
329
 
315
330
  class AdSDKWrapper {
@@ -513,20 +528,70 @@
513
528
  const adImageWidth = ad.getImageWidth ? ad.getImageWidth() : 0;
514
529
  const adImageHeight = ad.getImageHeight ? ad.getImageHeight() : 0;
515
530
 
516
- // 获取容器尺寸
517
- const containerRect = this.container.getBoundingClientRect();
518
- const containerWidth = containerRect.width || this.container.offsetWidth || 200;
519
- const containerHeight = containerRect.height || this.container.offsetHeight || 120;
531
+ // 获取容器尺寸(优先使用计算样式,确保获取准确)
532
+ let containerWidth = this.container.offsetWidth;
533
+ let containerHeight = this.container.offsetHeight;
520
534
 
521
- // 判断是否为小尺寸广告(宽度或高度小于300px)
522
- const isSmallAd = containerWidth < 300 || containerHeight < 200;
523
- const wrapperClass = isSmallAd ? 'q-ad-wrapper q-ad-small' : 'q-ad-wrapper';
535
+ // 如果 offsetWidth/offsetHeight 为0,尝试使用 getBoundingClientRect
536
+ if (!containerWidth || !containerHeight) {
537
+ const containerRect = this.container.getBoundingClientRect();
538
+ containerWidth = containerRect.width || containerWidth || 200;
539
+ containerHeight = containerRect.height || containerHeight || 120;
540
+ }
541
+
542
+ // 如果还是0,尝试从计算样式获取
543
+ if (!containerWidth || !containerHeight) {
544
+ const computedStyle = window.getComputedStyle(this.container);
545
+ containerWidth = parseFloat(computedStyle.width) || 200;
546
+ containerHeight = parseFloat(computedStyle.height) || 120;
547
+ }
548
+
549
+ // 计算宽高比
550
+ const aspectRatio = containerWidth / containerHeight;
551
+
552
+ // 判断是否为Banner样式(横向细长条):宽高比大于3:1,且高度小于150px
553
+ const isBanner = aspectRatio > 3 && containerHeight < 150;
554
+ const isNarrowBanner = isBanner && containerHeight < 80;
555
+
556
+ // 判断是否为小尺寸广告(宽度或高度小于300px,但不是Banner)
557
+ const isSmallAd = !isBanner && (containerWidth < 300 || containerHeight < 200);
558
+
559
+ // 构建样式类
560
+ let wrapperClass = 'q-ad-wrapper';
561
+ if (isBanner) {
562
+ wrapperClass += ' q-ad-banner';
563
+ if (isNarrowBanner) {
564
+ wrapperClass += ' q-ad-banner-narrow';
565
+ }
566
+ } else if (isSmallAd) {
567
+ wrapperClass += ' q-ad-small';
568
+ }
569
+
570
+ // 调试信息(始终输出,便于排查问题)
571
+ console.log('[AdSDK] 容器尺寸检测:', {
572
+ width: containerWidth,
573
+ height: containerHeight,
574
+ aspectRatio: aspectRatio.toFixed(2),
575
+ isBanner: isBanner,
576
+ isNarrowBanner: isNarrowBanner,
577
+ isSmallAd: isSmallAd,
578
+ wrapperClass: wrapperClass
579
+ });
524
580
 
525
581
  // 构建 HTML 结构
582
+ // 如果是Banner样式,计算媒体容器的宽度(基于高度和宽高比)
583
+ let mediaContainerStyle = '';
584
+ if (isBanner) {
585
+ // Banner样式:媒体容器宽度 = 高度 * 宽高比(16:9 或 4:3)
586
+ const mediaAspectRatio = isNarrowBanner ? 4/3 : 16/9;
587
+ const mediaWidth = Math.min(containerHeight * mediaAspectRatio, containerWidth * 0.4);
588
+ mediaContainerStyle = `width: ${mediaWidth}px;`;
589
+ }
590
+
526
591
  this.container.innerHTML = `
527
592
  <div class="${wrapperClass}">
528
593
  <button class="q-ad-close" title="关闭广告" style="position: absolute; top: 5px; right: 5px; width: 20px; height: 20px; background: rgba(0,0,0,0.5); color: #fff; border: none; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; line-height: 1; z-index: 10; transition: background 0.2s; flex-shrink: 0; padding: 0; margin: 0; box-sizing: border-box; font-family: Arial, sans-serif; font-weight: bold;">×</button>
529
- <div class="q-media-container">
594
+ <div class="q-media-container" style="${mediaContainerStyle}">
530
595
  <div class="q-ad-video" style="display:none"></div>
531
596
  <img class="q-ad-img" style="display:none">
532
597
  <span class="q-ad-tag">广告</span>
@@ -662,6 +727,245 @@
662
727
  // 浏览器环境:挂载到 window
663
728
  if (typeof window !== 'undefined' && window.document) {
664
729
  window.AdSDK = AdSDKWrapper;
730
+
731
+ // ============================================================
732
+ // 即插即用模式:自动扫描并初始化 <ins class="qb-adsbyqubian"> 标签
733
+ // 支持 WordPress 等建站平台的傻瓜式接入
734
+ // ============================================================
735
+
736
+ // 初始化 qbAds 队列(类似 Google AdSense 的 adsbygoogle)
737
+ if (!window.qbAds) {
738
+ window.qbAds = [];
739
+ }
740
+
741
+ // 存储已处理的广告位实例
742
+ window._qbAdsInstances = window._qbAdsInstances || [];
743
+
744
+ /**
745
+ * 扫描并初始化页面中所有 <ins class="qb-adsbyqubian"> 标签
746
+ */
747
+ function initAllAdSlots() {
748
+ if (!window.AdSDK || !window.GDTAdSDK) {
749
+ // SDK 未加载完成,等待
750
+ return false;
751
+ }
752
+
753
+ // 查找所有 <ins class="qb-adsbyqubian"> 标签
754
+ const adSlots = window.document.querySelectorAll('ins.qb-adsbyqubian');
755
+
756
+ if (adSlots.length === 0) {
757
+ return true; // 没有广告位,也算处理完成
758
+ }
759
+
760
+ adSlots.forEach(function(insElement, index) {
761
+ // 跳过已经处理过的标签
762
+ if (insElement._qbAdInitialized) {
763
+ return;
764
+ }
765
+
766
+ // 标记为已处理
767
+ insElement._qbAdInitialized = true;
768
+
769
+ // 获取配置参数
770
+ const appId = insElement.getAttribute('data-app-id');
771
+ const placementId = insElement.getAttribute('data-placement-id');
772
+
773
+ if (!appId || !placementId) {
774
+ console.warn('[qb-ads] 广告位缺少必要参数:', {
775
+ appId: appId,
776
+ placementId: placementId,
777
+ element: insElement
778
+ });
779
+ return;
780
+ }
781
+
782
+ // 确保 ins 标签有容器样式
783
+ const computedStyle = window.getComputedStyle(insElement);
784
+ if (computedStyle.display === 'none') {
785
+ insElement.style.display = 'block';
786
+ }
787
+
788
+ // 清空 ins 标签内容(广告会渲染到这里)
789
+ insElement.innerHTML = '';
790
+
791
+ // 创建 AdSDKWrapper 实例
792
+ try {
793
+ const adSDKInstance = new window.AdSDK({
794
+ appId: appId,
795
+ placementId: placementId,
796
+ container: insElement,
797
+ onAdLoaded: function(ad, instance) {
798
+ // 广告加载成功回调(可选)
799
+ if (window.qbAds._onAdLoaded && typeof window.qbAds._onAdLoaded === 'function') {
800
+ window.qbAds._onAdLoaded.call(this, ad, instance, insElement);
801
+ }
802
+ },
803
+ onAdError: function(err, msg) {
804
+ // 广告加载失败回调(可选)
805
+ if (window.qbAds._onAdError && typeof window.qbAds._onAdError === 'function') {
806
+ window.qbAds._onAdError.call(this, err, msg, insElement);
807
+ }
808
+ },
809
+ onAdExpose: function() {
810
+ if (window.qbAds._onAdExpose && typeof window.qbAds._onAdExpose === 'function') {
811
+ window.qbAds._onAdExpose.call(this, insElement);
812
+ }
813
+ },
814
+ onAdClick: function() {
815
+ if (window.qbAds._onAdClick && typeof window.qbAds._onAdClick === 'function') {
816
+ window.qbAds._onAdClick.call(this, insElement);
817
+ }
818
+ }
819
+ });
820
+
821
+ // 保存实例引用
822
+ window._qbAdsInstances.push({
823
+ element: insElement,
824
+ instance: adSDKInstance
825
+ });
826
+
827
+ } catch (error) {
828
+ console.error('[qb-ads] 初始化广告位失败:', error, {
829
+ appId: appId,
830
+ placementId: placementId,
831
+ element: insElement
832
+ });
833
+ }
834
+ });
835
+
836
+ return true;
837
+ }
838
+
839
+ /**
840
+ * 重写 qbAds.push 方法,当调用 push({}) 时触发广告初始化
841
+ */
842
+ const originalPush = window.qbAds.push.bind(window.qbAds);
843
+
844
+ // 确保只监听一次 SDK 就绪事件
845
+ if (!window._qbAdsReadyHandler) {
846
+ window._qbAdsReadyHandler = function() {
847
+ if (window.AdSDK && window.GDTAdSDK) {
848
+ setTimeout(function() {
849
+ initAllAdSlots();
850
+ }, 0);
851
+ }
852
+ };
853
+ window.addEventListener('qb-pc-sdk-ready', window._qbAdsReadyHandler);
854
+ }
855
+
856
+ window.qbAds.push = function(config) {
857
+ // config 通常是一个空对象 {},用于触发初始化
858
+ // 但也可以传入回调函数配置
859
+ if (config && typeof config === 'object') {
860
+ if (config.onAdLoaded && typeof config.onAdLoaded === 'function') {
861
+ window.qbAds._onAdLoaded = config.onAdLoaded;
862
+ }
863
+ if (config.onAdError && typeof config.onAdError === 'function') {
864
+ window.qbAds._onAdError = config.onAdError;
865
+ }
866
+ if (config.onAdExpose && typeof config.onAdExpose === 'function') {
867
+ window.qbAds._onAdExpose = config.onAdExpose;
868
+ }
869
+ if (config.onAdClick && typeof config.onAdClick === 'function') {
870
+ window.qbAds._onAdClick = config.onAdClick;
871
+ }
872
+ }
873
+
874
+ // 尝试初始化所有广告位
875
+ const initialized = initAllAdSlots();
876
+
877
+ if (!initialized && window.AdSDK && window.GDTAdSDK) {
878
+ // 如果 SDK 已经加载但初始化失败,稍后重试
879
+ setTimeout(function() {
880
+ initAllAdSlots();
881
+ }, 100);
882
+ }
883
+
884
+ // 保持队列的原始行为
885
+ return originalPush(config);
886
+ };
887
+
888
+ // 如果 DOM 已经加载完成,立即尝试初始化
889
+ if (window.document.readyState === 'complete' || window.document.readyState === 'interactive') {
890
+ setTimeout(function() {
891
+ if (window.AdSDK && window.GDTAdSDK) {
892
+ initAllAdSlots();
893
+ }
894
+ }, 0);
895
+ } else {
896
+ // 监听 DOMContentLoaded 事件
897
+ window.addEventListener('DOMContentLoaded', function() {
898
+ setTimeout(function() {
899
+ if (window.AdSDK && window.GDTAdSDK) {
900
+ initAllAdSlots();
901
+ }
902
+ }, 0);
903
+ });
904
+ }
905
+
906
+ // 如果 SDK 已经加载完成(同步加载的情况),立即尝试初始化
907
+ if (window.AdSDK && window.GDTAdSDK) {
908
+ setTimeout(function() {
909
+ initAllAdSlots();
910
+ }, 0);
911
+ }
912
+
913
+ // 监听 SDK 就绪事件(异步加载的情况)
914
+ window.addEventListener('qb-pc-sdk-ready', function() {
915
+ setTimeout(function() {
916
+ initAllAdSlots();
917
+ }, 0);
918
+ });
919
+
920
+ // 使用 MutationObserver 监听动态添加的广告位(适用于 SPA 等场景)
921
+ if (window.MutationObserver) {
922
+ const observer = new window.MutationObserver(function(mutations) {
923
+ let shouldInit = false;
924
+ mutations.forEach(function(mutation) {
925
+ mutation.addedNodes.forEach(function(node) {
926
+ if (node.nodeType === 1) {
927
+ // 检查是否是广告位标签,或其包含广告位标签
928
+ if (node.tagName && node.tagName.toLowerCase() === 'ins' &&
929
+ node.classList && node.classList.contains('qb-adsbyqubian')) {
930
+ shouldInit = true;
931
+ } else if (node.querySelectorAll) {
932
+ const adSlots = node.querySelectorAll('ins.qb-adsbyqubian');
933
+ if (adSlots.length > 0) {
934
+ shouldInit = true;
935
+ }
936
+ }
937
+ }
938
+ });
939
+ });
940
+
941
+ if (shouldInit && window.AdSDK && window.GDTAdSDK) {
942
+ setTimeout(function() {
943
+ initAllAdSlots();
944
+ }, 100); // 延迟一点,确保 DOM 完全插入
945
+ }
946
+ });
947
+
948
+ // 开始观察
949
+ if (window.document.body) {
950
+ observer.observe(window.document.body, {
951
+ childList: true,
952
+ subtree: true
953
+ });
954
+ } else {
955
+ window.addEventListener('DOMContentLoaded', function() {
956
+ if (window.document.body) {
957
+ observer.observe(window.document.body, {
958
+ childList: true,
959
+ subtree: true
960
+ });
961
+ }
962
+ });
963
+ }
964
+ }
965
+
966
+ // ============================================================
967
+ // 即插即用模式初始化完成
968
+ // ============================================================
665
969
  }
666
970
 
667
971
  // CommonJS 模块导出
@@ -7,8 +7,8 @@
7
7
  <style>
8
8
  body { margin: 0; padding: 20px; font-family: sans-serif; background: #f0f2f5; }
9
9
  #ad-slot-1 {
10
- width: 400px;
11
- height: 220px;
10
+ width: 728px;
11
+ height: 500px;
12
12
  margin: 20px auto;
13
13
  box-sizing: border-box;
14
14
  }
@@ -17,10 +17,14 @@
17
17
  <body>
18
18
  <div id="ad-slot-1"></div>
19
19
 
20
- <!-- 只需引入一个文件,会自动加载底层 SDK 和封装 SDK -->
21
- <!-- CDN 方式(发布到 npm 后使用) -->
22
- <script src="https://unpkg.com/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
23
- <!-- 本地测试方式(如果还未发布到 npm,取消下面这行的注释,注释掉上面的 CDN 方式) -->
20
+ <!-- 测试最新代码:直接引用源文件 -->
21
+ <!-- 先引入底层 SDK -->
22
+ <!-- 使用 jsdelivr CDN(国内访问更快更稳定) -->
23
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js"></script>
24
+ <!-- 再引入封装 SDK 源文件(包含最新的 Banner 适配代码) -->
25
+ <!-- <script src="ad-sdk-wrapper.js"></script> -->
26
+
27
+ <!-- 如果使用打包后的文件(可能不包含最新代码),取消下面这行的注释 -->
24
28
  <!-- <script src="../qb-pc-sdk.js"></script> -->
25
29
 
26
30
  <script>
@@ -74,8 +78,8 @@
74
78
 
75
79
  // 初始化广告
76
80
  const adSDK = new window.AdSDK({
77
- appId: '1999364640831725629',
78
- placementId: '2003009002186760245',
81
+ appId: '2004088976381599817',
82
+ placementId: '2004089182414200847',
79
83
  container: '#ad-slot-1',
80
84
  onAdLoaded: (ad, adSDKInstance) => {
81
85
  console.log('✅ 广告加载完成');
@@ -0,0 +1,290 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>WordPress 即插即用模式示例</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ padding: 20px;
11
+ font-family: Arial, sans-serif;
12
+ background: #f5f5f5;
13
+ line-height: 1.6;
14
+ }
15
+ .container {
16
+ max-width: 1200px;
17
+ margin: 0 auto;
18
+ background: #fff;
19
+ padding: 30px;
20
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
21
+ }
22
+ h1 {
23
+ color: #333;
24
+ border-bottom: 2px solid #007bff;
25
+ padding-bottom: 10px;
26
+ }
27
+ h2 {
28
+ color: #555;
29
+ margin-top: 30px;
30
+ }
31
+ .code-block {
32
+ background: #f8f8f8;
33
+ border: 1px solid #ddd;
34
+ border-left: 4px solid #007bff;
35
+ padding: 15px;
36
+ margin: 15px 0;
37
+ overflow-x: auto;
38
+ font-family: 'Courier New', monospace;
39
+ font-size: 14px;
40
+ line-height: 1.5;
41
+ }
42
+ .ad-slot {
43
+ margin: 20px 0;
44
+ border: 1px dashed #ccc;
45
+ padding: 10px;
46
+ background: #fafafa;
47
+ }
48
+ .ad-slot-title {
49
+ font-size: 12px;
50
+ color: #999;
51
+ margin-bottom: 10px;
52
+ }
53
+ .note {
54
+ background: #fff3cd;
55
+ border: 1px solid #ffc107;
56
+ border-left: 4px solid #ffc107;
57
+ padding: 15px;
58
+ margin: 15px 0;
59
+ border-radius: 4px;
60
+ }
61
+ .note strong {
62
+ color: #856404;
63
+ }
64
+ </style>
65
+ </head>
66
+ <body>
67
+ <div class="container">
68
+ <h1>🚀 趣变广告 SDK - WordPress 即插即用模式</h1>
69
+
70
+ <div class="note">
71
+ <strong>使用说明:</strong> 这是专门为 WordPress 等建站平台设计的傻瓜式接入方式。只需要复制粘贴代码即可,无需任何技术背景。
72
+ <br><br>
73
+ <strong>⚠️ 当前状态:</strong> 此功能还未发布到 npm,请使用本地文件进行测试(已配置为本地测试模式)。
74
+ </div>
75
+
76
+ <h2>📝 接入步骤</h2>
77
+ <ol>
78
+ <li>在需要展示广告的位置插入以下 HTML 代码:</li>
79
+ </ol>
80
+
81
+ <div class="code-block">
82
+ &lt;ins class="qb-adsbyqubian"
83
+ style="display:block; width:400px; height:220px;"
84
+ data-app-id="1999336062823956569"
85
+ data-placement-id="1999381081819709520"&gt;
86
+ &lt;/ins&gt;
87
+ &lt;script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js" async&gt;&lt;/script&gt;
88
+ &lt;script&gt;(window.qbAds = window.qbAds || []).push({});&lt;/script&gt;
89
+ </div>
90
+
91
+ <h2>✨ 示例:多个广告位</h2>
92
+
93
+ <div class="ad-slot">
94
+ <div class="ad-slot-title">📌 广告位 1:横幅广告 (728x90)</div>
95
+ <ins class="qb-adsbyqubian"
96
+ style="display:block; width:728px; height:90px; margin:0 auto;"
97
+ data-app-id="2004088976381599817"
98
+ data-placement-id="2004089182414200847">
99
+ </ins>
100
+ </div>
101
+
102
+ <div class="ad-slot">
103
+ <div class="ad-slot-title">📌 广告位 2:中等尺寸 (400x220)</div>
104
+ <ins class="qb-adsbyqubian"
105
+ style="display:block; width:400px; height:220px; margin:0 auto;"
106
+ data-app-id="2004088976381599817"
107
+ data-placement-id="2004089182414200847">
108
+ </ins>
109
+ </div>
110
+
111
+ <div class="ad-slot">
112
+ <div class="ad-slot-title">📌 广告位 3:窄条横幅 (780x60)</div>
113
+ <ins class="qb-adsbyqubian"
114
+ style="display:block; width:780px; height:60px; margin:0 auto;"
115
+ data-app-id="2004088976381599817"
116
+ data-placement-id="2004089182414200847">
117
+ </ins>
118
+ </div>
119
+
120
+ <div class="ad-slot">
121
+ <div class="ad-slot-title">📌 广告位 4:小尺寸 (300x250)</div>
122
+ <ins class="qb-adsbyqubian"
123
+ style="display:block; width:300px; height:250px; margin:0 auto;"
124
+ data-app-id="2004088976381599817"
125
+ data-placement-id="2004089182414200847">
126
+ </ins>
127
+ </div>
128
+
129
+ <h2>📋 参数说明</h2>
130
+ <ul>
131
+ <li><strong>class="qb-adsbyqubian"</strong>:必需的类名,用于标识广告位</li>
132
+ <li><strong>data-app-id</strong>:您的应用 ID(必填)</li>
133
+ <li><strong>data-placement-id</strong>:广告位 ID(必填)</li>
134
+ <li><strong>style</strong>:设置广告位尺寸,建议设置 width 和 height</li>
135
+ </ul>
136
+
137
+ <h2>💡 可选回调配置(高级用法)</h2>
138
+ <p>如果需要监听广告加载、点击等事件,可以在 push 中传入回调函数:</p>
139
+
140
+ <div class="code-block">
141
+ &lt;script&gt;
142
+ (window.qbAds = window.qbAds || []).push({
143
+ onAdLoaded: function(ad, instance, element) {
144
+ console.log('✅ 广告加载成功', element);
145
+ },
146
+ onAdError: function(err, msg, element) {
147
+ console.log('❌ 广告加载失败', err, element);
148
+ },
149
+ onAdExpose: function(element) {
150
+ console.log('👀 广告曝光', element);
151
+ },
152
+ onAdClick: function(element) {
153
+ console.log('🖱️ 广告被点击', element);
154
+ }
155
+ });
156
+ &lt;/script&gt;
157
+ </div>
158
+
159
+ <h2>✅ 本地测试验证步骤</h2>
160
+ <ol>
161
+ <li><strong>打开文件:</strong> 直接用浏览器打开此 HTML 文件,或使用本地服务器(推荐)</li>
162
+ <li><strong>打开控制台:</strong> 按 F12 或右键 → 检查 → Console</li>
163
+ <li><strong>查看日志:</strong> 应该能看到以下调试信息:
164
+ <ul>
165
+ <li>🔍 [测试模式] 开始初始化广告...</li>
166
+ <li>🔍 [测试模式] window.GDTAdSDK: ✅ 已加载</li>
167
+ <li>🔍 [测试模式] window.AdSDK: ✅ 已加载</li>
168
+ <li>🔍 [测试模式] 找到的广告位数量: 4</li>
169
+ <li>[AdSDK] 容器尺寸检测: {...}</li>
170
+ <li>✅ [测试模式] 广告加载成功</li>
171
+ </ul>
172
+ </li>
173
+ <li><strong>检查页面:</strong> 应该能看到 4 个广告位,每个都显示了广告内容</li>
174
+ <li><strong>验证布局:</strong>
175
+ <ul>
176
+ <li>横幅广告(728x90)应该是横向布局(图片在左,文字在右)</li>
177
+ <li>窄条横幅(780x60)应该是横向布局,内容更紧凑</li>
178
+ <li>中等尺寸(400x220)和小尺寸(300x250)应该是纵向布局</li>
179
+ </ul>
180
+ </li>
181
+ </ol>
182
+
183
+ <div class="note">
184
+ <strong>💡 使用本地服务器(推荐):</strong>
185
+ <br>在项目根目录运行:<code>python -m http.server 8000</code> 或 <code>http-server -p 8000</code>
186
+ <br>然后访问:<code>http://localhost:8000/src/example-wordpress.html</code>
187
+ </div>
188
+
189
+ <h2>⚠️ 注意事项</h2>
190
+ <ul>
191
+ <li><strong>当前状态:</strong> 代码还未发布到 npm,请使用本地文件测试(已配置为本地模式)</li>
192
+ <li><strong>发布后:</strong> 代码发布到 npm 后,可以切换为 CDN 方式(取消注释方式1,注释掉方式2)</li>
193
+ <li>确保 <code>data-app-id</code> 和 <code>data-placement-id</code> 正确填写</li>
194
+ <li>建议为每个广告位设置合适的 <code>width</code> 和 <code>height</code></li>
195
+ <li>脚本标签中的 <code>async</code> 属性可以加快页面加载速度</li>
196
+ <li>支持在一个页面中插入多个广告位</li>
197
+ <li>广告会自动适配容器尺寸,支持横幅、中等尺寸、小尺寸等不同布局</li>
198
+ </ul>
199
+ </div>
200
+
201
+ <!-- ============================================================ -->
202
+ <!-- ⚠️ 重要提示:代码还未发布到 npm,请使用本地测试方式 -->
203
+ <!-- 文件要求:确保 ad-sdk-wrapper.js 与此 HTML 文件在同一目录下 -->
204
+ <!-- ============================================================ -->
205
+
206
+ <!-- 方式1:使用 CDN(生产环境推荐,代码发布到 npm 后使用) -->
207
+ <!--
208
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-sdk@latest/qb-pc-sdk.js" async></script>
209
+ -->
210
+
211
+ <!-- 方式2:本地测试(开发环境,当前使用此方式) -->
212
+ <!-- 先引入底层 SDK(从 CDN 加载,因为底层 SDK 已发布到 npm) -->
213
+ <!-- 使用 jsdelivr CDN(国内访问更快更稳定) -->
214
+ <script src="https://cdn.jsdelivr.net/npm/qb-pc-ad-sdk-origin@latest/dist/qb-pc-ad-sdk.v1.0.0.js"></script>
215
+ <!-- 再引入封装 SDK(使用本地文件,包含最新的即插即用模式) -->
216
+ <!-- 注意:ad-sdk-wrapper.js 必须与此 HTML 文件在同一目录(src/)下 -->
217
+ <script src="ad-sdk-wrapper.js"></script>
218
+
219
+ <!-- 触发广告初始化(每个广告位都需要调用一次 push,或放在最后一个广告位之后统一调用) -->
220
+ <script>
221
+ // 添加调试信息,方便排查问题
222
+ console.log('🔍 [测试模式] 开始初始化广告...');
223
+ console.log('🔍 [测试模式] window.GDTAdSDK:', typeof window.GDTAdSDK !== 'undefined' ? '✅ 已加载' : '❌ 未加载');
224
+ console.log('🔍 [测试模式] window.AdSDK:', typeof window.AdSDK !== 'undefined' ? '✅ 已加载' : '❌ 未加载');
225
+ console.log('🔍 [测试模式] 找到的广告位数量:', document.querySelectorAll('ins.qb-adsbyqubian').length);
226
+
227
+ // 监听 SDK 就绪事件
228
+ window.addEventListener('qb-pc-sdk-ready', function() {
229
+ console.log('✅ [测试模式] SDK 就绪事件已触发');
230
+ });
231
+
232
+ // 如果 SDK 已经加载,立即初始化;否则等待
233
+ function initAds() {
234
+ if (window.AdSDK && window.GDTAdSDK) {
235
+ console.log('✅ [测试模式] SDK 已加载,开始初始化广告位');
236
+ (window.qbAds = window.qbAds || []).push({
237
+ onAdLoaded: function(ad, instance, element) {
238
+ console.log('✅ [测试模式] 广告加载成功', {
239
+ element: element,
240
+ hasAd: !!ad,
241
+ hasInstance: !!instance
242
+ });
243
+ },
244
+ onAdError: function(err, msg, element) {
245
+ console.error('❌ [测试模式] 广告加载失败', {
246
+ error: err,
247
+ message: msg,
248
+ element: element
249
+ });
250
+ },
251
+ onAdExpose: function(element) {
252
+ console.log('👀 [测试模式] 广告曝光', element);
253
+ },
254
+ onAdClick: function(element) {
255
+ console.log('🖱️ [测试模式] 广告被点击', element);
256
+ }
257
+ });
258
+ } else {
259
+ console.warn('⚠️ [测试模式] SDK 尚未加载完成,等待中...');
260
+ // 如果 SDK 还未加载,等待最多 10 秒
261
+ setTimeout(function() {
262
+ if (window.AdSDK && window.GDTAdSDK) {
263
+ initAds();
264
+ } else {
265
+ console.error('❌ [测试模式] SDK 加载超时,请检查:');
266
+ console.error(' 1. 网络连接是否正常');
267
+ console.error(' 2. CDN 是否能正常访问');
268
+ console.error(' 3. 控制台是否有其他错误信息');
269
+ }
270
+ }, 100);
271
+ }
272
+ }
273
+
274
+ // DOM 加载完成后尝试初始化
275
+ if (document.readyState === 'loading') {
276
+ document.addEventListener('DOMContentLoaded', function() {
277
+ setTimeout(initAds, 100);
278
+ });
279
+ } else {
280
+ setTimeout(initAds, 100);
281
+ }
282
+
283
+ // 监听 SDK 就绪事件(备用方案)
284
+ window.addEventListener('qb-pc-sdk-ready', function() {
285
+ setTimeout(initAds, 100);
286
+ });
287
+ </script>
288
+ </body>
289
+ </html>
290
+