我一直很喜欢标签云,我喜欢通过查看它们的相对字体大小来了解网站上哪些是最受欢迎的标签,流行的标签更大。制作标签云有多难?这一点都不难。让我们来看看!让我们从HTML开始对于我们的HTML,我们会将每个标签放入一个列表中,我们将使用JavaScript将其注入。我模拟了一些JSON,每个属性都有一定数量的文章标签。让我们编写一些JavaScript来获取JSON提要并做三件事。首先,我们将从列表中的每个条目创建一个- 。想象一下到目前为止的HTML:
- align-content
- align-items
- align-self
- animation
- ...
- z-index
其次,我们将每个属性的文章数放在每个列表项旁边的括号中。所以现在,标签看起来像这样:align-content(2)align-items(2)align-self(2)animation(9)...z-index(4)第三也是最后,我们A将在每个标记周围创建链接,该链接将转到正确的位置。在这里我们可以为每个项目设置font-size属性,这取决于有多少篇文章标有该属性。动画(9)JavasScript部分让我们看看执行此操作的JavaScript。constdataURL="https://gist.githubusercontent.com/markconroy/536228ed416a551de8852b74615e55dd/raw/9b96c9049b10e7e18ee922b4caf9167acb4efdd6/tags.json";const标签=document.querySelector(".tags");constfragment=document.createDocument();constfragment=document.createDocument()maxFontSizeForTag=6;fetch(dataURL).then(function(res){returnres.json();}).then(function(data){//1.从数据创建新数组letorderedData=data.map((x)=>x);//2.按每个标签的文章数排序orderedData.sort(function(a,b){returna.tagged_articles.length-b.tagged_articles.length;});orderedData=orderedData.reverse();//3.获取包含最多文章的标签的值consthighestValue=orderedData[0].tagged_articles.length;//4.为数据中的每个结果创建一个列表项data.forEach((result)=>handleResult(result,highestValue));//5.将完整的标签列表附加到标签元素tags.appendChild(tag);});上面的JavaScript使用FetchAPI获取tags.json所在的URL。这里我们插入一个新的数组,叫做orderedData(所以我们不改变原来的数组),找到包含最多文章的标签。我们稍后会在font-size中使用这个值,这样所有其他标签都会有一个相对于它的font-size。然后,根据响应中的forEach结果,我们调用一个名为handleResult()的函数,并将结果和highestValue作为参数传递给该函数。它还创建了:一个名为tags的变量,我们将使用它来注入从结果创建的每个列表项fragment的变量,以保存循环每次迭代的结果,稍后我们将其附加到标签和最大字体大小的变量,稍后将在字体比例中使用。接下来是handleResult(result)函数:functionhandleResult(result,highestValue){consttag=document.createElement("li");tag.classList.add("标签");tag.innerHTML=`${result.title}(${result.tagged_articles.length})`;//将每个标签附加到片段fragmentfragment.appendChild(tag);}这是一个非常简单的函数,它创建一个列表元素并将其设置为一个名为tag的变量,然后这个列表元素添加一个.tag类。创建后,它将列表项的innerHTML设置为链接,并使用来自JSON提要的值填充该链接的值(例如,标签链接的result.href)。当创建每个li时,它将作为字符串添加到片段中,稍后我们将其附加到tags变量中。这里最重要的项目是内联样式标签,它使用文章的数量——result.tagged_articles.length——为这个列表项目设置一个以em为单位的相对字体大小。稍后,我们会将此值更改为公式以使用基本字体比例。我发现这个JavaScript有点丑陋且难以理解,所以让我们为每个属性创建一些变量和一个简单的字体比例公式来整理并使其更易于阅读。functionhandleResult(result,highestValue){//设置我们的变量constname=result.title;constlink=result.href;constnumberOfArticles=result.tagged_articles.length;让fontSize=numberOfArticles/highestValue*maxFontSizeForTag;fontSize=+fontSize.toFixed(2);constfontSizeProperty=`${fontSize}em`;//为每个具有内联字体大小的标签创建一个列表元素consttag=document.createElement("li");tag.classList.add("标签");tag.innerHTML=`${name}(${numberOfArticles})`;//将每个标签附加到片段fragment.appendChild(tag);}通过在创建HTML之前设置一些变量使代码更易于阅读。而且它还使我们的代码更加DRY,因为我们可以在多个地方使用numberOfArticles变量。在此.forEach循环中返回每个标签后,它们将一起收集在片段中。之后,我们使用appendChild()将它们添加到标签元素中。这意味着DOM只被操作一次,而不是每次循环运行时,如果我们碰巧有大量标签,这是一个很好的性能提升。字体缩放与我们现有的东西配合得很好,我们可以开始编写CSS。然而,我们的fontSize变量公式意味着文章最多的标签(又名“flex”有25篇文章)将为6em(25/256=6),但只有一篇文章的标签将为1其大小/25(1/256=0.24),使内容不可读。如果我们有一个包含100篇文章的选项卡,较小的选项卡会更差(1/100*6=0.06)。为了解决这个问题,我添加了一个简单的if语句,如果返回的fontSize小于1,则将fontSize设置为1。所有标签现在的字体范围为1em到6em,四舍五入到小数点后两位。要增加最大标签大小,只需更改maxFontSizeForTag的值。您可以根据您处理的内容量来决定什么最适合您。functionhandleResult(result,highestValue){//设置变量constnumberOfArticles=result.tagged_articles.length;constname=result.title;constlink=result.href;让fontSize=numberOfArticles/highestValue*maxFontSizeForTag;fontSize=+fontSize.toFixed(2);//确保我们的字体大小至少为1emif(fontSize<=1){fontSize=1;}else{fontSize=fontSize;}constfontSizeProperty=`${fontSize}em`;//然后,为每个具有内联字体大小的标签创建一个列表元素。tag=document.createElement("li");tag.classList.add("标签");tag.innerHTML=`${name}(${numberOfArticles})`;//将每个标签附加到片段fragment.appendChild(tag);写CSS!我们在布局中使用flexbox,因为每个标签的宽度都可以变化。然后我们使用justify-content:center将它们居中并删除列表项目符号。.tags{显示:flex;弹性包装:包装;证明内容:居中;最大宽度:960px;保证金:自动;填充:2rem01rem;列表样式:无;:5px;}我们还将为各个标签使用flexbox。这样我们就可以使用align-items:center进行垂直对齐,因为它们会根据字体大小具有不同的高度。.tag{显示:flex;对齐项目:居中;margin:0.25rem1rem;}标签云中的每个链接都有一点填充,只是为了使其在严格尺寸之外可以轻微点击。.tag__link{填充:5px5px0;过渡:0.3s;text-decoration:none;}我发现这在小屏幕上非常方便,特别是对于那些可能很难点击链接的人。去掉了原来的text-decoration是因为我觉得我们可以假设标签云中的每段文字都是一个链接,所以不需要对它们进行特殊的修饰。我要添加一些颜色以获得更好的外观:.tag:nth-of-type(4n+1).tag__link{color:#ffd560;}.tag:nth-of-type(4n+2).tag__link{颜色:#ee4266;}.tag:nth-of-type(4n+3).tag__link{color:#9e88f7;}.tag:nth-of-type(4n+4).tag__link{颜色:#54d0ff;这个配色方案是直接从Chris的blogroll上偷来的,从tab1开始每隔四个tab是黄色的,从tab2开始每隔四个tab是红色的,从tab3开始每隔四个tab是紫色的。然后我们为每个链接设置焦点和悬停状态:.tag:nth-of-type(4n+1).tag__link:focus,.tag:nth-of-type(4n+1).tag__link:hover{box-shadow:inset0-1.3em00#ffd560;}.tag:nth-of-type(4n+2).tag__link:focus,.tag:nth-of-type(4n+2).tag__link:hover{框-阴影:插图0-1.3em00#ee4266;}.tag:nth-of-type(4n+3).tag__link:focus,.tag:nth-of-type(4n+3).tag__link:hover{box-shadow:inset0-1.3em00#9e88f7;}.tag:nth-of-type(4n+4).tag__link:focus,.tag:nth-of-type(4n+4).tag__link:hover{box-shadow:inset0-1.3em00#54d0ff;}我可以在这个阶段为颜色创建自定义变量,比如--yellow:#ffd560等,但为了支持IE11,我决定使用手写法。我喜欢box-shadow悬停效果,它只需要很少的代码就可以实现比标准下划线或底部边框更直观的效果。在这里使用em单位意味着我们可以微调阴影相对于它需要覆盖的文本的大小。首先,将每个标签链接设置为黑色悬停:.tag:nth-of-type(4n+1).tag__link:focus,.tag:nth-of-type(4n+1).tag__link:hover,.tag:nth-of-type(4n+2).tag__link:focus,.tag:nth-of-type(4n+2).tag__link:hover,.tag:nth-of-type(4n+3).tag__link:focus,.tag:nth-of-type(4n+3).tag__link:hover,.tag:nth-of-type(4n+4).tag__link:focus,.tag:nth-of-type(4n+4).tag__link:hover{color:black;}我们完成了!这是最终结果: