var WX_BJ_REPORT = window.WX_BJ_REPORT || {}; (function(_) { if (_.BadJs) { return; } //onerror上报名 var BADJS_WIN_ERR = 'BadjsWindowError'; var extend = function(source, destination) { for (var property in destination) { source[property] = destination[property] } return source } /* 出错上报字段:mid name key msg stack file col line uin mid 模块名 name 监控名 key 特征值 msg 额外信息 */ _.BadJs = { uin: 0, mid: "", view: "wap", _cache: {}, //上报_cache 同一mid name key 只会上报一次 _info: {}, // 打点记录 会写入msg帮助定位 _hookCallback: null, ignorePath: true, throw: function(e, extData) { this.onError(e, extData); throw e; }, //接收异常并上报处理 如果有额外信息可以放在第二个参数_data中 // _data 只能覆盖上报协议的字段mid (name,key 不建议通过data覆盖) msg stack file col line uin onError: function(e, extData) { try { //标记已执行的throw if (e.BADJS_EXCUTED == true) { return; } e.BADJS_EXCUTED = true; var data = errToData(e); data.uin = this.uin; data.mid = this.mid; data.view = this.view; data.cmdb_module = 'mmbizwap'; //data.msg = msg || data.msg; if (!!extData) { data = extend(data, extData); } //如果cid存在 将cid合并到key if (data.cid) { data.key = "[" + data.cid + "]:" + data.key; }
if (data._info) { if (Object.prototype.toString.call(data._info) == "[object Object]") { data.msg += " || info:" + JSON.stringify(data._info); } else if (Object.prototype.toString.call(data._info) == "[object String]") { data.msg += " || info:" + data._info; } else { data.msg += " || info:" + data._info; } } if (typeof this._hookCallback == "function") { if (this._hookCallback(data) === false) { return } } this._send(data); return _.BadJs; } catch (e) { console.error(e); } }, winErr: function(event) { if (event.error && event.error.BADJS_EXCUTED) { return; } if (event.type === 'unhandledrejection') { _.BadJs.onError(createError(event.type, event.reason, "", "", "", event.reason)); }else{ _.BadJs.onError(createError(BADJS_WIN_ERR, event.message, event.filename, event.lineno, event.colno, event.error)); } }, init: function(uin, mid, view) { this.uin = uin || this.uin; this.mid = mid || this.mid; this.view = view || this.view; return _.BadJs; }, //钩子函数 hook: function(fn) { this._hookCallback = fn; return _.BadJs; }, _send: function(data) { //hack uin mid if (!data.mid) { if (typeof window.PAGE_MID !== 'undefined' && window.PAGE_MID) { data.mid = window.PAGE_MID; } else { return; } } if (!data.uin) { data.uin = window.user_uin || 0; } // 发送要去重 var flag = [data.mid, data.name, data.key].join("|"); if (this._cache && this._cache[flag]) { return } else { this._cache && (this._cache[flag] = true); this._xhr(data); } return _.BadJs; }, _xhr: function(data) { //console.log(data); var xmlobj; if (window.ActiveXObject) { try { xmlobj = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlobj = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlobj = false; } } } else if (window.XMLHttpRequest) { xmlobj = new XMLHttpRequest(); } var param = ""; for (var key in data) { if (key && data[key]) { param += [key, "=", encodeURIComponent(data[key]), "&"].join(""); } } if (xmlobj && typeof xmlobj.open == "function") { xmlobj.open("POST", "https://badjs.weixinbridge.com/report", true); xmlobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); xmlobj.onreadystatechange = function(status) {}; xmlobj.send(param.slice(0, -1)); } else { var img = new Image(); img.src = "https://badjs.weixinbridge.com/report?" + param; } }, // key是特征值 默认上报msg就是key,也可以主动传msg包含更多上报信息 report: function(name, key, data) { this.onError(createError(name, key), data); return this; }, // 打点标记 mark: function(info) { this._info = extend(this._info, info); }, nocache: function() { this._cache = false; return _.BadJs; } } function createError(name, msg, url, line, col, error) { return { name: name || "", message: msg || "", file: url || "", line: line || "", col: col || "", stack: (error && error.stack) || "", } } //将异常错误转换成上报协议支持的字段 /* * 先取e对象上的file line col等字段 * 再解析e.statck * name 错误大类 默认取badjs_try_err|badjs_win_err * key 错误标识 e.message * msg 错误信息 e.message * stack 错误堆栈 e.stack * file 错误发生的文件 * line 行 * col 列 * client_version */ function errToData(e) { var _stack = parseStack(e); return { name: e.name, key: e.message, msg: e.message, stack: _stack.info, file: _stack.file, line: _stack.line, col: _stack.col, client_version: "", _info: e._info } } function parseStack(e) { e._info = e._info || ""; // 当前错误的额外信息 最终上报到info var stack = e.stack || ""; var _stack = { info: stack, file: e.file || "", line: e.line || "", col: e.col || "", }; if (_stack.file == "") { // 提取file line col var stackArr = stack.split(/\bat\b/); if (stackArr && stackArr[1]) { var match = /(https?:\/\/[^\n]+)\:(\d+)\:(\d+)/.exec(stackArr[1]); if (match) { //若stack提取的file line col跟e中的属性不一致,以stack为准 但在e._info中记录原始数据 if (match[1] && match[1] != _stack.file) { _stack.file && (e._info += " [file: " + _stack.file + " ]"); _stack.file = match[1]; } if (match[2] && match[2] != _stack.line) { _stack.line && (e._info += " [line: " + _stack.line + " ]"); _stack.line = match[2]; } if (match[3] && match[3] != _stack.col) { _stack.col && (e._info += " [col: " + _stack.col + " ]"); _stack.col = match[3]; } } } } //替换堆栈中的文件路径 combojs太长 if (_stack && _stack.file && _stack.file.length > 0) { _stack.info = _stack.info.replace(new RegExp(_stack.file.split("?")[0], "gi"), "__FILE__") } //堆栈路径只保存文件名 if (_.BadJs.ignorePath) { _stack.info = _stack.info.replace(/http(s)?\:[^:\n]*\//ig, "").replace(/\n/gi, ""); } return _stack; } //兜底方法 window.addEventListener && window.addEventListener('error', _.BadJs.winErr); window.addEventListener && window.addEventListener('unhandledrejection', _.BadJs.winErr); return _.BadJs; })(WX_BJ_REPORT); window.WX_BJ_REPORT = WX_BJ_REPORT; /** * 兼容wap项目的简单CMD管理 * 所有wap项目必须包含此文件才可以执行成功 * 暴露在全局的变量仍然以seajs为命名空间,跟web项目保持一致 * 支持的API是seajs.use,以及require define * @author raphealguo * @date 20140326 */ function __moonf__() { if (window.__moonhasinit) return; window.__moonhasinit = true; window.__moonclientlog = []; // moon中存到客户端日志里面的内容,最终写入到客户端的地点在fereport.js if (typeof JSON != "object") { //针对IE7的hack window.JSON = { stringify: function() { return ""; }, parse: function() { return {}; } }; } var moon_init = function() { /** * mooncatch * 对各种异步回调都使用try catch错误上报 * @radeonwu raphealguo */ (function() { var inWx = (/MicroMessenger/i).test(navigator.userAgent); var inMp = (/MPAPP/i).test(navigator.userAgent); var _idkey = 121261; //上报的idkey 添加默认上报值 var _startKey; //开始的key var _limit; //上报的key的长度 var _badjsId; var _reportOpt; //上报的额外信息 var _extInfo; //附加的预留字段,如网络采样率采样率network_rate, 总体上报率rate var MOON_AJAX_NETWORK_OFFSET = 4; //network错误时的上报偏移量为4,这里在ajax.js中上报,这里需要加入采样率 window.__initCatch = function(opt) { _idkey = opt.idkey; _startKey = opt.startKey || 0; _limit = opt.limit; _badjsId = opt.badjsId; _reportOpt = opt.reportOpt || ""; _extInfo = opt.extInfo || {}; _extInfo.rate = _extInfo.rate || 0.5; } //暴露的上报函数,供core.js和ajax.js上报错误使用,array = [{offset:MOON_JSAPI_KEY_OFFSET, log:"ready", e:e}] window.__moon_report = function(array, rate_opt) { var isAcrossOrigin = false; var href = ''; try { href = top.location.href; } catch (e) { isAcrossOrigin = true; } var rate = 0.5; if (!!_extInfo && !!_extInfo.rate) { rate = _extInfo.rate; } if (!!rate_opt && (typeof rate_opt == 'number')) { rate = rate_opt; } if ( (!(/mp\.weixin\.qq\.com/).test(location.href) && !(/payapp\.weixin\.qq\.com/).test(location.href)) || Math.random() > rate || !(inWx || inMp) || (top != window && !isAcrossOrigin && !(/mp\.weixin\.qq\.com/).test(href)) ) { //return ; } if (isObject(array)) array = [array]; if (!isArray(array) || _idkey == '') return; var data = ""; var log = []; //存放array中每个对象关联的log var key = []; //存放array中每个上报的key var val = []; //存放array中每个上报的value var idkey = []; //如果这里没有opt.limit,直接上报到startKey if (typeof _limit != "number") { _limit = Infinity; } for (var i = 0; i _limit) continue; //上报的偏移量超过limit if (typeof item.offset != "number") continue; if (item.offset == MOON_AJAX_NETWORK_OFFSET && !!_extInfo && !!_extInfo.network_rate && Math.random() >= _extInfo.network_rate) { continue; } //log[i] = item.log || ""; var k = _limit == Infinity ? _startKey : (_startKey + item.offset); log[i] = (("[moon]" + _idkey + "_" + k + ";") + item.log + ";" + getErrorMessage(item.e || {})) || ""; key[i] = k; val[i] = 1; } for (var j = 0; j 0) { // sendReport("idkey=" + idkey.join(";") + "&lc=" + log.length + data); sendReport("POST", location.protocol + '//mp.weixin.qq.com/mp/jsmonitor?', "idkey=" + idkey.join(";") + "&r=" + Math.random() + "&lc=" + log.length + data); // 把图文消息的错误上报一份到badjs,只支持get请求 // 这里由于量比较大,把badjs的内层怼爆了,这里加多一个采样,并且去掉用户的信息 var rate = 1; if (_extInfo && _extInfo.badjs_rate) { // 初始化时的badjs采样率 rate = _extInfo.badjs_rate; } if (Math.random()
中国乳业下一个千亿级风口,羊奶品牌正在加速破圈
从完美日记、元气森林等品牌的迅速崛起中可以发现,不少国产新消费品牌在短短创业三五年内,便完成了对拥有数十年积累的传统品牌的逆袭,这显然并非偶然,而是新物种们对传统商业市场逻辑的一种打破重组。
移动互联网人口红利的消失、城市化的持续推进、新生儿出生率的降低、中产群体的大规模崛起、个性化多元化审美的爆发……种种因素下都让大众消费从功能导向转变为品质升级。事实上,正是因为消费升级红利的涌现,才释放了各大行业弯道超车的市场机遇。
纵观各大消费产业,乳业作为国民健康的支柱性产业,无疑拥有足够的分量。可以发现,从产品形态,到品类升级,乳业的消费升级才刚刚开始,最为明显的表现就是羊奶这一细分品类正在快速兴起,成为乳业消费升级的一大代表,而民间素来都有“一杯羊奶等于三杯牛奶”的说法。
从产业链上看,乳业横跨了一二三产业、涉及范围颇广,因此终端乳产品消费升级的新趋势,对整个行业的迭代意义都非常深远,高速增长的羊奶,或许已经成为各大乳企的兵家必争之地。
羊奶破圈进行时
羊奶产业真正的高速发展就在这十多年间,根据中国社会科学院食品药品产业发展与监管研究中心数据,2008年我国羊奶粉市场销售额仅为3亿元左右,到2015年已经突破50亿元。而根据华经产业研究院发布的《2021-2026年中国羊奶粉市场调查研究及行业投资潜力预测报告》数据显示,2019年我国羊奶粉市场规模已经突破100亿元。
图片来自华经产业研究院
值得一提的是,根据华商情报网数据统计,本土羊奶粉的市场规模增速明显强于进口羊奶粉,且我国羊奶粉在婴幼儿配方奶粉中的占比,从2013年的2.80%一路预计增长至2020年的6.59%。
业内不少专家学者对羊奶市场态度更加积极,根据国际奶山羊协会主席、陕西省奶山羊产业技术创新体系首席科学家曹斌云在公开场合表示,据估算,未来10年中国乳业市场的开发潜力在6000亿元左右,羊乳产业的市场开发潜力在2000亿元以上。羊乳行业将成为下一个千亿级风口。
羊奶近年来受到市场的热捧,主要在于其温和营养的产品特性,尤其是对于婴幼儿而言,羊奶相对于牛奶产品脂肪球分子更小,也就更易于婴幼儿吸收。除此之外,羊奶的致敏性较牛奶更低,也就更适宜婴幼儿食用。根据公开数据统计,大约有2.5%的婴儿在出生后会出现不同程度的牛奶过敏现象,从而出现皮肤红疹等应激反应。
如今市场中,确实有不少品牌主打纯羊奶婴幼儿配方奶粉,并在此基础上加入自身的产品“黑科技”,例如近几年羊奶粉品牌蓓康僖,其产品启铂系列便在纯羊乳的基础上添加了更多天然类母乳的OPO结构脂,以完善婴幼儿的营养吸收,同时优化配方添加BB-12益生菌+益生元组合,促进肠道吸收。
事实上,羊奶产品的品质优点很早就被业内所知晓,但相比于牛奶千亿级的产业的规模,羊奶产业在过去许多年中仍属于小众行业,消费者认知相对不充分,这背后与羊奶整个产业链结构及生产制作方式有关。随着产业发展和消费升级的推进,羊奶产业发展的痛点正在被一一破解,羊奶品类正驶入快车道。
羊奶行业的生存法则
价格是消费决策中的最后一道关卡,对于羊奶产品来说,不少消费者的直观认知在于其价格较高。这并非国内消费者独有感受,而是全球羊奶产品的普遍情况,有媒体报道,欧洲鲜羊奶的价格是鲜牛奶的7-9倍。
羊奶价格高居不下的背后,是羊奶的成本难题。相比于适合圈养的乳牛,乳羊更适合放养,这也意味着羊奶产业在养殖端便难以集中管理,产业的规模效应较弱。再加上乳羊放养过程中可能对植被有破坏作用,不少地区的政府也在严格限制乳羊的数量。正是羊奶产品成本高居不下,从而在过去多年内限制产品破圈及产业发展,甚至催生了不少行业乱象。
在成本压力下,有不少品牌通过“半羊”的方式制作羊奶粉,所谓“半羊”,便是通过羊乳和牛乳混合加工制成的产品,这类产品由于添加了牛乳相关成分,通常来说并不能完全达到降低致敏性、促进蛋白吸收等功效,因此这类产品更多可以看做是产业升级过渡时期的产品形态。
真正推动整个羊奶行业发展的是2018年起奶粉配方注册制的实行,在注册制的政策推动下,羊奶产业集中度不断提高,无竞争力的“杂牌”中小厂商被迫出局,羊奶行业也因此进入了大品牌时代,在产品方面,“半羊”产品也逐步被“纯羊”所取代。
不少人把消费升级误解为“量价齐升”,但如果观察各大消费行业的现状就能发现,消费升级的整体方向并不是质优价高,而是物美价廉。在品牌集中度提高的同时,羊奶的成本难题也通过科技创新得到了解决。
羊奶粉加工的核心原材料是脱盐羊乳清粉,但问题在于脱盐羊乳清粉是羊乳酪生产加工的副产品,若是单独生产则显然在商业上并不划算,而国内消费者并没有消费羊乳酪的饮食习惯。因此就不难发现,目前市场上不少羊奶品牌主打进口,背后真正的原因并不在于进口的奶源质量更好,而在于对脱盐羊乳清粉这一核心原材料把控上的被动。与其说进口羊奶粉是“崇洋媚外”,不如说其实是国内羊奶产业的“被逼无奈”。
如今情况正在发生变化,国内已经有羊奶企业突破了这一原材料难题,宜品集团在2016年率先研发出了脱盐羊乳清粉技术,并同年推出蓓康僖纯羊品牌,摆脱了国内羊奶产业长期对国外原材料的依赖,推动了中国羊奶的产业发展。
事实上,国产化一直是乳业发展的大趋势,无论牛羊奶产品均是如此,从宏观层面来看,乳业作为重要的民生行业,国产化亦是国家战略,2019年5月出台的《国产婴幼儿配方乳粉提升行动方案》中提出,力争婴幼儿配方乳粉自给水平稳定在60%以上。而随着“洋奶粉”的祛魅,国产品质正在被更多消费者所认同,2020年的新冠疫情黑天鹅对供应链的挑战,更是推动了国产品牌的进一步崛起,因此可以说国产羊奶粉才是羊奶产业发展的未来方向。
国产品牌的红利期
随着民族自信的建立,国货品牌的快速崛起已经毋庸置疑,未来数十年或许将是国产品牌在全球范围内大放异彩的时代。中国不仅拥有着庞大的市场容量,而且拥有着层次最为丰富、需求最为多元的消费群体,这种市场多样性也能有效催生国际性品牌的涌现。
但国产品牌的崛起,并不意味着反全球化的商业路径,恰恰相反,国产品牌崛起的背后是对全球优质资源的高效整合。就乳业来说,2019年5月出台的《国产婴幼儿配方乳粉提升行动方案》中提出“支持国内企业在境外收购和建设奶源基地”等政策方向,我们也能发现飞鹤、伊利、圣元、雅士利、澳优、合生元等中国乳企近年来正在积极地进行海外市场、海外供应链布局,不同乳企的布局侧重点亦不相同,例如飞鹤主要布局北美,伊利则侧重于在新西兰、圣元建设法国工厂、宜品布局韩国及西班牙、贝因美则牵手爱尔兰。
在中国乳业及国产奶粉品牌发展历程中,2008年三聚氰胺事件始终是一个绕不过去的坎,直接导致国产品牌“失去的十年”。当年为数不多未受三聚氰胺事件影响的“品牌幸存者”,大多也因此次事件走向了全产业链布局之路,当年黑龙江的两家乳品企业飞鹤、宜品均是如此。
当年蓓康僖所属的宜品乳业全系产品未受三聚氰胺事件波及,宜品董事长牟善波曾在后来的媒体采访中表示,“奶源的质量是根本,是源头,如果解决不了源头问题,大厦建多高,基础都是一盘散沙,经不起折腾的。”据公开媒体报道,多年以来,蓓康僖已经逐步构建出了围绕羊奶生产的全产业链布局。
早在2013年,宜品开始布局羊奶产业链,并在羊奶粉行业中率先进行脱盐羊乳清这一关键技术的突破,经过三年的研发攻坚,宜品于2016年成为国内首个掌握成熟D90脱盐羊乳清技术的企业,攻破羊奶产业技术壁垒;同年起宜品开始布局海外生产工厂,在具有天然港口优势的韩国光阳进行投资建厂,打通产品销售链条,并将高端纯羊奶粉产品销往全球各地。
2018年,宜品继续布局上游珍稀羊乳清资源,收购西班牙羊乳清工厂,从源头上保证充足产能。2020年10月,总投资约10亿元、全国最大羊奶粉项目在青岛莱西投产,宜品由此完成了全产业链的整体布局,并构建出了在羊乳行业中的深厚企业护城河。
由于奶粉是民生类产品,婴幼儿奶粉更是高频刚需品,因此相比于当下新消费普遍采用的线上及DTC模式,奶粉的主要销售渠道依旧在于线下,而国产奶粉企业的渠道下沉优势显然远超外资企业。根据母婴时代资料显示,在2016-2017年期间,菲仕兰、美赞臣、惠氏等外资品牌均宣布要进行市场下沉,到3-5线城市进行渠道布局,但最终效果均不理想。
不难发现,近年来国产奶粉企业品牌化、高端化的进程正在加速。日前,蓓康僖官宣佟大为成为品牌代言人,并正式对外宣布赞助合作由佟大为作为男一号出演的热播剧《小舍得》。在此期间,蓓康僖还与新潮传媒合作进行了线下高铁、电梯等线下入口场景广告投放,并联手金鹰卡通等综艺资源实现深度品牌价值曝光。而在产品品质层面,蓓康僖亦获得了全球认可,根据官网资料显示,蓓康僖启铂已连续四年获得“世界食品品质评鉴大会金奖”。
总体来看,羊奶产业的发展与竞争或许将是乳业未来的一个重要变量,而从研发、生产、销售的多维因素综合来分析,国产品牌、本土产品应该会成为羊奶产业中最为重要的一支力量。据悉,蓓康僖在2020年疫情背景之下销量并未下降,反而实现了全年同比100%的高速增长,凭借近10亿销售额夺下国产羊奶品牌第一,成为国内羊奶行业中的标志性品牌。
分析发现,蓓康僖的高速增长更多在于企业战略的“顺势而为”,每一场外在危机都是优质企业的试金石,纵观宜品的产品线及产业链布局,尤其在产品端,宜品旗下各产品线都能实现稳定及高速的增长,表现出了企业强大的市场爆发力和品牌竞争力。对此,牟善波表示,“我经常跟事业部负责人强调我们就像蒙古骑兵一样,来自不同的盟不同的旗,假如今天要出征,我们一发号令,大家就集中在宜品的旗下,一起攻下城池。”
在牟善波看来,蓓康僖的渠道、产品、品牌便是企业高速发展的“三驾马车”,在渠道端,蓓康僖已经覆盖全国30000余家母婴门店;在产品端,蓓康僖用5年突破了10亿的发展速度,验证了市场对高品质产品的认可和需求;在品牌端,蓓康僖已经找准发力点,通过加大品牌营销的投入,一击突围。
未来,随着大众对羊奶认知的不断升级,预计更多消费者将转化为羊奶用户,羊奶或许将成为乳制产品中的新贵,亦成为当下中国乳业的重要变量。放眼整个羊奶行业,蓓康僖一步一脚印的稳扎稳打,为其发展提供有力支撑,如果说2020年是羊乳企业艰难求生的一年,那么2021将成为羊乳企业突出重围走进更为激烈市场竞争的一年。如今,蓓康僖已率先打响这场品牌破圈之战。
// // 广告iframe预加载 try { var adIframeUrl = localStorage.getItem('__WXLS_ad_iframe_url'); if (window === top) { if (adIframeUrl) { if (navigator.userAgent.indexOf('iPhone') > -1) { var img = new Image(); img.src = adIframeUrl; } else { var link = document.createElement('link'); link.rel = 'prefetch'; link.href = adIframeUrl; document.getElementsByTagName('head')[0].appendChild(link); } } } } catch (err) {
}
function _addVConsole(uri, cb) { totalCount++; var node = document.createElement('SCRIPT'); node.type = 'text/javascript'; node.src = uri; node.setAttribute('nonce', '718129770'); if (cb) { node.onload = cb; } document.getElementsByTagName('head')[0].appendChild(node); } if ( (document.cookie && document.cookie.indexOf('vconsole_open=1') > -1) || location.href.indexOf('vconsole=1') > -1 ) { _addVConsole('https://mp.weixin.qq.com/mmbizappmsg/zh_CN/htmledition/js/scripts/vconsole-3.14.6.js', function () { var vConsole = new window.VConsole(); }); }
})();
var ua = navigator.userAgent.toLowerCase(); var re = new RegExp("msie ([0-9]+[\.0-9]*)"); var version; if (re.exec(ua) != null) { version = parseInt(RegExp.$1); } var isIE = false; if (typeof version != 'undefined' && version >= 6 && version 16) break; // 16是占位loading的宽度,所以要大于16 outerWidth += parseFloat(parent_style.paddingLeft) + parseFloat(parent_style.paddingRight) + parseFloat(parent_style.marginLeft) + parseFloat(parent_style.marginRight) + parseFloat(parent_style.borderLeftWidth) + parseFloat(parent_style.borderRightWidth); parent = parent.parentNode; } return parent_width; } var getOuterW = function (dom) { var style = getComputedStyle(dom), w = 0; if (!!style) { w = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth); } return w; }; var getOuterH = function (dom) { var style = getComputedStyle(dom), h = 0; if (!!style) { h = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); } return h; }; var insertAfter = function (dom, afterDom) { var _p = afterDom.parentNode; if (!_p) { return; } if (_p.lastChild === afterDom) { _p.appendChild(dom); } else { _p.insertBefore(dom, afterDom.nextSibling); } }; var getQuery = function (name, url) { //参数:变量名,url为空则表从当前页面的url中取 var u = arguments[1] || window.location.search, reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"), r = u.substr(u.indexOf("\?") + 1).match(reg); return r != null ? r[2] : ""; };
/** * 设置图片size * * @param {HTMLElement} item 图片元素 * @param {number} widthNum 宽度数值 * @param {string} widthUnit 宽度单位 * @param {number} ratio 宽高比 * @param {boolean} breakParentWidth 是否突破父元素宽度(父元素是否被撑大) */ function setImgSize(item, widthNum, widthUnit, ratio, breakParentWidth) { setTimeout(function () { var img_padding_border = getOuterW(item) || 0; var img_padding_border_top_bottom = getOuterH(item) || 0;
// 如果设置的宽度超过了父元素最大宽度,则取父元素宽度 if (widthNum > getParentWidth(item) && !breakParentWidth) { widthNum = getParentWidth(item); }
var height = (widthNum - img_padding_border) * ratio + img_padding_border_top_bottom;
if (isCarton) { // 判一下是不是漫画原创,如果是,不走懒加载 var url = item.getAttribute('data-src'); item.src = url;
// 不走懒加载但是需要跟懒加载一样去除占位高度 item.style.height = 'auto'; } else { // if (parseFloat(widthNum, 10) > 40 && height > 40 && breakParentWidth) { // item.className += ' img_loading'; // } // item.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=="; widthNum !== 'auto' && (item.style.cssText += ";width: " + widthNum + widthUnit + " !important;"); widthNum !== 'auto' && (item.style.cssText += ";height: " + height + widthUnit + " !important;"); } }, 10); } // 图片和视频预加载逻辑,记得H5和秒开要对齐逻辑 (function () { var images = document.getElementsByTagName('img'); var length = images.length; var max_width = getMaxWith(); for (var i = 0; i 0) { // 非漫画才需要占位 if (!isCarton) { imageItem.setAttribute('data-origin-display', imageItem.style.display); imageItem.style.display = 'none'; imgPlaceHolder.className = "js_img_placeholder wx_widget_placeholder"; imgPlaceHolder.setAttribute("data-src", src_ || realSrc); imgPlaceHolder.setAttribute("data-index", i); imgPlaceHolder.innerHTML = '';
insertAfter(imgPlaceHolder, imageItem); // 在视频后面插入占位 }
var parent_width = getParentWidth(imageItem) || max_width; var initWidth = imageItem.style.width || imageItem.getAttribute('width') || originWidth || parent_width; initWidth = parseFloat(initWidth, 10) > max_width ? max_width : initWidth; // 有attribute或style中的width,写入_width属性,在图片加载完成时写入img标签 if (initWidth) { imageItem.setAttribute('_width', !isNaN(initWidth * 1) ? initWidth + 'px' : initWidth); } // 使用百分比,则计算出像素宽度 if (typeof initWidth === 'string' && initWidth.indexOf('%') !== -1) { initWidth = parseFloat(initWidth.replace('%', ''), 10) / 100 * parent_width; } // 使用auto,就是原始宽度 if (initWidth === 'auto') { initWidth = originWidth; if (originWidth === 'auto') { initWidth = parent_width; } else { initWidth = originWidth; } }
var widthNum; var widthUnit; if (initWidth === 'auto') { widthNum = 'auto'; } else { var res = /^(\d+(?:\.\d+)?)([a-zA-Z%]+)?$/.exec(initWidth); widthNum = res && res.length >= 2 ? res[1] : 0; widthUnit = res && res.length >= 3 && res[2] ? res[2] : 'px'; }
// 试探一下parent宽度在设置了图片的大小之后是否会变化 if (!isCarton) { setImgSize(imgPlaceHolder, widthNum, widthUnit, ratio_, true); } else { setImgSize(imageItem, widthNum, widthUnit, ratio_, true); }
// // 真正设置宽高 // (function (item, widthNumber, unit, ratio) { // setTimeout(function () { // setImgSize(item, widthNumber, unit, ratio, false); // }); // })(imageItem, widthNum, widthUnit, ratio_); } else { // 这里使用visibility 而不是display none 是因为没有占位元素,那就让图片自己占位 imageItem.style.cssText += ";visibility: hidden !important;"; } } })(); window.__videoDefaultRatio = 16 / 9;//默认值是16/9 window.__getVideoWh = function (dom) { var max_width = getMaxWith(), width = max_width, ratio_ = dom.getAttribute('data-ratio') * 1,//mark16/9 arr = [4 / 3, 16 / 9], ret = arr[0], abs = Math.abs(ret - ratio_); if (!ratio_) { // 没有比例 if (dom.getAttribute("data-mpvid")) { // MP视频 ratio_ = 16 / 9; } else { // 非MP视频,需要兼容历史图文 ratio_ = 4 / 3; } } else { // 有比例,则判断更接近4/3还是更接近16/9 for (var j = 1, jl = arr.length; j parent_width ? parent_width : width, outerW = getOuterW(dom) || 0, outerH = getOuterH(dom) || 0, videoW = width - outerW, videoH = videoW / ratio_, speedDotH = 12, // 播放器新样式的进度条在最下面,为了避免遮住拖动的点点,需要额外设置高一些 height = videoH + outerH + speedDotH;
return { w: Math.ceil(width), h: Math.ceil(height), vh: videoH, vw: videoW, ratio: ratio_, sdh: speedDotH }; };
// 图片和视频预加载逻辑,记得H5和秒开要对齐逻辑 (function () { var iframe = document.getElementsByTagName('iframe'); for (var i = 0, il = iframe.length; i '; videoPlaceHolderSpan.style.cssText = "width: " + obj.w + "px !important;";
insertAfter(videoPlaceHolderSpan, a); // 在视频后面插入占位
/* var parentNode = a.parentNode; var copyIframe = a; var index = i; */
// 由于视频需要加一个转载的来源,所以这里需要提前设置高度 function ajax(obj) { var url = obj.url; var xhr = new XMLHttpRequest();
var data = null; if (typeof obj.data == "object") { var d = obj.data; data = []; for (var k in d) { if (d.hasOwnProperty(k)) { data.push(k + "=" + encodeURIComponent(d[k])); } } data = data.join("&"); } else { data = typeof obj.data == 'string' ? obj.data : null; }
xhr.open('POST', url, true); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status '; videoBarHtml += '
'; videoBarHtml += '
'; videoBarHtml += '
'; videoBarHtml += ''; videoBarHtml += '
'; videoBarHtml += '
'; videoBarHtml += '
'; videoBar.innerHTML = videoBarHtml; var spanContainer = document.getElementById('js_mp_video_container_' + index); if (spanContainer) { spanContainer.parentNode.insertBefore(videoBar, spanContainer); } else if (parentNode.contains && parentNode.contains(copyIframe)) { parentNode.insertBefore(videoBar, copyIframe); } else { parentNode.insertBefore(videoBar, parentNode.firstElementChild); } var avatorEle = document.getElementById(hit_biz_headimg + index); var avatorSrc = avatorEle.dataset.src; console.log('avatorSrc' + avatorSrc); if (ret.hit_biz_headimg) { avatorEle.style.backgroundImage = 'url(' + avatorSrc + ')'; } } }, error: function (xhr) { } }); })(a.parentNode, a, i, vid);
a.style.cssText += ";width: " + obj.w + "px !important;"; a.setAttribute("width", obj.w); if (window.__zoom != 1) { a.style.display = "block"; videoPlaceHolderSpan.style.display = "none"; a.setAttribute("_ratio", obj.ratio); a.setAttribute("_vid", vid); } else { videoPlaceHolderSpan.style.cssText += "height: " + (obj.h - obj.sdh) + "px !important;margin-bottom: " + obj.sdh + "px !important;"; a.style.cssText += "height: " + obj.h + "px !important;"; a.setAttribute("height", obj.h); } a.setAttribute("data-vh", obj.vh); a.setAttribute("data-vw", obj.vw); if (a.getAttribute("data-mpvid")) { a.setAttribute("data-src", location.protocol + "//mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&auto=0&vid=" + vid); } else { a.setAttribute("data-src", location.protocol + "//v.qq.com/iframe/player.html?vid=" + vid + "&width=" + obj.vw + "&height=" + obj.vh + "&auto=0"); } } })();
(function () { if (window.__zoom != 1) { if (!window.__second_open__) { document.getElementById('page-content').style.zoom = window.__zoom; var a = document.getElementById('activity-name'); var b = document.getElementById('meta_content'); if (!!a) { a.style.zoom = 1 / window.__zoom; } if (!!b) { b.style.zoom = 1 / window.__zoom; } } var images = document.getElementsByTagName('img'); for (var i = 0, il = images.length; i = 0 && child.getAttribute("data-vid") == vid) { child.style.cssText += "height: " + h + "px !important;"; child.style.display = ""; } } } } })(); })();
"},{querySelector:"qqmusic",genId:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(t.node.getAttribute("musicid")||"").replace(/^\s/,"").replace(/\s$/,"")+"_"+t.index},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 88},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mpvoice",genId:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=decodeURIComponent(t.node.getAttribute("voice_encode_fileid")||"").replace(/^\s/,"").replace(/\s$/,"");return e+"_"+t.index},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 122},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mppoi",genId:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return t.node.getAttribute("data-id")||""},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 219},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mpsearch",genId:function(){return decodeURIComponent("mp-common-search")},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 100},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mp-common-search",genId:function(){return decodeURIComponent("mp-common-search")},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 100},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mpvideosnap",genId:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.node.getAttribute("data-type")||"video";return"live"===e?decodeURIComponent(t.node.getAttribute("data-noticeid")||""):decodeURIComponent(t.node.getAttribute("data-id")||"")},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.node.getAttribute("data-type")||"video",n=t.node.getAttribute("data-width")||"",r=t.node.getAttribute("data-height")||"";if("live"===e||"topic"===e)return t.parentWidth;var i=1,o=0,a=0,d=!1;return 1===(i=n/r)||i===3/4||(i===4/3||i===16/9?d=!0:i1&&i4/3?d=!0:("number"!=typeof i||Object.is(i,NaN))&&(i=1)),t.node.setAttribute("data-ratio",i),t.node.setAttribute("data-isHorizontal",d),o=(a=!0===d?t.parentWidth:window.innerWidth0&&void 0!==arguments[0]?arguments[0]:{},e=t.node.getAttribute("data-desc")||"",n=t.node.getAttribute("data-type")||"video",r=t.node.getAttribute("data-computedHeight")||"";switch(n){case"live":return e?152:116;case"topic":return 201;case"image":case"video":return parseFloat(r)}},getBorderRadius:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.node.getAttribute("data-type")||"video";return"video"===e?4:8},replaceContentCssText:"",appendContentCssText:"display:flex;margin:16px auto;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mp-wxaproduct",genId:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return decodeURIComponent(t.node.getAttribute("data-wxaproduct-productid")||"")},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.node.getAttribute("data-wxaproduct-cardtype")||"";return"mini"===e?124:466},replaceContentCssText:"",appendContentCssText:"margin:16px 0;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mpprofile",genId:function(t){return t.node.getAttribute("data-id")||""},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 143},replaceContentCssText:"",appendContentCssText:"margin:16px 0 16px;diplay:block;",outerContainerLeft:"",outerContainerRight:""},{querySelector:"mp-common-profile",genId:function(t){return t.node.getAttribute("data-id")||""},calW:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 1*t.parentWidth},calH:function(){return 143},replaceContentCssText:"",appendContentCssText:"margin:16px 0 16px;diplay:block;",outerContainerLeft:"",outerContainerRight:""}]};!function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("function"==typeof document.querySelectorAll)for(var e={maxWith:document.getElementById("img-content").getBoundingClientRect().width,idAttr:"data-preloadingid"},n=0,r=t.config.length;n
var uin = ''; var key = ''; var pass_ticket = ''; var new_appmsg = 1; var item_show_type = "0"; var real_item_show_type = "0"; var can_see_complaint = "0"; var tid = ""; var aid = ""; var clientversion = ""; var appuin = "" || "MzI2NDk5NzA0Mw=="; var voiceid = "";
var source = ""; var ascene = ""; var subscene = ""; var sessionid = "" || "svr_11d0e07bc0f"; var abtest_cookie = "";
var scene = 75;
var itemidx = ""; var appmsg_token = ""; var _copyright_stat = "0"; var _ori_article_type = "";
var is_follow = ""; var nickname = "36氪"; var appmsg_type = "9"; var ct = "1618220803"; var user_name = "gh_240fbf8b33e4"; var fakeid = ""; var version = ""; var is_limit_user = "0"; var round_head_img = "http://mmbiz.qpic.cn/mmbiz_png/QicyPhNHD5vYf0JyXiavcUmicQ7icOk55ygRlyOhCa9r132trMAiaYtqL0QzacfMLPolhsiaXGibWC0JskibLic02W6Mw1g/0?wx_fmt=png"; var hd_head_img = "http://wx.qlogo.cn/mmhead/Q3auHgzwzM6bia44ArPNMqFIeUFznyuic1uaRBHxkkppnTnnYpkPVSXA/0" || ""; var ori_head_img_url = "http://wx.qlogo.cn/mmhead/Q3auHgzwzM6bia44ArPNMqFIeUFznyuic1uaRBHxkkppnTnnYpkPVSXA/132"; var msg_title = '中国乳业下一个千亿级风口,羊奶品牌正在加速破圈'.html(false); var msg_desc = htmlDecode("高速增长的羊奶,或许已经成为各大乳企的兵家必争之地。"); var msg_cdn_url = "http://mmbiz.qpic.cn/mmbiz_jpg/QicyPhNHD5va04omMicRLticb5y40P47GzIsjIA87zbLQMnmWhKFpcMicAIzegYfLq9ibqJVjf12CDjI3LInNxKcrgw/0?wx_fmt=jpeg"; // 首图idx=0时2.35:1 , 次图idx!=0时1:1 var cdn_url_1_1 = "https://mmbiz.qlogo.cn/mmbiz_jpg/QicyPhNHD5va04omMicRLticb5y40P47GzIGT17IIKdBYRbJbqAju5RcdSSWE3ODwlCicXprwXNrHlISAde8GZ9yxA/0?wx_fmt=jpeg"; // 1:1比例的封面图 var cdn_url_235_1 = "https://mmbiz.qlogo.cn/mmbiz_jpg/QicyPhNHD5va04omMicRLticb5y40P47GzIsjIA87zbLQMnmWhKFpcMicAIzegYfLq9ibqJVjf12CDjI3LInNxKcrgw/0?wx_fmt=jpeg"; // 首图idx=0时2.35:1 , 次图idx!=0时1:1 // var msg_link = ""; var msg_link = ""; // @radeonwu var user_uin = "" * 1; var msg_source_url = ''; var img_format = 'jpeg'; var srcid = ''; var req_id = '2911eaiE3joz8Fl0tnvi9xH0'; var networkType; var appmsgid = "2247800885" || '' || ''; var comment_id = "1822484356838277120" || "1822484356838277120" * 1; var comment_enabled = "" * 1; var open_fansmsg = "0" * 1; var is_https_res = ("" * 1) && (location.protocol == "https:"); var msg_daily_idx = "2" || ""; var profileReportInfo = "" || "";
var devicetype = ""; var source_encode_biz = ""; // 转载来源的公众号encode biz var source_username = ""; // var profile_ext_signature = "" || ""; var reprint_ticket = ""; var source_mid = ""; var source_idx = ""; var source_biz = ""; var author = ""; var author_id = ""; var reward_wording = "";
// 压缩标志位 var optimizing_flag = "0" * 1;
// 广告灰度实验取消 @add by scotthuang // var ad_abtest_padding = "0" * 1;
var show_comment = ""; var __appmsgCgiData = { wxa_product: "" * 1, wxa_cps: "" * 1, show_msg_voice: "0" * 1, can_use_page: "" * 1, is_wxg_stuff_uin: "0" * 1, card_pos: "", copyright_stat: "0", source_biz: "", hd_head_img: "http://wx.qlogo.cn/mmhead/Q3auHgzwzM6bia44ArPNMqFIeUFznyuic1uaRBHxkkppnTnnYpkPVSXA/0" || (window.location.protocol + "//" + window.location.host + "//res.wx.qq.com/mmbizappmsg/zh_CN/htmledition/js/images/pic/pic_rumor_link60e8b7.jpg"), has_red_packet_cover: "0" * 1 || 0, minishopCardData: "" }; var _empty_v = "//res.wx.qq.com/mmbizappmsg/zh_CN/htmledition/js/audios/empty60e8b7.mp3"; var appmsg_album_info = (function () { var curAlbumId = ''; var publicTagInfo = [ ]; for (var i = 0; i