Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在内容安全策略中使用默认样式的谷歌地图信息窗口?_Javascript_Jquery_Css_Google Maps Api 3_Content Security Policy - Fatal编程技术网

Javascript 如何在内容安全策略中使用默认样式的谷歌地图信息窗口?

Javascript 如何在内容安全策略中使用默认样式的谷歌地图信息窗口?,javascript,jquery,css,google-maps-api-3,content-security-policy,Javascript,Jquery,Css,Google Maps Api 3,Content Security Policy,我在一个网站上使用Google Maps Javascript API,该网站的内容安全策略不允许内联CSS 在实现CSP之前,信息窗口的样式很好。在实现CSP之后,信息窗口根本没有样式,因为GoogleMapsJavaScriptAPI使用内联CSS 我愿意接受任何能让信息窗口看起来像以前一样的解决方案 我尝试的策略是获取GoogleMapsAPI添加到每个元素的内联样式,然后通过jQuery应用该样式。理论上,这应该是可行的,因为: 值得一提的是,如果样式属性通过 直接使用JavaScrip

我在一个网站上使用Google Maps Javascript API,该网站的内容安全策略不允许内联CSS

在实现CSP之前,信息窗口的样式很好。在实现CSP之后,信息窗口根本没有样式,因为GoogleMapsJavaScriptAPI使用内联CSS

我愿意接受任何能让信息窗口看起来像以前一样的解决方案

我尝试的策略是获取GoogleMapsAPI添加到每个元素的内联样式,然后通过jQuery应用该样式。理论上,这应该是可行的,因为:

值得一提的是,如果样式属性通过 直接使用JavaScript,那么就不会有问题了。例如 jQuery的css()方法很好,因为它可以更新样式属性 就在封面下

以下是一个最小的可复制示例

HTML:

JavaScript:

//on page load, call the function to initialize the map
$(function($) {
    var script = document.createElement('script');
    script.src = "//maps.googleapis.com/maps/api/js?callback=initialize&key=yourKeyHere";
    document.body.appendChild(script);
});

//function to initialize the map
function initialize() {

    //construct the map
    var map = new google.maps.Map(document.getElementById("map-canvas"), {
        fullscreenControl: false,
        mapTypeId: 'roadmap',
        scaleControl: false,
        streetViewControl: false,
        zoomControl: false,
    });

    //center the map
    var latLng = new google.maps.LatLng('34.4270881', '-117.57501819999999');
    map.setCenter(latLng);
    map.fitBounds(new google.maps.LatLngBounds(latLng));

    //info window
    var infoWindow = new google.maps.InfoWindow(), marker, i;
    marker = new google.maps.Marker({position: latLng, map: map, title: 'marker title'});
    google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() {
        infoWindow.setContent("foobar");
        infoWindow.open(map, marker);
        google.maps.event.addListener(infoWindow, 'domready', applyStyles(document.getElementById("map-wrapper")));
    }})(marker, i));
}

