Polymer2.0- Попытка загрузить DIV контент пользовательского элемента
Я пытаюсь загрузить содержимое div пользовательского элемента, используя document.getElementById элемента div, и пытаюсь реализовать опцию загрузки из JS FIddle - http://jsfiddle.net/evx9stLb/
Из консоли я получаю ошибку ниже
pen.js:6 Uncaught TypeError: Невозможно прочитать свойство 'innerHTML' с нулевым значением при загрузке (pen.js:6) в HTMLButtonElement.onclick (index.html: 15)
HTML:
<head>
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-collapse/iron-collapse.html">
</head>
<body>
<x-foo></x-foo>
<button onClick="download()">Download</button>
<dom-module id="x-foo">
<template>
<button on-click="toggle">toggle collapse</button>
<div id="content">
<iron-collapse id="collapse">
<div>Content goes here...</div>
</iron-collapse>
</div>
</template>
</dom-module>
</body>
JS:
function download(){
var a = document.body.appendChild(
document.createElement("a")
);
a.download = "export.html";
a.href = "data:text/html," + document.getElementById("content").innerHTML;
a.click();
}
class XFoo extends Polymer.Element {
static get is() { return 'x-foo'; }
static get properties() {
return {};
}
toggle() {
this.$.collapse.toggle();
}
}
customElements.define(XFoo.is, XFoo);
Код, который я ниже - https://codepen.io/nagasai/pen/ZyRKxj
3 ответа
Запрос документа (на Light DOM) не будет пробивать shadowDom. Для этого вам нужно специально выбрать элемент и запросить его shadowRoot.
это будет выглядеть примерно так
a.href = "data:text/html," + document.getElementsByTagName('x-foo')[0].shadowRoot.querySelector('#content').innerHTML;
НО делать это, только если вы не можете изменить сам элемент. Нехорошо болтаться в чужом shadowRoot.
Как показал Фрэнк Р., гораздо лучше модифицировать сам элемент и обеспечить функциональность загрузки.
Вы можете легко вызвать это из внешнего элемента с чем-то вроде
document.getElementsByTagName('x-foo')[0].download();
DOM под теневым Root или теневым DOM не доступен через innerHTML
, Это не должно быть. Просто так оно и есть.
Итак, нет, вы просто не можете получить содержимое DOM-тени через innerHTML
,
Раньше раньше доступ к shadowDOM запрещался через vanilla javascript, а также обсуждался здесь. Однако теперь, когда теневой DOM V1 является нормой, вам, возможно, придется подождать и посмотреть, сможете ли вы пробить shadowDOM.
В качестве альтернативы можно переместить всю модель DOM в пользовательский элемент за его пределы, используя слоты.
Слоты распространяют контент, поэтому страница, которая использует ваш элемент, может получить к нему доступ через innerHTML
,
Вы могли бы попробовать хакерские способы, подобные упомянутому здесь
Сделайте некоторые обновления, и помощь поможет,
HTML
<head>
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-collapse/iron-collapse.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<button on-click="download">Download</button>
<button on-click="toggle">toggle collapse</button>
<div id="content">
<iron-collapse id="collapse">
<div>Content goes here...</div>
</iron-collapse>
</div>
</template>
</dom-module>
</body>
JS
class XFoo extends Polymer.Element {
static get is() { return 'x-foo'; }
static get properties() {
return {};
}
toggle() {
this.$.collapse.toggle();
}
download(){
var a = document.body.appendChild(
document.createElement("a")
);
a.download = "export.html";
a.href = "data:text/html," + this.$.content.innerHTML;
a.click();
console.log(this.$.content.innerHTML);
}
}
customElements.define(XFoo.is, XFoo);