Google Maps v3 - 防止 API 加载 Roboto 字体
Posted
技术标签:
【中文标题】Google Maps v3 - 防止 API 加载 Roboto 字体【英文标题】:Google Maps v3 - prevent API from loading Roboto font 【发布时间】:2014-10-20 20:10:18 【问题描述】:Google 将样式添加到地图容器中以覆盖我的样式。 我知道如何解决这个问题。但是 API (v3.8/9/exp) 也加载了我并不真正需要/不想要的 webfont "Roboto"。
是否有任何设置/选项/解决方法? 我可以阻止 API 添加额外的 CSS 吗?
这是 google-maps-API 添加到我页面的 <head>
的代码:
<style type="text/css">
.gm-style .gm-style-cc span,
.gm-style .gm-style-cc a,
.gm-style .gm-style-mtc div
font-size:10px
</style>
<link type="text/css"
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<style type="text/css">
@media print
.gm-style .gmnoprint,
.gmnoprint
display:none
@media screen
.gm-style .gmnoscreen,
.gmnoscreen
display:none
</style>
<style type="text/css">
.gm-style
font-family: Roboto,Arial,sans-serif;
font-size: 11px;
font-weight: 400;
text-decoration: none
</style>
【问题讨论】:
这是输出吗?很难判断代码本身引用了什么。 @JoshBurgess 是的,这是 google 在包含 maps-api-javascript 时添加到<head>
的内容
由于没有使用旧版本的 gmapsAPI,我无法找到一种方法来阻止 Roboto 在不阻止来自 Apache、IIS 或您正在使用的任何等效项的请求的情况下访问该域。如果这已经足够了,我会将其添加到答案中,但这对我来说似乎是一种逃避。
@pkyeck,看看吧!正在工作!
@coma 可以,谢谢
【参考方案1】:
您可以在 Google 脚本调用它之前替换 insertBefore 方法:
http://jsfiddle.net/coma/7st6d9p2/
var head = document.getElementsByTagName('head')[0];
// Save the original method
var insertBefore = head.insertBefore;
// Replace it!
head.insertBefore = function (newElement, referenceElement)
if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') > -1)
console.info('Prevented Roboto from loading!');
return;
insertBefore.call(head, newElement, referenceElement);
;
// Check it!
new google.maps.Map(document.getElementById('map'),
center : new google.maps.LatLng(51.508742,-0.120850),
zoom : 16,
mapTypeId : google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl : false,
panControl : false,
mapTypeControl : false
);
【讨论】:
感谢您的回答。希望您可以使用某种 API 选项,但这种“黑客”绝对有效:) 我在他们的文档上没有找到任何东西,猜想他们想保留它的风格。顺便说一句,一旦阻止了字体加载,您可以在每次 insertBefore 调用时恢复更改以跳过该更改。 非常感谢!为我工作。 @AymanSalah 或只使用适用于 http 和 https 的newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') !== -1
如果地图是使用 iframe 嵌入的,则此解决方案不起作用,因为 Roboto 字体是由 iframe 文档的 head 部分中的 css 调用加载的,无法访问。有什么提示吗?【参考方案2】:
2017 年 10 月更新
Google 改变了在页面上注入样式的方式。目前他们插入了一个空的 style
元素,然后用 Robot 字体更改了这个样式元素的内容。这是一个新的解决方案:
// Preventing the Google Maps libary from downloading an extra font
(function()
var isRobotoStyle = function (element)
// roboto font download
if (element.href
&& element.href.indexOf('https://fonts.googleapis.com/css?family=Roboto') === 0)
return true;
// roboto style elements
if (element.tagName.toLowerCase() === 'style'
&& element.styleSheet
&& element.styleSheet.cssText
&& element.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0)
element.styleSheet.cssText = '';
return true;
// roboto style elements for other browsers
if (element.tagName.toLowerCase() === 'style'
&& element.innerhtml
&& element.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0)
element.innerHTML = '';
return true;
// when google tries to add empty style
if (element.tagName.toLowerCase() === 'style'
&& !element.styleSheet && !element.innerHTML)
return true;
return false;
// we override these methods only for one particular head element
// default methods for other elements are not affected
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement)
if (!isRobotoStyle(newElement))
insertBefore.call(head, newElement, referenceElement);
;
var appendChild = head.appendChild;
head.appendChild = function (textNode)
if (!isRobotoStyle($(textNode)[0]))
appendChild.call(head, textNode);
;
)();
原始答案
感谢 coma 的解决方案!我还决定拦截覆盖字体系列、字体大小和字体粗细的样式。现代浏览器和 IE8+ 的完整解决方案:
// Preventing the Google Maps libary from downloading an extra font
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement)
// intercept font download
if (newElement.href
&& newElement.href.indexOf('https://fonts.googleapis.com/css?family=Roboto') === 0)
return;
// intercept style elements for IEs
if (newElement.tagName.toLowerCase() === 'style'
&& newElement.styleSheet
&& newElement.styleSheet.cssText
&& newElement.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0)
return;
// intercept style elements for other browsers
if (newElement.tagName.toLowerCase() === 'style'
&& newElement.innerHTML
&& newElement.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0)
return;
insertBefore.call(head, newElement, referenceElement);
;
【讨论】:
太棒了,非常感谢。您可以轻松省略 2 个 jQuery 引用,因此任何人都可以使用它:document.getElementsByTagName('head')[0]
而不是 $('head')[0];
textNode
而不是 $(textNode)[0]
【参考方案3】:
我找到了上述解决方案,以防止带有 Google 地图的网站加载 Roboto。
如果您 - 像我一样 - 使用 Wordpress,可能会有其他插件引用 Google 字体。
但是,我在使用上述代码的一些网站上遇到了困难,因为它的某些部分 (1) 也影响了其他要加载的样式,(2) “杀死”的样式,它故意不仅包含 gm 样式,还包含其他样式样式以及 (3) 不影响其他 Google 字体的加载,其中一个或另一个插件也通过 DOM 操作添加了指向 fonts.googleapis.com 的链接。
以下内容对我有用。它只是阻止其他脚本在其 href 属性中添加任何带有 https://fonts.googleapis.com 的标签。
(function($)
var isGoogleFont = function (element)
// google font download
if (element.href
&& element.href.indexOf('https://fonts.googleapis.com') === 0)
return true;
return false;
// we override these methods only for one particular head element
// default methods for other elements are not affected
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement)
if (!isGoogleFont(newElement))
insertBefore.call(head, newElement, referenceElement);
;
var appendChild = head.appendChild;
head.appendChild = function (textNode)
if (!isGoogleFont($(textNode)[0]))
appendChild.call(head, textNode);
;
)(jQuery);
【讨论】:
首先感谢您的代码。不幸的是,我无法让它发挥作用。当我将它添加到我的子主题的functions.php 文件时,它说:“语法错误,意外'$',期望变量(T_VARIABLE)”,我无法保存文件。知道为什么它不接受 $?以上是关于Google Maps v3 - 防止 API 加载 Roboto 字体的主要内容,如果未能解决你的问题,请参考以下文章
google maps js v3 api教程 -- 在地图上添加标记
Google Maps API V3 错误:RefererDeniedMapError
google maps js v3 api教程 -- 创建一个地图
JavaScript Google Maps API V3 Javascript基本示例