如何使用Javascript动态生成面包屑模式



以下是实际用于显示每页上的面包屑的HTML

<c:forEach items="${breadcrumbArray}" var="breadcrumb" varStatus="loopCounter">
<c:if test="${breadcrumb ne 'store'}">
<li class="breadcrumb__item">
<c:choose>
<c:when test="${not loopCounter.last}">                                    
<a href="/${breadcrumb}">${breadcrumb}</a>                             
</c:when>
<c:otherwise>
${fn:replace(breadcrumb, '-', ' ')}
</c:otherwise>
</c:choose>
</li>
</c:if>
</c:forEach>

用于动态生成模式的Javascript

<script type="text/javascript">
$(document).ready(function(){
var el = document.createElement('script');
el.type = 'application/ld+json';
el.text = JSON.stringify({ "@context": "https://schema.org/",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": "",
"item": ""                                     
}]
});
document.querySelector('head').appendChild(el);
});
</script>

例如;主页>我们的使命>"我们是谁";应该像这样生成:

<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://corp.com/"
},{
"@type": "ListItem",
"position": 2,
"name": "Our Mission",
"item": "https://corp.com/our-mission/"
},{
"@type": "ListItem",
"position": 3,
"name": "Who We Are",
"item": "https://corp.com/our-mission/who-we-are"
}]
}
</script>

脚本未附加到"head"标记。。

这个有几个部分。

第一:脚本未附加到"head"标记

这可能需要更多信息,代码中的内容至少应该在head中呈现JSON-LDscript标记。您的环境中可能发生了一些事情,使您无法向head进行写入。您可以尝试将代码更改为类似以下内容:

document.head.appendChild(el)document.getElementsByTagName('head')[0].appendChild(el)(如果需要支持较旧的浏览器(。

更多信息可以在这些SO线程中找到:

  • 使用document.head.appendChild((来附加具有SRC属性的脚本标记
  • document.head v.document.getElementsByTagName("head"([0]

我再次怀疑这就是问题所在。我也会尝试在页面上的其他地方呈现script,而不是head,看看这是否适用于您(也相关,请参阅本答案末尾的最后一条注释(。

第二:使用JavaScript创建JSON-LD

以下是一个粗略的、无jQuery但与ES5兼容的解决方案,用于生成以下内容:

HTML

<ol class="breadcrumbs">
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page1">Page 1</a>
</li>
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page2">Page 2</a>
</li>
<li class="breadcrumb-item">
<a class="breadcrumb-link" href="https://mypage.com/page3">Page 3</a>
</li>
</ol>
<!-- Testing Purposes -->
<div class="output"></div>

JavaScript

// Create Script
var el = document.createElement('script');
el.type = 'application/ld+json';
// Set initial position
var position = 0;
// Create breadcrumb object
var breadcrumb = {
position:0,
name:"",
item:""
}
// Empty array for list items
var listArray = []
// Loop through each breadcrumb link and set attributes
var items = document.querySelectorAll('.breadcrumb-link');
for(var i = 0; i < items.length; i++) {
var newItem = Object.create(breadcrumb);
var curItem = items[i];
newItem["@type"] = "ListItem";
position++;
newItem.position = position;
newItem.name = curItem.text;
newItem.item = curItem.getAttribute('href');
listArray.push(newItem);
}
// Create overarching Schema object
var breadcrumbSchema = {
"@context": "https://schema.org/",
"@type": "BreadcrumbList",
"itemListElement": listArray
};
// Stringify JSON
var finalSchema = JSON.stringify(breadcrumbSchema);
// Add schema to Script
el.text = finalSchema;
// Set head variable with browser fallback
var head = document.head || document.getElementsByTagName("head")[0];
// Add to head (This won't work in codepen)
head.appendChild(el);
// Testing purposes - Show example of string in HTML
document.querySelector('.output').innerHTML = finalSchema;
// Testing purposes - Inspect source to see script generated inside of the "output" div
document.querySelector('.output').appendChild(el);

以下是CodePen 的示例

第三:你真的想这样做吗

正如一位评论者提到的那样,用JavaScript编写JSON-LD可能是个问题。如果你的意图是SEO相关的,你可能想玩安全的赌注,并呈现这个服务器端。无法保证搜索引擎机器人会捕捉到客户端呈现的类似内容。

更新:看起来谷歌会很好地使用动态渲染的JSON-LD,但这可能仍然是其他搜索引擎的问题。我也喜欢谨慎行事。谢谢@JayGray

如果您必须对JSON-LD的值进行硬编码,正如评论者所提到的,您可以使用仍然支持的RDFa(即使与JSON-LD相比不是首选(。HTML是根据您的代码动态呈现的。下面是schema.org/上BreadcrumbList的一个例子

<ol vocab="https://schema.org/" typeof="BreadcrumbList">
<li property="itemListElement" typeof="ListItem">
<a property="item" typeof="WebPage" href="https://example.com/dresses">
<span property="name">Dresses</span>
</a>
<meta property="position" content="1">
</li>
<li property="itemListElement" typeof="ListItem">
<a property="item" typeof="WebPage" href="https://example.com/dresses/real">
<span property="name">Real Dresses</span>
</a>
<meta property="position" content="2">
</li>
</ol>

(请记住,与JSON-LD不同,RDFa和Microdata如果是动态生成的,将不会被搜索引擎选中(。

最后说明:

尽管建议JSON-LD在head中,但它确实需要在才能正确拾取(至少在谷歌中(。它真的可以在你的内容中的任何地方,它也会起作用。

  • 这里有一篇文章说它不需要在head中
  • 这是谷歌的直接确认

此外,如果您通过结构化数据测试工具运行页面,则正文中的任何JSON-LD仍然可以验证。我想Rich Snippets工具也会验证,但我还没有确认。

我发现我们不需要javascript来动态填充值。HTML5运行良好。下面是我用来呈现模式的最后一个脚本

附言:业务需求是只使用json-ld,而不是rdfa

<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1
"name": "Home",
"item": "${baseURL}",
},
<c:forEach items="${breadcrumbArray}" var="breadcrumb" varStatus="loopCounter">
{
"@type": "ListItem",
"position": ${loopCounter.index+1}
"name": "${fn:replace(breadcrumb, '-', ' ')}",
"item": "${baseURL}${breadcrumbArray[loopCounter.index-1]}/${breadcrumb}",
}
</c:forEach>
]
}
</script>

最新更新