Мне нужно отредактировать (используя javascript) документ SVG, встроенный в страницу html.
Когда SVG загружен, я могу получить доступ к внутреннему пространству SVG и его элементам. Но я не могу знать, готов ли дом SVG или нет, поэтому я не могу выполнять действия по умолчанию для SVG при загрузке страницы html.
Для доступа к SVG dom я использую этот код:
var svg = document.getElementById("chart").getSVGDocument();
где «диаграмма» - это идентификатор встроенного элемента.
Если я попытаюсь получить доступ к SVG, когда HTML-документ будет готов, следующим образом:
jQuery(document).ready( function() {
var svg = document.getElementById("chart").getSVGDocument();
...
svg всегда имеет значение null. Мне просто нужно знать, когда он не равен нулю, чтобы я мог начать манипулировать им. Вы знаете, есть ли способ это сделать?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете назначить обработчик события onload элементу в вашем документе SVG и заставить его вызывать функцию javascript на странице html. onload отображает SVGLoad.
http://www.w3.org/TR/SVG11/interact.html#LoadEvent
The event is triggered at the point at which the user agent has fully parsed the element and its descendants and is ready to act appropriately upon that element
Загрузка родительского элемента не сработает, только фактический файл svg.
Вы можете попробовать опрашивать время от времени.
function checkReady() {
var svg = document.getElementById("chart").getSVGDocument();
if (svg == null) {
setTimeout("checkReady()", 300);
} else {
...
}
}
Да, это работает. Не думал о решении тайм-аута ... Спасибо, чувак.
Опрос - не лучший способ сделать это. Вместо этого используйте прослушиватель событий load.
У прослушивателя событий @ ErikDahlström load есть проблемы.
В вашем элементе внедрения (например, 'embed', 'object', 'iframe') в основном документе добавьте атрибут onload, который вызывает вашу функцию, или добавьте прослушиватель событий в скрипт, например embeddingElm.addEventListener('load', callbackFunction, false). Другой вариант - прослушивание DOMContentLoaded, в зависимости от того, для чего вы этого хотите.
Вы также можете добавить прослушиватель нагрузки в основной документ. jQuery(document).ready не означает, что все ресурсы загружены, просто документ имеет DOM, готовый к действию. Однако обратите внимание, что если вы прослушиваете загрузку всего документа, ваша функция обратного вызова не будет вызываться до тех пор, пока не будут загружены все ресурсы в этом документе, css, javascript и т. д.
Однако если вы используете встроенный svg, то jQuery(document).ready будет работать нормально.
В качестве дополнительной заметки вы можете рассмотреть возможность использования embeddingElm.contentDocument (если есть) вместо embeddingElm.getSVGDocument().
embeddingElm.addEventListener ('load', callbackFunction, false) не будет работать, если embeddingElm уже загружен при запуске скрипта. DOMContentLoaded не будет работать, если вы свяжете изображение в SVG (например, фоновое изображение). Вы (не должны) делать: что-то похожее на: window.onload, потому что тогда вам придется подождать, пока все ваши внешние ресурсы также не будут загружены (например, скрипты отслеживания и реклама)
Вы также знаете, как запустить этот прослушиватель событий загрузки для объекта SVG в тесте Angular?
В Safari, если содержимое SVG уже загружено, load никогда не запускается.
будет ли onload работать, если кто-то изменит документ SVG, назначенный чему-то вроде DIV, который вызывает загрузку этого документа? Все это, когда мы знаем, что DOM и контент действительно загружены, чтобы можно было вызывать определенные функции ECMAscript, определенные в SVG, или запрашивать DOM, по-прежнему кажется предложением удачного / промаха в 2018 году на основе того, что я слышу от некоторых людей.
Используя jQuery, вы можете привязаться к событию загрузки окна, о котором упоминает Эрик:
$(window).load(function(){
var svg = document.getElementById("chart").getSVGDocument();
});
Я думаю, таким образом вы можете узнать, когда объект SVG загружен на страницу html, но вы все еще не знаете, готова ли DOM SVG.
Я обнаружил, что это работает, когда встраивал jquery в автономный SVG - спасибо!
Предполагая, что ваш SVG находится в теге <embed>:
<embed id = "embedded-image" src = "image.svg" type = "image/svg+xml" />
Изображение SVG, по сути, находится во вложенном документе, который будет иметь отдельное событие load по сравнению с событием основного document. Однако вы можете прослушать это событие и обработать его:
var embed = document.getElementById("embedded-image");
embed.addEventListener('load', function()
{
var svg = embed.getSVGDocument();
// Operate upon the SVG DOM here
});
Это лучше, чем опрос, поскольку любые изменения, которые вы вносите в SVG, будут происходить до того, как он будет сначала отрисован, что уменьшит мерцание и затраты процессора на рисование.
Чтобы работать с JQuery с заданным элементом, выполните следующее: var svg = $ (embed.getSVGDocument (). DocumentElement);
Событие загрузки элемента внедрения (например, объекта) было бы моим предпочтением, но, если по какой-то причине это не является жизнеспособным решением, единственным универсальным и надежным тестом, который я нашел для готовности SVG DOM, является метод getCurrentTime SVG корневой элемент:
var element = document.getElementById( 'elementId' );
var svgDoc = element.contentDocument;
var svgRoot = svgDoc ? svgDoc.rootElement : null;
if ( svgRoot
&& svgRoot.getCurrentTime
&& ( svgRoot.getCurrentTime() > 0 ))
{
/* SVG DOM ready */
}
Рекомендация W3C SVG утверждает, что getCurrentTime для SVGSVGElement:
Returns the current time in seconds relative to the start time for the current SVG document fragment. If getCurrentTime is called before the document timeline has begun (for example, by script running in a ‘script’ element before the document's SVGLoad event is dispatched), then 0 is returned.
You could use an onload event for the check.
Предположим, что some.svg встроен в тег объекта:
<body>
<object id = "svgholder" data = "some.svg" type = "image/svg+xml"></object>
</body>
JQuery
var svgholder = $('body').find("object#svgholder");
svgholder.load("image/svg+xml", function() {
alert("some svg loaded");
});
javascript
var svgholder = document.getElementById("svgholder");
svgholder.onload = function() {
alert("some svg loaded");
}
addEventListener('load', handler) вместо установки свойства onload, чтобы не переопределять другие обработчики нагрузки. Однако это не поддерживается древними браузерами. Вопрос: jQuery load был первым методом, который я пытался использовать, но без 'image/svg+xml' в качестве первого аргумента он не будет работать. Вы можете объяснить эту магию? Я не нашел объяснения в документации jQuery. Он просто упоминает аргумент как url (а здесь мы указываем тип MIME). И опять же, почему нам не нужна такая штука для onload?
Я думаю, можно с уверенностью сказать, что если вы предполагаете, что браузер может отображать встроенные SVG, вы можете быть уверены, что он также реализует addEventListener.
svgholder.load("image/svg+xml", function()..., похоже, вместо этого вызывает загрузку jquery ajax. До версии v3.0 jquery определял, какую нагрузку вызывать, на основе предоставленных аргументов. Со строкой в первом аргументе jquery пытается выполнить GET для 'image / svg + xml' в качестве URL-адреса. Поскольку он помещает загруженное содержимое в выбранный элемент, а затем вызывает предоставленный обратный вызов, это может выглядеть как загруженное уведомление, но делает что-то еще. Найдите 404 в своей консоли. Кроме того, обработчик событий .load устарел с версии 3.0.
Для справки в будущем: решение Угловой (8) / Машинопись выглядит так:
@ViewChild('startimage', {static:false})
private startimage: ElementRef;
...
this.startimage.nativeElement.addEventListener('load', () => {
alert('loaded');
});
Попасть в svg можно по const svg = this.startimage.nativeElement.getSVGDocument();
Нет, я не могу редактировать документ SVG. Я просто могу манипулировать им, когда он находится на веб-странице.