Ich bin Klassenname auf <A>
Elemente (im Original-HTML-Format), unter denen SVG-Elemente angehängt werden, wie sie mit $ .get geladen werden. Die SVG-Elemente haben Stile, die in Chrome nicht angewendet werden, es sei denn, ich mache etwas, das ein erneutes Rendern erzwingt. Zum Beispiel das Aktivieren/Deaktivieren eines Kontrollkästchens für ein Stilattribut in der Entwickleransicht oder die Verwendung von Brackets-IDE und das Ändern von CSS (wodurch Brackets unser gesamtes CSS zerreißt und für jedes eingegebene Zeichen ersetzt).Umgang mit Chrome-Rendering dynamisch Elemente mit unvollständigen CSS hinzugefügt
Wenn ich den Klasse hinzufügen-Code auf setTimeout, mit mindestens 80 ms Intervall, funktioniert es. In IE11, Edge, Safari und Firefox funktioniert es ohne diese Umgehung. Laut Netzwerkbereich wird CSS vor den Skripts geladen (auch versucht, sie an den Schwanz statt an den Kopf zu platzieren). Dies ist ein Problem von Chrome, das die Rendersequenz nicht richtig verwaltet (am ehesten versucht, mit minimalem Render-Algorithmus zu schlau zu sein) arbeitet gegen mich).
Wie gehe ich richtig damit um?
Dies ist ein working version, funktioniert, weil ich die Stile, die normalerweise mit jQuery angewendet werden hart-codiert (in der Produktion würde ich diese Server-Seite rendern, aber es ist keine befriedigende Lösung).
Hier ist der broken version
Sie können überprüfen, dass die Linien 55-64 in navigation.js
in eine setTimeout
bewegen wird es funktioniert.
Mit Chrome Version 51.0.2704.103 (64-Bit) auf Mac OS X
Edit: relevante HTML und JS wie gewünscht, die oben für vollständige Bild Links.
index.htm
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css"></link>
<script type="text/javascript" src="scripts/jquery.min.js"></script>
<script type="text/javascript" src="scripts/navigation.js"></script>
</head>
<body>
<header>
<div id="logo" class="icon" data-src="images/logo.svg"></div>
<nav data-src="images/navigation.svg">
<a href="index.htm">news</a>
<a href="articles.htm">articles</a>
<a href="projects.htm">projects</a>
<a href="about.htm">about</a>
</nav>
Navigation.js
$(document).ready(function() {
loadNavigationButtons();
});
function loadNavigationButtons() {
var buttonParts =
[
"matte",
"border",
"highlight",
"icon",
"selection"
];
return $.Deferred(function(callback) {
$("nav a").each(function(index) {
var navigationIconSet = $(this)
.closest("nav[data-src]")
.attr("data-src");
var buttonName = $(this).text();
$(this).text("");
if (document.URL.indexOf($(this).attr("href")) != -1) {
// Add navigation-selected class to <a>
$(this).addClass("navigation-selected");
} else {
// Add navigation-unselected class to <a>
$(this).addClass("navigation-unselected");
}
for (var partIndex in buttonParts) {
loadIcon(
// Prepend to this element.
$(this),
// Attempt to find a part for this specific button.
navigationIconSet + "#" + buttonName + "-" + buttonParts[partIndex],
// Fallback to generic part name.
navigationIconSet + "#" + buttonParts[partIndex],
// Class to apply.
"navigation navigation-" + buttonParts[partIndex]
// Not passing callback parameter
);
}
// Append button text.
$("<div></div>")
.text(buttonName)
.addClass("navigation navigation-text")
.appendTo($(this));
});
callback.resolve();
});
}
function loadIcon($container, iconUri, fallbackUri, classToApply, callbackParameter) {
if (~iconUri.indexOf("#")) {
var sourceComponents = iconUri.split("#");
var fallbackComponents;
if (fallbackUri) {
fallbackComponents = fallbackUri.split("#");
// Support fallback only within the same icon set.
if (sourceComponents[0] != fallbackComponents[0]) {
return $.Deferred(function(callback) {
callback.reject($container, null, callbackParameter)
});
}
} else {
fallbackComponents = [null, null];
}
return loadIconFromDefinition(
$container,
sourceComponents[0],
sourceComponents[1],
fallbackComponents[1],
classToApply,
callbackParameter);
} else {
return loadIconFromFile(
$container, iconUri, classToApply, callbackParameter);
}
}
function loadIconFromFile($container, iconUri, classToApply, callbackParameter) {
return $.Deferred(function(callback) {
$.get(iconUri).done(function(icon) {
callback.resolve(
$("svg", icon).prependTo($container),
null,
callbackParameter);
});
});
}
function loadIconDefinition(definitionUri) {
if (!loadIconDefinition.loaded) {
loadIconDefinition.loaded = {};
}
if (loadIconDefinition.loaded[definitionUri]) {
return loadIconDefinition.loaded[definitionUri];
}
loadIconDefinition.loaded[definitionUri] =
$.Deferred(function(callback) {
loadIconFromFile($("body"), definitionUri)
.then(function($loaded) {
// Hide definition after it's loaded.
$loaded.get(0).setAttributeNS(null, "style", "display:none");
callback.resolve($loaded);
});
});
return loadIconDefinition.loaded[definitionUri];
}
function loadIconFromDefinition(
$container, definitionUri, groupName, fallbackGroupName, classToApply, callbackParameter) {
return $.Deferred(function(callback) {
loadIconDefinition(definitionUri).then(function($loaded) {
if (fallbackGroupName &&
!$loaded.find("#" + groupName).length) {
groupName = fallbackGroupName;
}
callback.resolve(
$("<svg class=\"" + classToApply + "\"><use xlink:href='#" + groupName + "'></use></svg>")
.prependTo($container),
$loaded,
callbackParameter);
});
});
}
Kein Code zu zeigen? – evolutionxbox
Raise einen Chrome-Bug auf ihrem Bugtracker. –
Ich konnte ein jsFiddle nicht veröffentlichen, da externe Ressourcen für die Demo benötigt werden (in diesem Fall eine kleine .svg). Ich wurde gewarnt, dass die Cross-Site-Anfrage nicht funktionieren würde. –