@@ -6,10 +6,20 @@
用法:
var P = MBCmPics.picker({ strip: 放缩略图的元素, onChange: fn })
P.pick() 打开相册 · P.urls() 已传好的地址 · P.busy() 还有没传完的 · P.count() 已选张数 · P.clear() 清空
MBCmPics.html(images) → 评论里那排图的 HTML( 没有图返回 '') */
MBCmPics.html(images) → 评论里那排图的 HTML( 没有图返回 '')
11-05 兜爸心选宝妈表情包(「妈妈盒子 / 表情包」会话 ee1ae406 做的 10 张, assets/img/<md5 前 12>.webp, 240px) :
· 输入框里加笑脸按钮,点开 5× 2 面板选一张(每条一张,再点别的就换),和文字 / 图片一起发;
· 存法:文字末尾带 [兜表情:收到~] 这样的记号(后端不用改,后台审核里也看得懂是哪张);
· 显示: MBCmPics.txt(文字) 代替 esc(文字) —— 记号换成表情图,不认识的记号原样当文字。
P.emoji() 当前选的表情记号(没选 = '') ; P.toggleEmo() 开关面板。 */
( function ( ) {
if ( window . MBCmPics ) return ;
var MAX = 3 ;
var ME _SRC = document . currentScript ? document . currentScript . src : location . href ;
var EMO = [ [ "收到~" , "e2f8d1f15db3" ] , [ "嘘,娃刚睡" , "52c77092e7ce" ] , [ "求链接!" , "865e4ae61d08" ] , [ "抱抱你" , "7f19e4c30dd6" ] , [ "带娃好累…" , "e89ae2a04626" ] , [ "我也是!" , "57a4273dd024" ] , [ "已下单 ✓" , "e8808f01ec7b" ] , [ "谢谢姐妹" , "a2c15d7bf5a8" ] , [ "哈哈哈哈" , "26a8bdcafbb7" ] , [ "宝妈加油!" , "23459742b18f" ] ] ;
var EMO _DIR = new URL ( '../assets/img/' , ME _SRC ) . href , EMO _BY = { } ;
EMO . forEach ( function ( e ) { EMO _BY [ e [ 0 ] ] = e [ 1 ] ; } ) ;
var emoSrc = function ( h ) { return EMO _DIR + h + '.webp' ; } ;
var st = document . createElement ( 'style' ) ;
st . textContent =
'.cmp-strip{display:flex;gap:8px;padding:8px 2px 2px;overflow-x:auto}.cmp-strip:empty{display:none}' +
@@ -24,9 +34,17 @@
'.cmp-btn svg{width:21px;height:21px}' +
'.cmp-btn.on{color:#F4593C}' +
'.cmp-lb{position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.92)}' +
'.cmp-lb img{max-width:100%;max-height:100%;object-fit:contain}' ;
'.cmp-lb img{max-width:100%;max-height:100%;object-fit:contain}' +
'.cmp-emo{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;padding:10px 12px 8px;background:#fff;border-top:1px solid #EEE6E2}' +
'.cmp-emo[hidden]{display:none}' +
'.cmp-emo button{display:block;padding:2px;border:0;border-radius:10px;background:#FBF6F3;aspect-ratio:1}' +
'.cmp-emo button.on{box-shadow:inset 0 0 0 2px #F4593C}' +
'.cmp-emo img{display:block;width:100%;height:100%;object-fit:contain}' +
'.cmp-t.emo{background:#FBF6F3}.cmp-t.emo img{object-fit:contain}' +
'.cmp-sk{display:block;width:96px;height:96px;margin-top:6px;object-fit:contain}' ;
( document . head || document . documentElement ) . appendChild ( st ) ;
var EMO _ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><path d="M8.5 14.5c.9 1.3 2.1 2 3.5 2s2.6-.7 3.5-2"/><circle cx="9" cy="10" r=".6" fill="currentColor"/><circle cx="15" cy="10" r=".6" fill="currentColor"/></svg>' ;
var ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="15" rx="3"/><circle cx="9" cy="10.5" r="1.8"/><path d="M21 16l-5-5-8 8"/></svg>' ;
var esc = function ( s ) { return String ( s ) . replace ( /[&<>"']/g , function ( c ) { return { '&' : '&' , '<' : '<' , '>' : '>' , '"' : '"' , "'" : ''' } [ c ] ; } ) ; } ;
@@ -45,7 +63,26 @@
}
function picker ( o ) {
var pics = [ ] , ups = 0 , strip = o . strip ;
var pics = [ ] , ups = 0 , strip = o . strip , emo = '' , emoEl = null , panel = null ;
function setEmo ( n ) {
emo = n || '' ;
if ( emoEl ) { emoEl . remove ( ) ; emoEl = null ; }
if ( emo ) {
emoEl = document . createElement ( 'span' ) ; emoEl . className = 'cmp-t emo' ;
emoEl . innerHTML = '<img alt="" src="' + emoSrc ( EMO _BY [ emo ] ) + '"><button type="button" aria-label="去掉表情">× </button>' ;
emoEl . querySelector ( 'button' ) . addEventListener ( 'mousedown' , function ( e ) { e . preventDefault ( ) ; } ) ;
emoEl . querySelector ( 'button' ) . onclick = function ( ) { setEmo ( '' ) ; } ;
strip . insertBefore ( emoEl , strip . firstChild ) ;
}
if ( panel ) [ ] . forEach . call ( panel . children , function ( b ) { b . classList . toggle ( 'on' , b . dataset . n === emo ) ; } ) ;
ch ( ) ;
}
if ( o . emoPanel ) {
panel = o . emoPanel ; panel . className = 'cmp-emo' ; panel . hidden = true ;
panel . innerHTML = EMO . map ( function ( e ) { return '<button type="button" data-n="' + esc ( e [ 0 ] ) + '" aria-label="' + esc ( e [ 0 ] ) + '"><img alt="" src="' + emoSrc ( e [ 1 ] ) + '" loading="lazy"></button>' ; } ) . join ( '' ) ;
panel . addEventListener ( 'mousedown' , function ( e ) { e . preventDefault ( ) ; } ) ;
panel . addEventListener ( 'click' , function ( e ) { var b = e . target . closest ( '[data-n]' ) ; if ( ! b ) return ; setEmo ( b . dataset . n === emo ? '' : b . dataset . n ) ; panel . hidden = true ; ch ( ) ; } ) ;
}
var fi = document . createElement ( 'input' ) ; fi . type = 'file' ; fi . accept = 'image/*' ; fi . multiple = true ; fi . hidden = true ;
document . body . appendChild ( fi ) ;
var ch = function ( ) { if ( o . onChange ) o . onChange ( ) ; } ;
@@ -71,8 +108,12 @@
pick : function ( ) { if ( pics . length >= MAX ) { if ( o . toast ) o . toast ( '每条最多带 ' + MAX + ' 张图' ) ; return ; } fi . click ( ) ; } ,
urls : function ( ) { return pics . map ( function ( x ) { return x . url ; } ) . filter ( Boolean ) ; } ,
busy : function ( ) { return ups > 0 ; } ,
count : function ( ) { return pics . length ; } ,
clear : function ( ) { pics = [ ] ; strip . innerHTML = '' ; ch ( ) ; }
count : function ( ) { return pics . length + ( emo ? 1 : 0 ) ; } ,
clear : function ( ) { pics = [ ] ; emo = '' ; emoEl = null ; strip . innerHTML = '' ; if ( panel ) panel . hidden = true ; ch ( ) ; } ,
emoji : function ( ) { return emo ? '[兜表情:' + emo + ']' : '' ; } ,
hasEmo : function ( ) { return ! ! emo ; } ,
toggleEmo : function ( ) { if ( panel ) { panel . hidden = ! panel . hidden ; ch ( ) ; } } ,
emoOpen : function ( ) { return ! ! ( panel && ! panel . hidden ) ; }
} ;
}
@@ -92,5 +133,16 @@
document . body . appendChild ( lb ) ;
} , true ) ;
window . MBCmPics = { picker : picker , html : html , ICON : ICON , MAX : MAX } ;
/* 评论文字 → HTML: 转义 + 把 [兜表情:xx] 换成表情图(每条只认第一个,其余去掉) */
function txt ( t ) {
var sk = '' , out = esc ( t || '' ) . replace ( /\[兜表情:([^\]]{1,12})\]/g , function ( m , n ) {
var h = EMO _BY [ n ] || EMO _BY [ n . replace ( /\s+/g , ' ' ) ] ;
if ( ! h ) return m ;
if ( ! sk ) sk = '<img class="cmp-sk" alt="' + esc ( n ) + '" src="' + emoSrc ( h ) + '">' ;
return '' ;
} ) . trim ( ) ;
return out + sk ;
}
window . MBCmPics = { picker : picker , html : html , txt : txt , ICON : ICON , EMO _ICON : EMO _ICON , MAX : MAX } ;
} ) ( ) ;