//function to get inline CSS and apply it via jQuery
function applyStyles(div) {

    //log the div
    console.log(div);

    //loop through the inline CSS properties applied by Google Maps API
    for (var propertyNum = 0; propertyNum < div.style.length; propertyNum++) {

        //get property and convert to camelCase
        var property = div.style[propertyNum].replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); })

        //get value
        var value = div.style[property];

        //log the property and value
        console.log(property + " = " + value);

        //apply style via jquery
        $(div).css(property, value);
    }

    //log a line break
    console.log("");

    //do the same for children of this div
    var children = $(div).children();
    for (var child = 0; child < children.length; child++) {
        applyStyles(children[child]);
    }

}
//在页面加载时,调用函数初始化映射
$(函数($){
var script=document.createElement('script');
script.src=“//maps.googleapis.com/maps/api/js?callback=initialize&key=yourKeyHere”;
document.body.appendChild(脚本);
});
//函数初始化映射
函数初始化(){
//构建地图
var map=new google.maps.map(document.getElementById(“地图画布”){
全屏控制:错误,
mapTypeId:“路线图”,
scaleControl:false,
街景控制:错误,
动物控制:错误,
});
//将地图居中
var latLng=new google.maps.latLng('34.4270881','-117.575018199999');
地图设置中心(latLng);
fitBounds(新的google.maps.LatLngBounds(latLng));
//信息窗口
var infoWindow=new google.maps.infoWindow(),marker,i;
marker=new google.maps.marker({position:latLng,map:map,title:'marker title'});
google.maps.event.addListener(标记,'click',(函数(标记,i){return function(){
infoWindow.setContent(“foobar”);
信息窗口。打开(地图、标记);
google.maps.event.addListener(infoWindow,'domready',applyStyles(document.getElementById(“地图包装”));
}})(marker,i));
}
//函数获取内联CSS并通过jQuery应用它
函数applyStyles(div){
//记录分区
控制台日志(div);
//循环浏览GoogleMapsAPI应用的内联CSS属性
对于(var-propertyNum=0;propertyNum
这是行不通的。这些样式都没有生效

这些样式都没有生效

事实并非如此。我通过元素的
style
属性“获取”的样式实际上是通过jQuery
.css()
方法应用的

我的错误是,当API同时注入内部CSS(例如
div{background=color:#ffffffff“>}
)时,假定API应用的样式仅限于内联CSS(例如

我注意到相关的
div
s都有以
gm-style-iw
开头的类名(其中,“gm”大概是指谷歌地图,“iw”是指信息窗口)。我搜索了注入的样式标记,发现其中只有一个有这些类名

.gm-style .gm-style-iw{font-weight:300;font-size:13px;overflow:hidden}.gm-style .gm-style-iw-a{position:absolute;width:9999px;height:0}.gm-style .gm-style-iw-t{position:absolute;width:100%}.gm-style .gm-style-iw-t::after{background:linear-gradient(45deg,rgba(255,255,255,1) 50%,rgba(255,255,255,0) 51%,rgba(255,255,255,0) 100%);box-shadow:-2px 2px 2px 0 rgba(178,178,178,.4);content:"";height:15px;left:0;position:absolute;top:0;transform:translate(-50%,-50%) rotate(-45deg);width:15px}.gm-style .gm-style-iw-c{position:absolute;box-sizing:border-box;overflow:hidden;top:0;left:0;transform:translate(-50%,-100%);background-color:white;border-radius:8px;padding:12px;box-shadow:0 2px 7px 1px rgba(0,0,0,0.3)}.gm-style .gm-style-iw-d{box-sizing:border-box;overflow:auto}.gm-style .gm-style-iw-d::-webkit-scrollbar{width:18px;height:12px;-webkit-appearance:none}.gm-style .gm-style-iw-d::-webkit-scrollbar-track,.gm-style .gm-style-iw-d::-webkit-scrollbar-track-piece{background:#fff}.gm-style .gm-style-iw-c .gm-style-iw-d::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,0.12);border:6px solid transparent;border-radius:9px;background-clip:content-box}.gm-style .gm-style-iw-c .gm-style-iw-d::-webkit-scrollbar-thumb:horizontal{border:3px solid transparent}.gm-style .gm-style-iw-c .gm-style-iw-d::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,0.3)}.gm-style .gm-style-iw-c .gm-style-iw-d::-webkit-scrollbar-corner{background:transparent}.gm-style .gm-iw{color:#2c2c2c}.gm-style .gm-iw b{font-weight:400}.gm-style .gm-iw a:link,.gm-style .gm-iw a:visited{color:#4272db;text-decoration:none}.gm-style .gm-iw a:hover{color:#4272db;text-decoration:underline}.gm-style .gm-iw .gm-title{font-weight:400;margin-bottom:1px}.gm-style .gm-iw .gm-basicinfo{line-height:18px;padding-bottom:12px}.gm-style .gm-iw .gm-website{padding-top:6px}.gm-style .gm-iw .gm-photos{padding-bottom:8px;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none}.gm-style .gm-iw .gm-sv,.gm-style .gm-iw .gm-ph{cursor:pointer;height:50px;width:100px;position:relative;overflow:hidden}.gm-style .gm-iw .gm-sv{padding-right:4px}.gm-style .gm-iw .gm-wsv{cursor:pointer;position:relative;overflow:hidden}.gm-style .gm-iw .gm-sv-label,.gm-style .gm-iw .gm-ph-label{cursor:pointer;position:absolute;bottom:6px;color:#fff;font-weight:400;text-shadow:rgba(0,0,0,0.7) 0 1px 4px;font-size:12px}.gm-style .gm-iw .gm-stars-b,.gm-style .gm-iw .gm-stars-f{height:13px;font-size:0}.gm-style .gm-iw .gm-stars-b{position:relative;background-position:0 0;width:65px;top:3px;margin:0 5px}.gm-style .gm-iw .gm-rev{line-height:20px;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none}.gm-style.gm-china .gm-iw .gm-rev{display:none}.gm-style .gm-iw .gm-numeric-rev{font-size:16px;color:#dd4b39;font-weight:400}.gm-style .gm-iw.gm-transit{margin-left:15px}.gm-style .gm-iw.gm-transit td{vertical-align:top}.gm-style .gm-iw.gm-transit .gm-time{white-space:nowrap;color:#676767;font-weight:bold}.gm-style .gm-iw.gm-transit img{width:15px;height:15px;margin:1px 5px 0 -20px;float:left}
我只是简单地复制和粘贴CSS并将其添加到外部样式表中。一个更理想的解决方案是通过编程方式获取CSS并通过jQuery应用它,但这对于我现在的目的来说是可行的

但即使在我这样做之后,信息窗口右上角的“x”按钮也没有出现,因为图像源是一个数据URI,这是强CSP不允许的

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224px%22%20height%3D%2224px%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23000000%22%3E%0A%20%20%20%20%3Cpath%20d%3D%22M19%206.41L17.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%0A%20%20%20%20%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%0A%3C%2Fsvg%3E%0A" style="pointer-events: none; display: block; width: 13px; height: 13px; margin: 12px;">
但是“x”按钮的位置不太正确,因为当有一个垂直滚动条时,“x”按钮实际上就在它上面。我通过在外部CSS中添加以下内容来解决这个问题:

.gm-style-iw-d{margin-top: 1rem;}

瞧!信息窗口看起来就像我实现CSP之前一样。

您何时/如何调用该函数?在打开信息窗口并将其添加到DOM(在触发
domready
事件后)之前,它可能不会对信息窗口内容起作用。请提供一个示例来演示您的问题。@geocodezip我已编辑了我的问题,以显示我在触发
domready
事件后调用该函数。使用
console.log()
我已经确定该函数在信息窗口打开并添加到DOM后生效。该函数确实获得了Google添加到该窗口的内联样式。还要注意的是,我是在
#map wrapper
及其每一个后代上执行此操作的,因为信息窗口的样式似乎没有限制d到信息窗口
div
本身。@geocodezip我现在编辑了我的问题,以包含一个最小的可复制示例。
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224px%22%20height%3D%2224px%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23000000%22%3E%0A%20%20%20%20%3Cpath%20d%3D%22M19%206.41L17.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%0A%20%20%20%20%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%0A%3C%2Fsvg%3E%0A" style="pointer-events: none; display: block; width: 13px; height: 13px; margin: 12px;">
marker.addListener('click', function() {
    infoWindow.setContent("<div class='info-window'>foobar</div>");
    infoWindow.open(map, marker);

    //check to see if the info window has loaded yet
    checkForInfoWindow();
});

function checkForInfoWindow() {
    var checkForInfoWindow = setInterval(function() {
        if ($(".info-window").length) {
            styleInfoWindow();
            clearInterval(checkForInfoWindow);
        }
    }, 1);
}

function styleInfoWindow() {

    //style the "x" button
    var button = $(".info-window").parent().parent().parent().children("button");
    $(button).html("<img src='/images/x.gif'>");
    $(button).mouseover(function() {
        $(button).html("<img src='/images/x-hover.gif'>");
    });
    $(button).mouseout(function() {
        $(button).html("<img src='/images/x.gif'>");
    });

    //get divs with a class name beginning with "gm-style-iw"
    var divs = $("div[class^='gm-style-iw']");

    //for each div
    for (var div = 0; div < divs.length; div++) {

        //for each inline css property
        for (var propertyNum = 0; propertyNum < divs[div].style.length; propertyNum++) {

            //get property and convert to camelCase
            var property = divs[div].style[propertyNum].replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); })

            //get value
            var value = divs[div].style[property];

            //apply style
            divs[div].style[property] = value;
        }

    }

}
.gm-style-iw-d{margin-top: 1rem;}