我有一个应用程序,页面生成器创建一个保存在数据库中的起始页面。保存的信息只是DOM对象的outerHTML
。要创建编辑功能,我需要一个从HTML信息中重新创建DOM对象的反函数。不幸的是,将解密的信息分配给outerHTML
部分不会产生任何结果,因为忽略了DOM对象中的更改。
我的问题:如何从保存的outerHTML信息中重新创建DOM对象?如果这是不可能的,那么做这样的事情的正确方法是什么?
修改 谢谢您的回复!以下是一些显示我正在做的代码片段。原型 MainWidget 正在从HTML页面获取信息。想要分配信息。使用的函数是另一个名为 Widgets 的对象(原型)的一部分。
var asserts = new Asserts();
var calls = new Calls();
var constants = new MainConst();
var strings = new Strings();
var widgets = new MainWidget();
MainWidget.method('assign2Widget', function (call, label, value, isValid) {
isValid = toBoolean(isValid), value = strings.toString(value);
if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) {
var section = (!label.includes('Builder') // A marker, not an element!
&& !label.includes(constants.NewsTicker))
? widgets.getSgSectionByLabel(document, label)
: null;
value = strings.decode(decodeURIComponent(value)); //<<<< Code decoded from DB
if (asserts.isObject(section)) {
section.outerHTML = value;
} else if (label.includes(constants.Elements)) {
if (asserts.isValid(infos.Elements) && infos.Elements.length > 0) {
// HERE, THE CODE FROM DB SHOULD BE ADDED TO WIDGET.
// The "label" gives the label of the widget, and the "value" is
// what is to be assigned to.
}
} else if (label.includes(constants.NewsTicker)) {
[…]
}
[…]
});
Widget.method('getElementTypeByLabel', function (thing, elementType, label) {
if (asserts.isObject(thing)
&& strings.hasMinimalLength(elementType, 2)
&& strings.hasMinimalLength(label, 2)) {
var element, elements = document.getElementsByTagName(elementType);
if (asserts.isValid(elements)
&& asserts.isDefined(elements.length) && elements.length === 0) {
elements = thing.children;
}
for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) {
element = elements*;
if (element.getAttribute !== null) {
var labelName = element.getAttribute(constants.label);
if (label === labelName && element !== null) {
return element;
}
} else {
return null;
}
}
// If the element was not found, search recursively the elements!
for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) {
return this.getElementTypeByLabel(elements*, elementType, label);
}
} else {
// Error! //messages.invalidFunctionCall(functionName);
}
return null;
});
Widget.method('getSgSectionByLabel', function (element, label) {
return this.getElementTypeByLabel(element, 'sg-section', label);
});
编辑2 :我在编辑现有页面时仅使用sg-section
中所做的更改来重新创建内容。
MainWidget.js:
[…]
MainWidget.method('assign2Widget', function (call, label, value, isValid) {
isValid = toBoolean(isValid), value = strings.toString(value);
if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) {
var section = (!label.includes('Builder') // A marker, not an element!
&& !label.includes(constants.NewsTicker))
? widgets.getSgSectionByLabel(document, label)
: null;
value = strings.decode(decodeURIComponent(value));
if (asserts.isObject(section)) {
section.outerHTML = value;
} else if (label.includes(constants.Elements)) {
if (asserts.isString(value) && value.includes(LeftBracket)) {
value = arrays.toArray(value); //value.replace(LeftBracket, '').split(RightBracket);
}
if (arrays.isArray(value)) {
for (var i = 0; i < value.length; i++) {
infos.insertGridItem(value[i]);
}
}
[…]
MainInfos.js:
[…]
function MainInfos() {
this.Elements; // Object for startGridGenerator
this.insertGridItem; // Function of startGridGenerator
this.PrototypeName = 'MainInfos';
}
MainInfos.inherits(Infos);
MainWidget.method('assign2Widget', function (call, label, value, isValid) {
isValid = toBoolean(isValid), value = strings.toString(value);
if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) {
var section = (!label.includes('Builder') // A marker, not an element!
&& !label.includes(constants.NewsTicker))
? widgets.getSgSectionByLabel(document, label)
: null;
value = strings.decode(decodeURIComponent(value));
if (asserts.isObject(section)) {
section.outerHTML = value;
} else if (label.includes(constants.Elements)) {
if (asserts.isString(value) && value.includes(LeftBracket)) {
value = arrays.toArray(value); //value.replace(LeftBracket, '').split(RightBracket);
}
if (arrays.isArray(value)) {
for (var i = 0; i < value.length; i++) {
infos.insertGridItem(value[i]);
}
}
} else if (label.includes(constants.NewsTicker)) {
[…]
}
});
startGridGenerator.js:
[…]
(function () {
var moduleName = 'ivmGridBuilder';
var controllerName = moduleName + Controller;
angular.module(moduleName, [
'ionic',
'ui.sortable',
'ivmColorpicker',
'ivmIconpicker'
])
.controller(controllerName, function ($scope,
$ionicScrollDelegate,
$ionicModal,
$sce,
CommunicationService) {
[…]
/**
* Inserts an existing grid item to the item's array
*
* @param item
*/
$scope.insertGridItem = function (item) {
if (asserts.isObject(item)) {
$scope.items.push(item);
infos.Elements.push(item);
$ionicScrollDelegate.resize()
} else {
// First call with no valid item & "remember" this function
// by having a link to in in object MainInfos!
infos.insertGridItem = $scope.insertGridItem;
}
};
答案 0 :(得分:1)
您可以使用DOMParser()
创建#document
或<template>
元素,以便从字符串中创建#document-fragment
const parser = new DOMParser();
const doc = parser.parseFromString(/* outerHTML */, "text/html");
答案 1 :(得分:1)
您可以将字符串添加到隐藏的Div in页面中,然后使用javascript获取您想要从该Div中获取的元素。就像在这段代码中一样:
var str ='abc 123<div id="test">coursesweb.net</div><span class="cls">some text</span>';
document.querySelector('body').insertAdjacentHTML('beforeend', '<div style="display:none;">'+str+'</div>');
var ob_test = document.getElementById('test');
alert(ob_test.innerHTML);
答案 2 :(得分:1)
解决方案应该是,你得到一个包含内容的HTML字符串。然后使用$sce.trustAsHtml();
并分配一个范围变量,该变量将确保HTML是安全的,然后您可以使用下面带有指令ng-bind-html
的HTML将HTML字符串呈现为实际HTML。
这是一个相同的工作示例。
var app = angular.module("angularApp", []);
app.controller("appController", function($scope, $sce) {
$scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here.";
$scope.output = $sce.trustAsHtml($scope.content);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h2>Rendering HTML with angularJS</h2>
<div ng-app="angularApp" ng-controller="appController">
<div ng-bind-html="output"></div>
</div>
另一种选择是使用ng-sanitize
。
如果使用ng-sanitize
- 通过将HTML解析为标记来清理输入。然后将所有安全令牌(来自白名单)序列化为正确转义的html字符串。这意味着没有不安全的输入可以使它成为返回的字符串。
请参阅以下问题以获得更详细的解释。
var app = angular.module("angularApp", ['ngSanitize']);
app.controller("appController", function($scope) {
$scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here.";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular-sanitize.min.js"></script>
<h2>Rendering HTML with angularJS</h2>
<div ng-app="angularApp" ng-controller="appController">
<div ng-bind-html="content"></div>
</div>
如上例所示,无需拨打$sce.trustAsHtml();
,因为ngSanitize
会自动处理。
请告诉我这种方法是否对您有所帮助,或者您是否遇到任何问题!