qb-pc-sdk 1.0.9 → 1.1.0
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 +60 -0
- package/package.json +2 -2
- package/src/ad-sdk-wrapper.js +72 -0
- package/src/example-simple.html +5 -1
package/README.md
CHANGED
|
@@ -139,8 +139,33 @@ new AdSDK(config)
|
|
|
139
139
|
- `onAdExpose` (function, 可选): 广告曝光回调
|
|
140
140
|
- `onAdClick` (function, 可选): 广告点击回调
|
|
141
141
|
|
|
142
|
+
### 实例方法
|
|
143
|
+
|
|
144
|
+
#### destroy()
|
|
145
|
+
|
|
146
|
+
销毁广告实例,清理 DOM、解绑事件、释放资源。
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const adSDK = new AdSDK({
|
|
150
|
+
appId: 'your-app-id',
|
|
151
|
+
placementId: 'your-placement-id',
|
|
152
|
+
container: '#ad-container'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// 销毁广告
|
|
156
|
+
adSDK.destroy();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**说明**:
|
|
160
|
+
- 调用后会清空广告容器内容
|
|
161
|
+
- 会调用底层 SDK 的 `destroy()` 方法释放资源
|
|
162
|
+
- 广告会自动显示关闭按钮(右上角 ×),点击即可关闭
|
|
163
|
+
- 也可以手动调用 `destroy()` 方法销毁广告
|
|
164
|
+
|
|
142
165
|
### 示例
|
|
143
166
|
|
|
167
|
+
#### 基本使用
|
|
168
|
+
|
|
144
169
|
```javascript
|
|
145
170
|
const AdSDK = require('qb-pc-sdk');
|
|
146
171
|
|
|
@@ -163,6 +188,41 @@ const adSDK = new AdSDK({
|
|
|
163
188
|
});
|
|
164
189
|
```
|
|
165
190
|
|
|
191
|
+
#### 销毁广告示例
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
const adSDK = new AdSDK({
|
|
195
|
+
appId: 'your-app-id',
|
|
196
|
+
placementId: 'your-placement-id',
|
|
197
|
+
container: '#ad-container'
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// 方式1:点击广告右上角的关闭按钮(自动销毁)
|
|
201
|
+
// 广告渲染时会自动显示关闭按钮
|
|
202
|
+
|
|
203
|
+
// 方式2:手动调用 destroy 方法
|
|
204
|
+
document.getElementById('close-ad-btn').addEventListener('click', () => {
|
|
205
|
+
adSDK.destroy();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// 方式3:在组件销毁时调用(Vue/React)
|
|
209
|
+
// Vue
|
|
210
|
+
onBeforeUnmount(() => {
|
|
211
|
+
if (adSDK) {
|
|
212
|
+
adSDK.destroy();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// React
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
return () => {
|
|
219
|
+
if (adSDK) {
|
|
220
|
+
adSDK.destroy();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}, []);
|
|
224
|
+
```
|
|
225
|
+
|
|
166
226
|
## 依赖
|
|
167
227
|
|
|
168
228
|
- `qb-pc-ad-sdk-origin`: 底层广告 SDK(已自动在浏览器环境加载)
|
package/package.json
CHANGED
package/src/ad-sdk-wrapper.js
CHANGED
|
@@ -300,6 +300,10 @@
|
|
|
300
300
|
.q-ad-desc { font-size: 12px; color: #666; margin: 0 0 10px 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
301
301
|
.q-cta-btn { background: #007bff; color: #fff; border: none; padding: 6px 15px; border-radius: 4px; font-size: 12px; cursor: pointer; align-self: flex-start; }
|
|
302
302
|
.q-ad-tag { position: absolute; right: 5px; bottom: 5px; background: rgba(0,0,0,0.3); color: #fff; font-size: 10px; padding: 2px 4px; border-radius: 2px; }
|
|
303
|
+
.q-ad-close { position: absolute; top: 5px; right: 5px; width: 24px; height: 24px; 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: 16px; line-height: 1; z-index: 10; transition: background 0.2s; }
|
|
304
|
+
.q-ad-close:hover { background: rgba(0,0,0,0.7); }
|
|
305
|
+
.q-ad-close:active { background: rgba(0,0,0,0.9); }
|
|
306
|
+
.q-ad-destroyed { display: none !important; }
|
|
303
307
|
`;
|
|
304
308
|
|
|
305
309
|
class AdSDKWrapper {
|
|
@@ -316,6 +320,9 @@
|
|
|
316
320
|
this.gdtPlacementId = null;
|
|
317
321
|
this.currentAd = null;
|
|
318
322
|
|
|
323
|
+
// 检测移动端环境并提示
|
|
324
|
+
this._checkMobileEnvironment();
|
|
325
|
+
|
|
319
326
|
this._injectStyles();
|
|
320
327
|
|
|
321
328
|
this.container = typeof this.config.container === 'string'
|
|
@@ -329,6 +336,27 @@
|
|
|
329
336
|
}
|
|
330
337
|
}
|
|
331
338
|
|
|
339
|
+
// 检测移动端环境
|
|
340
|
+
_checkMobileEnvironment() {
|
|
341
|
+
if (typeof window !== 'undefined' && window.navigator) {
|
|
342
|
+
const userAgent = window.navigator.userAgent || '';
|
|
343
|
+
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
|
344
|
+
|
|
345
|
+
if (isMobile) {
|
|
346
|
+
console.warn('[AdSDK] ⚠️ 检测到移动端环境,这是 PC 端 SDK,可能在移动端无法正常工作。建议使用移动端专用 SDK。');
|
|
347
|
+
if (this.config.onAdError) {
|
|
348
|
+
// 不立即触发错误,让用户决定是否继续
|
|
349
|
+
setTimeout(() => {
|
|
350
|
+
this.config.onAdError(
|
|
351
|
+
new Error('移动端环境警告'),
|
|
352
|
+
'这是 PC 端 SDK,移动端可能无法正常加载广告'
|
|
353
|
+
);
|
|
354
|
+
}, 100);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
332
360
|
// 注入默认 CSS
|
|
333
361
|
_injectStyles() {
|
|
334
362
|
if (!document.getElementById('q-ad-styles')) {
|
|
@@ -513,6 +541,7 @@
|
|
|
513
541
|
// 构建 HTML 结构
|
|
514
542
|
this.container.innerHTML = `
|
|
515
543
|
<div class="q-ad-wrapper">
|
|
544
|
+
<button class="q-ad-close" title="关闭广告">×</button>
|
|
516
545
|
<div class="q-media-container">
|
|
517
546
|
<div class="q-ad-video" style="display:none"></div>
|
|
518
547
|
<img class="q-ad-img" style="display:none">
|
|
@@ -526,6 +555,15 @@
|
|
|
526
555
|
</div>
|
|
527
556
|
`;
|
|
528
557
|
|
|
558
|
+
// 绑定关闭按钮事件
|
|
559
|
+
const closeBtn = this.container.querySelector('.q-ad-close');
|
|
560
|
+
if (closeBtn) {
|
|
561
|
+
closeBtn.addEventListener('click', (e) => {
|
|
562
|
+
e.stopPropagation(); // 阻止事件冒泡,避免触发广告点击
|
|
563
|
+
this.destroy();
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
529
567
|
const videoEl = this.container.querySelector('.q-ad-video');
|
|
530
568
|
const imgEl = this.container.querySelector('.q-ad-img');
|
|
531
569
|
const wrapper = this.container.querySelector('.q-ad-wrapper');
|
|
@@ -565,6 +603,40 @@
|
|
|
565
603
|
if (this.config.onAdLoaded) this.config.onAdLoaded(ad);
|
|
566
604
|
}
|
|
567
605
|
|
|
606
|
+
/**
|
|
607
|
+
* 销毁广告实例
|
|
608
|
+
* 清理 DOM、解绑事件、释放资源,并隐藏容器元素
|
|
609
|
+
*/
|
|
610
|
+
destroy() {
|
|
611
|
+
try {
|
|
612
|
+
// 1. 销毁底层广告实例
|
|
613
|
+
if (this.currentAd && typeof this.currentAd.destroy === 'function') {
|
|
614
|
+
this.currentAd.destroy();
|
|
615
|
+
this.currentAd = null;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// 2. 清空容器内容
|
|
619
|
+
if (this.container) {
|
|
620
|
+
this.container.innerHTML = '';
|
|
621
|
+
// 3. 隐藏容器元素
|
|
622
|
+
if (this.container.style) {
|
|
623
|
+
this.container.style.display = 'none';
|
|
624
|
+
} else {
|
|
625
|
+
// 如果 style 不可用,使用 class
|
|
626
|
+
this.container.classList.add('q-ad-destroyed');
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// 4. 清理引用
|
|
631
|
+
this.gdtAppId = null;
|
|
632
|
+
this.gdtPlacementId = null;
|
|
633
|
+
|
|
634
|
+
console.log('[AdSDK] 广告已销毁');
|
|
635
|
+
} catch (err) {
|
|
636
|
+
console.error('[AdSDK] 销毁广告时出错:', err);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
568
640
|
_handleError(error, message) {
|
|
569
641
|
// 内部错误也进行过滤,防止将过滤掉的错误再次打印
|
|
570
642
|
const errStr = String(error).toLowerCase();
|
package/src/example-simple.html
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
console.log('✅ 封装 SDK 加载成功');
|
|
39
39
|
|
|
40
40
|
// 初始化广告
|
|
41
|
-
new window.AdSDK({
|
|
41
|
+
const adSDK = new window.AdSDK({
|
|
42
42
|
appId: '1999364640831725629',
|
|
43
43
|
placementId: '2003009002186760245',
|
|
44
44
|
container: '#ad-slot-1',
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
onAdExpose: () => console.log('👀 广告曝光'),
|
|
48
48
|
onAdClick: () => console.log('🖱️ 用户点击了广告')
|
|
49
49
|
});
|
|
50
|
+
|
|
51
|
+
// 示例:可以通过 destroy 方法销毁广告
|
|
52
|
+
// 广告右上角会自动显示关闭按钮,点击即可关闭
|
|
53
|
+
// 也可以手动调用:adSDK.destroy();
|
|
50
54
|
});
|
|
51
55
|
</script>
|
|
52
56
|
</body>
|