击上方 "程序员小乐"关注, 星标或置顶一起成长
Style 对象
Style 对象表示一个个别的样式声明。
访问 Style 对象
Style 对象可以从文档的头部区域访问,或者从指定的 HTML 元素访问。
从文档的头部区域访问 style 对象:
var x=document.getElementsByTagName("STYLE");尝试一下
访问一个指定元素的 style 对象:
var x=document.getElementById("myH1").style;
创建 Style 对象
您可以使用 document.createElement() 方法来创建 <style> 元素:
var x=document.createElement("STYLE");尝试一下
您也可以设置一个已有元素的 style 属性:
document.getElementById("myH1").style.color="red";
Style 对象属性
"CSS" 列表示该属性是在哪一个 CSS 版本中定义的(CSS1、CSS2 或 CSS3)。
属性 | 描述 | CSS |
---|---|---|
alignContent | 设置或返回当灵活容器内的各项没有占用所有可用的空间时各项之间的对齐方式(水平)。 | 3 |
alignItems | 设置或返回灵活容器内的各项的对齐方式。 | 3 |
alignSelf | 设置或返回灵活容器内被选中项目的对齐方式。 | 3 |
animation | 是下面除了 animationPlayState 属性之外的其他属性的速记属性。 | 3 |
animationDelay | 设置或返回动画何时开始。 | 3 |
animationDirection | 设置或返回是否循环交替反向播放动画。 | 3 |
animationDuration | 设置或返回动画完成需花费的秒数或毫秒数。 | 3 |
animationFillMode | 设置或返回当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。 | 3 |
animationIterationCount | 设置或返回动画的播放次数。 | 3 |
animationName | 设置或返回关键帧 @keyframes 动画的名称。 | 3 |
animationTimingFunction | 设置或返回动画的速度曲线。 | 3 |
animationPlayState | 设置或返回动画是运行的还是暂停的。 | 3 |
background | 设置或返回在一个声明中的所有背景属性。 | 1 |
backgroundAttachment | 设置或返回背景图像是否固定或随页面滚动。 | 1 |
backgroundColor | 设置或返回元素的背景色。 | 1 |
backgroundImage | 设置或返回元素的背景图像。 | 1 |
backgroundPosition | 设置或返回的背景图像的起始位置。 | 1 |
backgroundRepeat | 设置或返回如何重复背景图像。 | 1 |
backgroundClip | 设置或返回背景的绘制区域。 | 3 |
backgroundOrigin | 设置或返回背景图像的定位区域。 | 3 |
backgroundSize | 设置或返回背景图像的大小。 | 3 |
backfaceVisibility | 设置或返回当一个元素背对屏幕时是否可见。 | 3 |
border | 设置或返回在一个声明中的 borderWidth、borderStyle 和 borderColor。 | 1 |
borderBottom | 设置或返回在一个声明中的所有 borderBottom* 属性。 | 1 |
borderBottomColor | 设置或返回下边框的颜色。 | 1 |
borderBottomLeftRadius | 设置或返回左下角边框的形状。 | 3 |
borderBottomRightRadius | 设置或返回右下角边框的形状。 | 3 |
borderBottomStyle | 设置或返回下边框的样式。 | 1 |
borderBottomWidth | 设置或返回下边框的宽度。 | 1 |
borderCollapse | 设置或返回表格的边框是否被折叠为一个单一的边框。 | 2 |
borderColor | 设置或返回元素边框的颜色(最多可以有四个值)。 | 1 |
borderImage | 一个用于设置或返回所有的 borderImage* 属性的速记属性。 | 3 |
borderImageOutset | 设置或返回边框图像区域超出边界框的量。 | 3 |
borderImageRepeat | 设置或返回图像边框是重复拼接图块还是延伸图块。 | 3 |
borderImageSlice | 设置或返回图像边框的向内偏移。 | 3 |
borderImageSource | 设置或返回要作为边框使用的图像。 | 3 |
borderImageWidth | 设置或返回图像边框的宽度。 | 3 |
borderLeft | 设置或返回在一个声明中的所有 borderLeft* 属性。 | 1 |
borderLeftColor | 设置或返回左边框的颜色。 | 1 |
borderLeftStyle | 设置或返回左边框的样式。 | 1 |
borderLeftWidth | 设置或返回左边框的宽度。 | 1 |
borderRadius | 一个用于设置或返回四个 border*Radius 属性的速记属性。 | 3 |
borderRight | 设置或返回在一个声明中的所有 borderRight* 属性。 | 1 |
borderRightColor | 设置或返回右边框的颜色。 | 1 |
borderRightStyle | 设置或返回右边框的样式。 | 1 |
borderRightWidth | 设置或返回右边框的宽度。 | 1 |
borderSpacing | 设置或返回表格中单元格之间的距离。 | 2 |
borderStyle | 设置或返回元素边框的样式(最多可以有四个值)。 | 1 |
borderTop | 设置或返回在一个声明中的所有 borderTop* 属性。 | 1 |
borderTopColor | 设置或返回上边框的颜色。 | 1 |
borderTopLeftRadius | 设置或返回左上角边框的形状。 | 3 |
borderTopRightRadius | 设置或返回右上角边框的形状。 | 3 |
borderTopStyle | 设置或返回上边框的样式。 | 1 |
borderTopWidth | 设置或返回上边框的宽度。 | 1 |
borderWidth | 设置或返回元素边框的宽度(最多可以有四个值)。 | 1 |
bottom | 设置或返回定位元素的底部位置。 | 2 |
boxDecorationBreak | 设置或返回分页处元素的背景和边框行为,或者换行处内联元素的背景和边框行为。 | 3 |
boxShadow | 设置或返回元素的下拉阴影。 | 3 |
boxSizing | 允许您以特定的方式定义匹配某个区域的特定元素。 | 3 |
captionSide | 设置或返回表格标题的位置。 | 2 |
clear | 设置或返回元素相对浮动对象的位置。 | 1 |
clip | 设置或返回定位元素的可见部分。 | 2 |
color | 设置或返回文本的颜色。 | 1 |
columnCount | 设置或返回元素应该被划分的列数。 | 3 |
columnFill | 设置或返回如何填充列。 | 3 |
columnGap | 设置或返回列之间的间隔。 | 3 |
columnRule | 一个用于设置或返回所有的 columnRule* 属性的速记属性。 | 3 |
columnRuleColor | 设置或返回列之间的颜色规则。 | 3 |
columnRuleStyle | 设置或返回列之间的样式规则。 | 3 |
columnRuleWidth | 设置或返回列之间的宽度规则。 | 3 |
columns | 一个用于设置或返回 columnWidth 和 columnCount 的速记属性。 | 3 |
columnSpan | 设置或返回一个元素应横跨多少列。 | 3 |
columnWidth | 设置或返回列的宽度。 | 3 |
content | 与 :before 和 :after 伪元素一起使用,来插入生成的内容。 | 2 |
counterIncrement | 增加一个或多个计数器。 | 2 |
counterReset | 创建或重置一个或多个计数器。 | 2 |
cursor | 设置或返回鼠标指针显示的光标类型。 | 2 |
direction | 设置或返回文本的方向。 | 2 |
display | 设置或返回元素的显示类型。 | 1 |
emptyCells | 设置或返回是否显示表格中的空单元格的边框和背景。 | 2 |
filter | 设置或返回图片滤镜(可视效果,如:高斯模糊与饱和度) | 3 |
flex | 相对于同一容器其他灵活的项目,设置或返回项目的长度。 | 3 |
flexBasis | 设置或灵活项目的初始长度。 | 3 |
flexDirection | 设置或返回灵活项目的方向。 | 3 |
flexFlow | 是 flexDirection 和 flexWrap 属性的速记属性。 | 3 |
flexGrow | 设置或返回项目将相对于同一容器内其他灵活的项目进行扩展的量。 | 3 |
flexShrink | 设置或返回项目将相对于同一容器内其他灵活的项目进行收缩的量。 | 3 |
flexWrap | 设置或返回灵活项目是否拆行或拆列。 | 3 |
cssFloat | 设置或返回元素的水平对齐方式。 | 1 |
font | 设置或返回一个声明中的 fontStyle、fontVariant、fontWeight、fontSize、lineHeight 和 fontFamily。 | 1 |
fontFamily | 设置或返回文本的字体。 | 1 |
fontSize | 设置或返回文本的字体尺寸。 | 1 |
fontStyle | 设置或返回字体样式是否是 normal(正常的)、italic(斜体)或 oblique(倾斜的)。 | 1 |
fontVariant | 设置或返回是否以小型大写字母显示字体。 | 1 |
fontWeight | 设置或返回字体的粗细。 | 1 |
fontSizeAdjust | 当使用备用字体时,确保文本的可读性。 | 3 |
fontStretch | 从字体库中选择一种正常的、浓缩的或扩大的字体。 | 3 |
hangingPunctuation | 规定一个标点符号是否可以放置在线框外。 | 3 |
height | 设置或返回元素的高度。 | 1 |
hyphens | 设置如何拆分单词来提高段落布局。 | 3 |
icon | 向作者提供为一个带有等价于图标的元素定义样式的功能。 | 3 |
imageOrientation | 规定一个用户代理应用到图像上的顺时针方向的旋转。 | 3 |
justifyContent | 设置或返回当灵活容器内的各项没有占用所有可用的空间时各项之间的对齐方式(垂直)。 | 3 |
left | 设置或返回定位元素的左部位置。 | 2 |
letterSpacing | 设置或返回文本中字符之间的空间。 | 1 |
lineHeight | 设置或返回在文本中行之间的距离。 | 1 |
listStyle | 设置或返回一个声明中的 listStyleImage、listStylePosition 和 listStyleType。 | 1 |
listStyleImage | 设置或返回作为列表项标记的图像。 | 1 |
listStylePosition | 设置或返回列表项标记的位置。 | 1 |
listStyleType | 设置或返回列表项标记的类型。 | 1 |
margin | 设置或返回元素的外边距(最多可以有四个值)。 | 1 |
marginBottom | 设置或返回元素的的下外边距。 | 1 |
marginLeft | 设置或返回元素的左外边距。 | 1 |
marginRight | 设置或返回元素的右外边距。 | 1 |
marginTop | 设置或返回元素的上外边距。 | 1 |
maxHeight | 设置或返回元素的最大高度。 | 2 |
maxWidth | 设置或返回元素的最大宽度。 | 2 |
minHeight | 设置或返回元素的最小高度。 | 2 |
minWidth | 设置或返回元素的最小宽度。 | 2 |
navDown | 设置或返回当使用向下箭头导航键时要导航到哪里。 | 3 |
navIndex | 设置或返回元素的显示顺序。 | 3 |
navLeft | 设置或返回当使用向左箭头导航键时要导航到哪里。 | 3 |
navRight | 设置或返回当使用向右箭头导航键时要导航到哪里。 | 3 |
navUp | 设置或返回当使用向上箭头导航键时要导航到哪里。 | 3 |
opacity | 设置或返回元素的不透明度。 | 3 |
order | 设置或返回一个灵活的项目相对于同一容器内其他灵活项目的顺序。 | 3 |
orphans | 设置或返回当元素内有分页时,必须在页面底部预留的最小行数。 | 2 |
outline | 设置或返回在一个声明中的所有 outline 属性。 | 2 |
outlineColor | 设置或返回一个元素周围的轮廓颜色。 | 2 |
outlineOffset | 对轮廓进行偏移,并在边框边缘进行绘制。 | 3 |
outlineStyle | 设置或返回一个元素周围的轮廓样式。 | 2 |
outlineWidth | 设置或返回一个元素周围的轮廓宽度。 | 2 |
overflow | 设置或返回如何处理呈现在元素框外面的内容。 | 2 |
overflowX | 规定如果内容溢出元素的内容区域,是否对内容的左/右边缘进行裁剪。 | 3 |
overflowY | 规定如果内容溢出元素的内容区域,是否对内容的上/下边缘进行裁剪。 | 3 |
padding | 设置或返回元素的内边距(最多可以有四个值)。 | 1 |
paddingBottom | 设置或返回元素的下内边距。 | 1 |
paddingLeft | 设置或返回元素的左内边距。 | 1 |
paddingRight | 设置或返回元素的右内边距。 | 1 |
paddingTop | 设置或返回元素的上内边距。 | 1 |
pageBreakAfter | 设置或返回元素后的分页行为。 | 2 |
pageBreakBefore | 设置或返回元素前的分页行为。 | 2 |
pageBreakInside | 设置或返回元素内的分页行为。 | 2 |
perspective | 设置或返回 3D 元素被查看的视角。 | 3 |
perspectiveOrigin | 设置或返回 3D 元素的底部位置。 | 3 |
position | 设置或返回用于元素定位方法的类型(static、relative、absolute 或 fixed)。 | 2 |
quotes | 设置或返回嵌入引用的引号类型。 | 2 |
resize | 设置或返回是否可由用户调整元素的尺寸大小。 | 3 |
right | 设置或返回定位元素的右部位置。 | 2 |
tableLayout | 设置或返回表格单元格、行、列的布局方式。 | 2 |
tabSize | 设置或返回制表符(tab)字符的长度。 | 3 |
textAlign | 设置或返回文本的水平对齐方式。 | 1 |
textAlignLast | 设置或返回当 text-align 属性设置为 "justify" 时,如何对齐一个强制换行符前的最后一行。 | 3 |
textDecoration | 设置或返回文本的修饰。 | 1 |
textDecorationColor | 设置或返回文本修饰的颜色。 | 3 |
textDecorationLine | 设置或返回文本修饰要使用的线条类型。 | 3 |
textDecorationStyle | 设置或返回文本修饰中的线条样式。 | 3 |
textIndent | 设置或返回文本第一行的缩进。 | 1 |
textJustify | 设置或返回当 text-align 属性设置为 "justify" 时,要使用的对齐方法。 | 3 |
textOverflow | 设置或返回当文本溢出包含它的元素,应该发生什么。 | 3 |
textShadow | 设置或返回文本的阴影效果。 | 3 |
textTransform | 设置或返回文本的大小写。 | 1 |
top | 设置或返回定位元素的顶部位置。 | 2 |
transform | 向元素应用 2D 或 3D 转换。 | 3 |
transformOrigin | 设置或返回被转换元素的位置。 | 3 |
transformStyle | 设置或返回被嵌套的元素如何呈现在 3D 空间中。 | 3 |
transition | 一个用于设置或返回四个过渡属性的速记属性。 | 3 |
transitionProperty | 应用过渡效果的 CSS 属性的名称。 | 3 |
transitionDuration | 设置或返回完成过渡效果需要花费的时间(以秒或毫秒计)。 | 3 |
transitionTimingFunction | 设置或返回过渡效果的速度曲线。 | 3 |
transitionDelay | 设置或返回过渡效果何时开始。 | 3 |
unicodeBidi | 设置或返回文本是否被重写,以便在同一文档中支持多种语言。 | 2 |
verticalAlign | 设置或返回元素中内容的垂直对齐方式。 | 1 |
visibility | 设置或返回元素是否应该是可见的。 | 2 |
whiteSpace | 设置或返回如何处理文本中的制表符、换行符和空格符。 | 1 |
width | 设置或返回元素的宽度。 | 1 |
wordBreak | 设置或返回非 CJK 语言的换行规则。 | 3 |
wordSpacing | 设置或返回文本中单词之间的空间。 | 1 |
wordWrap | 允许长单词或 URL 地址换行到下一行。 | 3 |
widows | 设置或返回一个元素必须在页面顶部的可见行的最小数量。 | 2 |
zIndex | 设置或返回定位元素的堆叠顺序。 | 2 |
如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!
为前端,和业务上下游交流数据的时候,经常会出现页面 PV、UV、点击率、转化率等中英混杂不知所云的名词。特别是在存量竞争的当下,数据更是频频出现在高层的目标和规划中。
那么,当我们,一个前端同学,谈起数据时,我们在谈些什么呢?
追本溯源
我们先抛开 spm 这些埋点名词,从一个行外人的角度来审视用户的交互过程。
让我们先从一个页面开始。
前端永远是从一个页面开始。
这个页面可能是一个内容流如各大内容平台的首页,可能是一个详情页,可能是一个会场页(如果你更容易理解的话):
看起来有点花哨?没关系,我们来抽象一下。这,就是我们的页面:
当然,我们的页面自然也不是孤立的。它与其它千千万万个页面一起,互相联系,构成了吞噬你我业余时光的时间黑洞:
作为页面的开发者,最基本的,我们要做好页面的渲染、功能的交互、跳转的响应。
然后,就可以了,吗?
如果作为一个独立的博客网站,往互联网里一丢,圈地自萌就好了。
用户来了,玩了,爽了,走了,不带走一片云彩。
但是作为一个商业公司,我们开发的页面需要产生价值。
玩爽了是要给钱的。
怎么给呢?
淘宝,本身就是一个卖货的场,从一个商品引流到另一个商品,从一个类目关联到更多类目,从卫生纸一路买到电视机。
我们希望用户在我们的业务里花更多时间,看更多东西,下更多订单。
这个时候,我们的页面更像是一个观光车:从火车站招揽游客上车,拉他们去看彩色兵马俑:
为了从商家拿到更多的回扣,出租车司机会主动去人流量大的场所拉客,旅行社会在签约前给到足够多的情绪价值,导游会不遗余力地把游客往玉石店里拉。
这个几乎出于本能的循环有足够强的自驱力,它能一直运行到市场监督管理局或央视的介入。
这个循环本身不需要数据。
数据的引入是为了优化这个循环。
为什么要优化这个循环?
因为我们希望有更多的人进来,更少的人流失,更多的人到达目的地,买票参观,这样我们才能从景区手里拿到更多的回扣、返点。
用户交互也一样。
我们希望有更多的人来看我们的页面,更多的比例引导到商品域,更多的人下单,从而收取更多的佣金。
为了追求这个目标,我们需要知道:
知道了这些,我们就能做有针对性的调整:
作为电商频道,交易的绝对值是我们的终极目标。
这就是为什么,我们大多数业务都在致力于提升页面的流量、用户停留、转化率。
而哪怕是一些与交易可能没有直接关系的,比如蚂蚁森林,只要能够增加用户的回访和停留,我们也总有办法从中获取权益。
做出我们自己的数据产品
看到这里,你也许会诧异,原来我们的数据目标这么简单而明确,为什么集团那么多花里胡哨的东西,看都看不懂!
刚好,我也是这么想的。不如我们另起炉灶!
先来明确一下我们的任务:
明确下来,只有三个内容:
So easy!
整套数据产品里,最核心的就是,如何感知页面的跳转行为。知道这个,我们才有可能将成交和引导页关联起来,进而通过引导页的优化来促进成交。
假设我们有这么个场景:用户在浏览时,看到一条广告,被引流到首页,最终在商详页完成下单:
要感知页面之间的行为,首先要认识页面,给每个页面独一无二的标识。
先来快速科普一下。对于浏览器来说,页面就是一条链接。www.taobao.com就是淘宝的页面。(APP 里略有差异,不遵循 web 的网页协议,但是原理是差不多的,也是一长串乱糟糟的字母。)
一条网页链接通常长这样,详细可以看这里:
重点关注 Parameters 这部分,它的结构是用 & 符号分隔的键/值对列表:
这个叫参数,有了它我们就能在一条资源链接上实现更多玩法。
比如,通过拼接商品 id 的参数,就能实现不同商品的浏览:
https://item.taobao.com/item.html?id=1111111111111 和
https://item.taobao.com/item.html?id=22222222222 就是两个不同商品的详情页。
那怎么知道一个页面是从哪个页面过来的呢?我们就可以通过约定一个 from 参数来传递:
www.item.taobao.com?id=1111111111&from=首页
这就表示用户从首页过来,访问了商品 1111111111。
我们的页面只要从链接上读到 from=xxx 参数,就代表用户是从那个源头过来的。
另一个关于网页的小知识点是:链接后的参数可以随意加,参数有没有用取决于页面有没有使用到。
比如在 www.item.taobao.com 后加 id 参数有用,但是在 www.taobao.com 后加 id 参数就不起作用,因为首页不消费 id 参数。
我们需要页面去消费 from 参数。
因此,基于上述约定,我们还需要在页面代码侧做具体的实现:
这样,我们就能够统计出如下信息:
恭喜你,已经成功做出了丐版的 spm 和上报 SDK。
接下来就是数据任务了,将所有页面繁杂的流量和来源日志处理成符合我们需要的数据结构。
最后,当我们给出一个页面标识,就能查出这个页面的流量、来源、去向。
但是我不会写 sql……新和联胜的计划只能中道崩殂了。
重新认识一下集团的数据方案
现在我们可以重新认识一下 spm了。
spm(Super Position Model,超级位置模型)是阿里埋点体系的重要规范,它的作用就是为每一个页面添加了一个独立的标识。阿里的spm位置编码由A.B.C.D四段构成, 各分段分别代表 A:站点/业务, B:页面, C:页面区块, D:区块内点。
假设我们现在做羽毛球行业的业务,该业务下有许多页面:
那么我们就能够轻松确定各个页面的 SPM 分别是 羽毛球行业.营销页、羽毛球行业.商详、羽毛球行业.店铺。
那么问题来了,既然 B 位代表了页面,为什么我们还需要 A 位呢?
我个人的理解,引入 A 位的好处是 B 位的定义可以更加语义化且业务无关,也可以通过 A 位对业务下的多个页面做统计分析。当然后者对业务同学可能更重要些。但作为前端同学,还是比较关心前者,毕竟命名真的是太难了。
既然 spmA.spmB 已经可以确定一个页面的标识,后面两位是什么作用呢?
让我们稍微细化一下场景。
假如我们营销页现在有两个活动,秒杀活动和场景购都导流到同一个商详页:
看起来没有什么问题。
让我们把视角放到商详页。你会发现它只能感知用户是从营销页过来,而不知道具体哪个活动导流过来的。相应的,秒杀业务的同学也无法感知模块的引导效率。
spmC 位和 spmD 位就是为了解决页面精准定位的需要。
当用户点击了秒杀模块的商品 2 时,商详页感知到的来源就是 羽毛球行业.营销页.秒杀.商品2,既有来源页,又有来源页的具体点击位置。如果统计页面维度的引导效率,可以只消费 spmA.spmB。如果有更细粒度的分析需求,也有相应的数据做支持。
spm 参数同样是通过 url 参数传递的。如果大家留意一下正在看的这篇文章的链接,可能会发现这么个 spm 参数:
前两位分别代表了 ata 业务和 2xxxxxx0 页面。
spmC 和 spmD 位是 0.0,这是因为 ata 不关心模块级的引导,给的默认值。
细心的同学可能注意到在 spmD 位之后还有一串乱七八糟的字符, SPM 官方解释是这样的:
看不懂吧。这描述确实太技术了,我来翻译一下:
不关你事!莫挨劳资!
通过 SPM 规范,我们能够定位到一个页面中的任意位置。
不过就像前面说的,约定 just 约定,在没有实现之前就只是概念而已。
前面提到,这套体系要运转起来,需要所有页面都统一动作:保证自己有一个 spm id,且在渲染时消费外部带过来的 spm,跳转时拼接自身的 spm。
从原理上分析,这就是个横向项目,需要自上而下的推广。
阿里集团侧给出的方案是一套上报工具 SDK。页面内集成这套脚本之后,它会做两件事:页面曝光上报、跳转链接劫持等。
一个页面有两个 spm 相关的参数:
页面加载后,SDK 会做页面曝光上报,携带自身 spm 和来源 spm。
对跳转链接的拦截是通过对 a 标签的点击事件拦截实现的。它会自动往其 href 属性上拼接页面的 spmA.spmB,如果 a 标签被包裹在区块或点击热区内,还会进一步携带上 spmC.spmD,以标识该跳转的点击来源。
前端同学请注意
从 SDK 的实现原理不难发现,如果跳转不是通过 a 标签完成的,那这个劫持就失效了。进而,二跳页就会失去当前页面的来源信息。
因为 a 标签的样式问题和默认行为问题,以及点击行为通常存在跳转前的逻辑处理等,前端同学更倾向使用 js 方式跳转页面,这时就需要特别关注下,有没有做好 spm 信息的手动拼接。
因为 spm 参数是依赖网页链接的,在这条链路下面没有任何问题。
但是当某个页面被分享出去时,分享链接里携带了 页面1 的 spm。所有从该分享链接进入的流量,SDK 也会认为它是来自页面 1 的,进而出现页面 1 引导到页面 2 的流量比页面 1 本身的流量大的多的情况。
比如你把当前页面链接分享出去:
别人通过你的链接访问,由于 spm 的传递特性,SDK 仍会认为用户是从首页过来的,进而计入首页的引导转化。
在具体实践中,除了统计页面的来源页面,还会统计页面来源页面的来源页面:
还拿这个例子,页面 3 不但知道用户是从页面 2 过来的,还知道用户在此之前访问了页面 1。
是怎么做到的呢?
答案就是 Referer 请求头:Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。
别忘了,我们的 spm 数据就藏在 url 上。
能拿到上一个页面的 url,自然就能够从当前页面感知到上上一个页面。
(对于一些拿不到 referer 请求头的场景「比如小程序」,业务实现上会往 url 上加 preSpm 参数,实现对来源页来源的感知)。
那么,你可能又要问了,为什么不统计来源页面的来源页面的来源页面,乃至于无限套娃呢?
我个人理解,这一方面是技术问题,另一方面也是成本和需求的平衡:
成本上,我们是否需要记录这么长的用户路径。因为考虑到存取的需求,路径必然是可枚举的。
技术上,有一个奥卡姆剃刀原理:如无必要,勿增实体。意思是不做无谓的复杂度升级。仅仅是往 url 上拼接 spm 参数,就已经需要集全集团之力,反复宣导,尚且常有漏报错报。如果要再增加 preSpm,乃至 prePreSpm,系统的稳健性乃至数据结果的可信度必然要打折扣。
除了关注页面流量和跳转情况,我们还是希望感知到用户在当前页面里做了什么。感知的其中一个目的,就是为了改善页面的跳转率。
当用户进入页面,到执行跳转前,通常有一些必须的行为。我们就可以通过考察用户在每个步骤中的行为情况,最终提高进入跳转的用户量:
页面 pv 和黄金令箭埋点通常被认为是两种东西。但从前端角度来看,它们都只是一个发向日志服务器的 http 请求。只不过在后续的数据任务处理中会有差别。(当然,在端侧,为了统计页面的停留时长,页面 pv 的发送时机也会有些变化,不过这些也不需要前端开发者去感知。)
现在我们可以梳理一下 SDK 在用户访问页面的过程中都做了什么事:
借助 SPM 体系和 SDK 方案,我们现在有了用户的访问路径。我们的最终目标是知道每个页面究竟创造了多少下单。
用户浏览产生页面交互数据,用户下单产生订单数据。我们需要把用户的浏览行为和下单结果关联起来。
这更多是一个数据任务。
在计算引导成交时,会涉及到两个概念:
在目标页的来源页和来源页的来源页里找到了当前页的 spm,就认为是当前页的引导数据。
根据路径不同:
根据目标页类型的不同
其指标关系如下:
从上图我们可以直观地发现:全引导进店的口径是最大的,直接引导宝贝的口径是最小的。
成交的口径就比较简单了。用户对该商品有购买记录,就认为用户这天有成交。
引导成交的纸面意义是:用户通过我们的页面被引导到目标页,并在目标页完成了下单。我们才将这个用户及其成交情况计作当前页的成果。
但是从上面提到的统计口径来看,成交和引导其实是两个相对独立的事件。
根据引导类型的不同,又能够进一步拆分为直接引导宝贝成交,直接引导店铺成交……相应的,也有同样的数据关系:
看数
集团除了提供一套上报 SDK,还建设了一个看数平台,将上述提及的所有数据需求汇总在平台上。
我们所有需要的东西就是一个页面 spm,在平台上检索:
然后你就会得到想要的一切。
页面流量
页面引导转化
页面来源去向
区块分析(包含区块曝光和引导成交)
黄金令箭
FBI 报表
当然,也可以从数据底表里写 sql ,借助 FBI 平台构建可视化效果更好的报表。
结语
尽管数据之路并非总是一帆风顺,诸如数据准确性、技术实现挑战等问题依旧存在,但正因如此,不断探索与优化数据应用的方法显得尤为重要。作为前端开发者,掌握这些知识与技能,意味着能在激烈的市场竞争中,为产品与团队带来更坚实的数据支撑,推动业务持续增长。
总之,当前端谈数据时,我们实际上在谈论如何更好地理解用户、优化体验、驱动决策与创造价值。在这个数据驱动的时代,每一位前端同学都是数据海洋中的领航员,用代码编织数据的网,捕捉商业成功的浪花。
作者:子虫
来源-微信公众号:大淘宝技术
出处:https://mp.weixin.qq.com/s/fN0XiCvcLqAEXcHwxo1D0w
*请认真填写需求信息,我们会在24小时内与您取得联系。