@@ -40,14 +40,20 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
. nav h1 span { background : linear-gradient ( transparent 60 % , #FFD0DC 60 % , #FFD0DC 92 % , transparent 92 % ) ; padding : 0 3 px }
. nav h1 span { background : linear-gradient ( transparent 60 % , #FFD0DC 60 % , #FFD0DC 92 % , transparent 92 % ) ; padding : 0 3 px }
. nav . sp { width : 36 px }
. nav . sp { width : 36 px }
/* ---------- 一级分类:分段按钮 ( 11-01 第三 版:用户说「经验 / 家庭不够明显、有点乱」→ 一条底槽三段,选中段实底 ) ---------- */
/* ---------- 一级分类( 11-02 第四 版:用户「去掉图标、滑块缺设计感」→ 小红书式文字标签:选中字放大加粗 + 底下一条会滑动的分类色胶囊;左右滑页面也能切 ) ---------- */
. cats { display : flex ; gap : 4 px ; margin : 2 px 12 px 10 px ; padding : 4 px ; border-radius : 16 px ; background : #F0E4DE }
. cats { position : relative ; display: flex ; gap : 8 px ; margin : 0 6 px ; padding : 2 px 0 10 px }
. cats button { flex : 1 ; min-width : 0 ; height : 38 px ; display : flex ; align-items : center ; justify-content : center ; gap : 3px ; border-radius : 1 2px ;
. cats button { position : relative ; z-index : 1 ; flex : none ; padding : 6 px 12 px 4 px ; font-size : 15.5 px ; font-weight : 700 ; color : #A08B85 ; letter-spacing : . 3px ; line-height : 24 px ; transition : color .25 s }
font-size : 14.5 px ; font-weight : 800 ; color : #8A7570 ; letter-spacing : .3 px ; transition : background .18 s , color .18 s , box-shadow .18 s }
. cats button . ic { display : none }
. cats button . ic { width : 15 px ; h eight: 15 px ; color : var ( - - cf ) }
. cats button . on { font-size : 18 px ; font-w eight: 900 ; color : #2A1E1E }
. cats button . on { background : var ( - - cf ) ; color : #fff ; box-shadow : 0 6 px 14 px -6 px var ( - - cf ) }
. cats button i { position : absolute ; left : calc ( 100 % - 12 px ) ; top : 2 px ; font-style : normal ; font-size : 1 0px ; font-weight : 800 ; line-height : 12 px ; color : var ( - - cf ) ; opacity : 0 ; transition : opacity .25 s }
. cats button . on . ic { color : #fff }
. cats button . on i { opacity : 1 }
. cats button : active { transform : scale ( .97 ) }
. cats . bar { position : absolute ; z-index : 0 ; left : 0 ; bottom : 12 px ; height : 7 px ; width : 28 px ; border-radius : 7 px ; background : var ( - - cbar , #F4593C ) ; opacity : .32 ;
transition : transform .32 s cubic-bezier ( .3 , 1.3 , .5 , 1 ) , width .32 s cubic-bezier ( .3 , 1.3 , .5 , 1 ) , background .25 s ; pointer-events : none }
. cats :: after { content : "" ; position : absolute ; left : 6 px ; right : 6 px ; bottom : 0 ; height : 1 px ; background : linear-gradient ( 90 deg , transparent , #EADAD3 20 % , #EADAD3 80 % , transparent ) }
. cats button : active { transform : scale ( .96 ) }
. wf . swl { animation : swl .32 s ease-out } . wf . swr { animation : swr .32 s ease-out }
@ keyframes swl { from { opacity : .2 ; transform : translateX ( 36 px ) } to { opacity : 1 ; transform : none } }
@ keyframes swr { from { opacity : .2 ; transform : translateX ( -36 px ) } to { opacity : 1 ; transform : none } }
. cats . c-all { --cf : #F4593C }
. cats . c-all { --cf : #F4593C }
/* 四块分类色( 11-01 第四版:按用户选题清单分 家庭 / 婚姻 / 职场 / 母婴) : kf 实色 · kt 深字 · kl/kl2 浅底两色 */
/* 四块分类色( 11-01 第四版:按用户选题清单分 家庭 / 婚姻 / 职场 / 母婴) : kf 实色 · kt 深字 · kl/kl2 浅底两色 */
. k-family , . c-family { --kf : #E0566F ; --kt : #C23A55 ; --kl : #FFF0F3 ; --kl2 : #FFD9E0 }
. k-family , . c-family { --kf : #E0566F ; --kt : #C23A55 ; --kl : #FFF0F3 ; --kl2 : #FFD9E0 }
@@ -450,9 +456,9 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
< div id = "sheet" role = "dialog" aria-modal = "true" > < i class = "sg" > < / i > < div class = "sbd" id = "sbd" > < / div > < / div >
< div id = "sheet" role = "dialog" aria-modal = "true" > < i class = "sg" > < / i > < div class = "sbd" id = "sbd" > < / div > < / div >
< div class = "toast" id = "toast" > < / div >
< div class = "toast" id = "toast" > < / div >
< script src = "topics.js?v=26110211 " > < / script >
< script src = "topics.js?v=26110212 " > < / script >
< script src = "data.js?v=26110211 " > < / script >
< script src = "data.js?v=26110212 " > < / script >
< script src = "feed.js?v=26110211 " > < / script >
< script src = "feed.js?v=26110212 " > < / script >
< script >
< script >
( function ( ) {
( function ( ) {
'use strict' ;
'use strict' ;
@@ -589,11 +595,26 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
/* 投稿奖励( 11-01 用户定):话题投稿被选中 → 30 元现金 + 500 兜豆 */
/* 投稿奖励( 11-01 用户定):话题投稿被选中 → 30 元现金 + 500 兜豆 */
var REWARD = '<em>¥30</em> 现金 + <em>500</em> 兜豆' ;
var REWARD = '<em>¥30</em> 现金 + <em>500</em> 兜豆' ;
function renderCats ( ) {
function renderCats ( ) {
var bs = $ ( '#cats' ) . querySelectorAll ( 'button[data-c]' ) ;
if ( bs . length ) { /* 已画过:只换选中态,胶囊才能滑过去 */
[ ] . forEach . call ( bs , function ( b ) { var on = b . dataset . c === catF ; b . classList . toggle ( 'on' , on ) ; b . setAttribute ( 'aria-selected' , on ) ; } ) ;
moveBar ( ) ; return ;
}
$ ( '#cats' ) . innerHTML = CATS . map ( function ( x ) {
$ ( '#cats' ) . innerHTML = CATS . map ( function ( x ) {
return '<button type="button" role="tab" data-c="' + x [ 0 ] + '" class="c-' + ( x [ 0 ] || 'all' ) + ( catF === x [ 0 ] ? ' on' : '' ) + '" aria-selected="' + ( catF === x [ 0 ] ) + '">' +
return '<button type="button" role="tab" data-c="' + x [ 0 ] + '" class="c-' + ( x [ 0 ] || 'all' ) + ( catF === x [ 0 ] ? ' on' : '' ) + '" aria-selected="' + ( catF === x [ 0 ] ) + '">' +
'<svg class="ic"><use href="#' + x [ 2 ] + '"/></svg >' + x [ 1 ] + '</button>' ;
x [ 1 ] + '<i >' + catCnt ( x[ 0 ] ) + '</i></ button>' ;
} ) . join ( '' ) ;
} ) . join ( '' ) + '<span class="bar"></span>' ;
moveBar ( ) ;
}
}
function catCnt ( c ) { return NOTES . filter ( function ( n ) { return ! c || TBY [ n . t ] . cat === c ; } ) . length ; }
/* 胶囊挪到选中标签文字下方,宽度跟文字走(取文字宽的一半,偏小红书) */
function moveBar ( ) {
var on = $ ( '#cats .on' ) , bar = $ ( '#cats .bar' ) ; if ( ! on || ! bar ) return ;
var w = on . offsetWidth - 20 , x = on . offsetLeft + ( on . offsetWidth - w ) / 2 ;
bar . style . width = w + 'px' ; bar . style . transform = 'translateX(' + x + 'px)' ;
bar . style . background = getComputedStyle ( on ) . getPropertyValue ( '--cf' ) ;
}
window . addEventListener ( 'resize' , moveBar ) ;
function rewardHTML ( sm ) {
function rewardHTML ( sm ) {
return '<button type="button" class="rw' + ( sm ? ' sm' : '' ) + '" data-rule="1"><span class="gf"><svg class="ic"><use href="#i-gift"/></svg></span>' +
return '<button type="button" class="rw' + ( sm ? ' sm' : '' ) + '" data-rule="1"><span class="gf"><svg class="ic"><use href="#i-gift"/></svg></span>' +
'<span class="rt"><small>参与话题投稿 · 被选中奖励</small><b>' + REWARD + '</b></span><span class="go">怎么参与<svg class="ic" style="width:12px;height:12px"><use href="#i-right"/></svg></span></button>' ;
'<span class="rt"><small>参与话题投稿 · 被选中奖励</small><b>' + REWARD + '</b></span><span class="go">怎么参与<svg class="ic" style="width:12px;height:12px"><use href="#i-right"/></svg></span></button>' ;
@@ -629,8 +650,10 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
el . innerHTML = '<div class="th k-' + t . cat + '"><i class="wm" aria-hidden="true">' + esc ( t . g ) + '</i><button type="button" class="x" data-t="" aria-label="看全部"><svg class="ic"><use href="#i-x"/></svg></button>' +
el . innerHTML = '<div class="th k-' + t . cat + '"><i class="wm" aria-hidden="true">' + esc ( t . g ) + '</i><button type="button" class="x" data-t="" aria-label="看全部"><svg class="ic"><use href="#i-x"/></svg></button>' +
'<div class="bc"><button type="button" data-t="">' + kbHTML ( t . cat ) . replace ( '</span>' , ' › </span>' ) + '</button><span>话题 · ' + cntT ( t . id ) + ' 篇</span></div>' +
'<div class="bc"><button type="button" data-t="">' + kbHTML ( t . cat ) . replace ( '</span>' , ' › </span>' ) + '</button><span>话题 · ' + cntT ( t . id ) + ' 篇</span></div>' +
'<h2><em>#</em>' + esc ( t . name ) + '<em>#</em></h2><p>' + esc ( d . desc || '' ) + '</p>' +
'<h2><em>#</em>' + esc ( t . name ) + '<em>#</em></h2><p>' + esc ( d . desc || '' ) + '</p>' +
'<div class="tf"><button type="button" class="join" data-join="' + t . id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button><button type="button" class="sw" data-all="1">换个话题</button></div></div>' + rewardHTML ( true ) ;
'<div class="tf"><button type="button" class="join" data-join="' + t . id + '"><svg class="ic"><use href="#i-plus"/></svg>参与话题</button><button type="button" class="sw" data-all="1">换个话题</button></div></div>' ;
fhLevels ( fh ) ;
/* 11-02 用户:「话题页比较乱」→ 去掉投稿奖励横幅和同分类话题胶囊,只留一行标题 */
fh . className = 'sh' ;
fh . innerHTML = '<h2>这个话题下的分享</h2><small>共 ' + cntT ( t . id ) + ' 篇</small>' ;
}
}
/* 11-02 用户:「选了家庭婚姻下一个话题,看着像这块就这几篇,层次感没出来」→ 选了分类 / 话题时,列表上方固定一行「分类 · N 个话题 · 共 M 篇」+ 该分类全部话题胶囊(带篇数),当前话题高亮,「全部」回分类 */
/* 11-02 用户:「选了家庭婚姻下一个话题,看着像这块就这几篇,层次感没出来」→ 选了分类 / 话题时,列表上方固定一行「分类 · N 个话题 · 共 M 篇」+ 该分类全部话题胶囊(带篇数),当前话题高亮,「全部」回分类 */
var cntT = function ( id ) { return NOTES . filter ( function ( n ) { return n . t === id ; } ) . length ; } ;
var cntT = function ( id ) { return NOTES . filter ( function ( n ) { return n . t === id ; } ) . length ; } ;
@@ -691,6 +714,24 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
catF = b . dataset . c ; haptic ( ) ;
catF = b . dataset . c ; haptic ( ) ;
selectTopic ( '' ) ; /* 换分类回到该类「全部」,避免停在别类话题上 */
selectTopic ( '' ) ; /* 换分类回到该类「全部」,避免停在别类话题上 */
} ) ;
} ) ;
/* 11-02 用户:「广场首页左右滑动,可以切到家庭婚姻、职场、经验」→ 横向滑动超过 60px 且明显比竖向大,就切到相邻分类;横滑列表、弹层里不触发 */
( function ( ) {
var sx = 0 , sy = 0 , ok = false , sc = $ ( '#sc' ) ;
sc . addEventListener ( 'touchstart' , function ( e ) {
var t = e . touches [ 0 ] ; sx = t . clientX ; sy = t . clientY ;
ok = e . touches . length === 1 && ! e . target . closest ( '.tcs,.hot,.htl .jn,#sheet,#note,.nd' ) && ! document . body . classList . contains ( 'lock' ) ;
} , { passive : true } ) ;
sc . addEventListener ( 'touchend' , function ( e ) {
if ( ! ok ) return ; ok = false ;
var t = e . changedTouches [ 0 ] , dx = t . clientX - sx , dy = t . clientY - sy ;
if ( Math . abs ( dx ) < 60 || Math . abs ( dx ) < Math . abs ( dy ) * 1.6 ) return ;
var order = CATS . map ( function ( c ) { return c [ 0 ] ; } ) , i = order . indexOf ( catF ) + ( dx < 0 ? 1 : - 1 ) ;
if ( i < 0 || i >= order . length ) return ;
catF = order [ i ] ; haptic ( ) ;
var wf = $ ( '#wf' ) ; wf . classList . remove ( 'swl' , 'swr' ) ; void wf . offsetWidth ; wf . classList . add ( dx < 0 ? 'swl' : 'swr' ) ;
selectTopic ( '' ) ;
} , { passive : true } ) ;
} ) ( ) ;
$ ( '#fh' ) . addEventListener ( 'click' , function ( e ) {
$ ( '#fh' ) . addEventListener ( 'click' , function ( e ) {
var b = e . target . closest ( '[data-t]' ) ; if ( ! b || b . dataset . t === cur ) return ;
var b = e . target . closest ( '[data-t]' ) ; if ( ! b || b . dataset . t === cur ) return ;
haptic ( ) ; var sl = $ ( '#fh .tcs' ) ? $ ( '#fh .tcs' ) . scrollLeft : 0 ;
haptic ( ) ; var sl = $ ( '#fh .tcs' ) ? $ ( '#fh .tcs' ) . scrollLeft : 0 ;
@@ -1081,6 +1122,8 @@ button{font:inherit;color:inherit;border:0;background:none;padding:0;cursor:poin
return '../' + ( s ? '?' + s : '' ) + location . hash ;
return '../' + ( s ? '?' + s : '' ) + location . hash ;
}
}
$ ( '#back' ) . addEventListener ( 'click' , function ( ) {
$ ( '#back' ) . addEventListener ( 'click' , function ( ) {
/* 11-02 用户:「从首页点热门话题进来,左上角返回要回孕妈广场,不是首页」→ 在话题里先退回广场「全部」,再按一次才回首页 */
if ( cur ) { haptic ( ) ; catF = '' ; selectTopic ( '' ) ; return ; }
var fromHome = false ;
var fromHome = false ;
try { fromHome = ! ! document . referrer && new URL ( document . referrer ) . origin === location . origin ; } catch ( e ) { }
try { fromHome = ! ! document . referrer && new URL ( document . referrer ) . origin === location . origin ; } catch ( e ) { }
if ( fromHome && history . length > 1 ) {
if ( fromHome && history . length > 1 ) {