I do not see what I am doing wrong:
var html = existingSelector.innerHTML;
var node = document.createTextNode(html);
existingSelector.parentNode.replaceChild(node, existingSelector);
existingSelector is the result of
selectedContents.querySelector("b");
Running the code correctly removes the "b" element, but does not insert the new node in its place. It simply deletes the entire node, without actually replacing it. As far as I can see, my syntax for the replaceChild() is correct though - ideas?
Edited Complete code:
this.bold = function() {
var selection = this.selection;
var selectedContents = selection.extractContents();
var existingSelector = selectedContents.querySelector("b");
if (existingSelector) {
var html = existingSelector.innerHTML;
var node = document.createTextNode(html);
console.log(node);
existingSelector.parentNode.replaceChild(node, existingSelector);
}
else {
var b = document.createElement("b");
b.appendChild(selectedContents);
selection.deleteContents();
selection.insertNode(b);
}
this.restoreSelection(selection);
}
Related
I am trying to get child node, but it prints null.
My code:
function findFile(ICO){
var fileName = ICO + '.xml';
const folderFiles = DriveApp.getFolderById('folderID').getFiles();
while (folderFiles.hasNext()) {
var folderFile = folderFiles.next();
if(folderFile.getName() == fileName){
return folderFile.getId();
break;
}
}
}
function filesearch(ICO){
var fileId = findFile(ICO);
var fileFound = DriveApp.getFileById(fileId).getBlob().getDataAsString();
var rawXml = XmlService.parse(fileFound);
return rawXml;
}
function parseXML(){
var text_ICO_txt = '27074358';
var docXml = filesearch(text_ICO_txt);
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Ares_odpovedi');
Logger.log(child1);
}
It prints:
[Element: <are:Ares_odpovedi [Namespace: http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0]/>]
null
So I tried different variation of Ares_odpovedi (including the whole text after Element:), but child node is null.
XML file:
<are:Ares_odpovedi xmlns:are="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0" odpoved_datum_cas="2022-05-09T15:00:10" odpoved_pocet="1" odpoved_typ="Vypis_VREO" vystup_format="XML" xslt="klient" validation_XSLT="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_odpovedi.xsl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0 http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0/ares_answer_vreo.xsd" Id="ares">
<are:Odpoved>
<are:Pomocne_ID>0</are:Pomocne_ID>
<are:Vysledek_hledani>
<are:Kod>1</are:Kod>
</are:Vysledek_hledani>
<are:Pocet_zaznamu>1</are:Pocet_zaznamu>
<are:Vypis_VREO>
<are:Uvod>
<are:Nadpis>Výpis z veřejného rejstříku v ARES - elektronický opis</are:Nadpis>
<are:Aktualizace_DB>2022-05-09</are:Aktualizace_DB>
<are:Datum_vypisu>2022-05-09</are:Datum_vypisu>
<are:Cas_vypisu>15:00:09</are:Cas_vypisu>
<are:Typ_vypisu>aktualni</are:Typ_vypisu>
</are:Uvod>
<are:Zakladni_udaje>
...
Could you, please, hint me, how to deal with it?
Thank you in advance!
This answer supposes the modification of your showing script.
When I saw your XML data, it seems that the tag of Ares_odpovedi is the root element. So, for example, when you want to retrieve the element of Odpoved, please modify it as follows.
From:
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Ares_odpovedi');
Logger.log(child1);
To:
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Odpoved', root.getNamespace());
Logger.log(child1);
Reference:
getChild(name, namespace)
I have two functions deleteNode, which accepts a node id and deleteEdge ,which takes a edge object as input.deleteEdge is triggered when a button is pressed and it deletes a particular node and also deletes all its connected edges. However my code only seems to delete the first edge that was added in the array.Not sure what is causing this problem.
Here $scope.nodes is an array of objects with each object looks like this:
var node = {
id:$scope.node_id,
Yedges_id:[],
Nedges_id:[],
}
And $scope.edges is an array of objects where each edge looks like :
var edge = {
id: $scope.edge_id,
start_id: start,
end_id: end,
}
$scope.deleteEdge = function(edge){
var index = $scope.edges.indexOf(edge)
var start_idx = $scope.nodes.findIndex(node=>node!==undefined && node.id==edge.start_id);
var end_idx = $scope.nodes.findIndex(node=>node!==undefined && node.id==edge.end_id);
var Ystart_edge_idx = $scope.nodes[start_idx].Yedges_id.indexOf(edge.id);
var Nstart_edge_idx = $scope.nodes[start_idx].Nedges_id.indexOf(edge.id);
var end_edge_idx = $scope.nodes[end_idx].Yedges_id.indexOf(edge.id);
if(Ystart_edge_idx!==-1){
$scope.nodes[start_idx].Yedges_id.splice(Ystart_edge_idx,1);
}
if(Nstart_edge_idx!==-1){
$scope.nodes[start_idx].Nedges_id.splice(Nstart_edge_idx,1);
}
$scope.nodes[end_idx].Yedges_id.splice(end_edge_idx,1);
$scope.edges.splice(index, 1);
}
$scope.deleteNode = function(id){
var index = $scope.nodes.findIndex(x=>x!==undefined && x.id===id);
$scope.nodes[index].Yedges_id.forEach(edge_id => {
var edge = $scope.edges.filter(edge=>edge.id==edge_id)
$scope.deleteEdge(edge[0]);
});
$scope.nodes[index].Nedges_id.forEach(edge_id => {
var edge = $scope.edges.filter(edge=>edge.id==edge_id)
$scope.deleteEdge(edge[0]);
});
delete $scope.nodes[index]
}
I was just playing around and went to CNN article and ran this code in the console. The idea was to be able to click a p element and it would replace the DOM node with a node that has the reverse text in it. It works as expected but only once. When I try to run it again to reverse it back, I am hit with the error in console and I can't tell why:
TaggedEventTracker.js:56 Uncaught TypeError: Cannot read property 'dataset' of null
at e.findNearestZjsOrAElement (TaggedEventTracker.js:56)
at e.findNearestZjsOrAElement (TaggedEventTracker.js:63)
at e.trackTaggedEvent (TaggedEventTracker.js:73)
at HTMLDocument.<anonymous> (TaggedEventTracker.js:17)
CODE:
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
let nodeText = target.innerHTML;
let newEl = document.createElement('p');
newEl.innerHTML = [...nodeText].reverse().join("");
node.parentNode.replaceChild(newEl, node);
}
Why are you creating a new node to replace the old one? You can just replace the innerHTML of the original element.
When you replace the element, it looks like their event tracker got broken.
Also, by replacing the node, you also replace the event handler associated with it.
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
target.innerHTML = [...target.innerHTML].reverse().join("");
}
<p>`123456789</p>
<p>`123456789</p>
<p>`123456789</p>
If you want to keep the original functionality and still replace the text, you will want to clone the node and attach a new event handler.
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
let nodeText = target.innerHTML;
let newEl = target.cloneNode();
newEl.innerHTML = [...nodeText].reverse().join("");
node.parentNode.replaceChild(newEl, node);
newEl.onclick = function(evt) {updateText(evt.target)}
}
<p>12233</p>
<p>x3332233</p>
This is all you need if you want to swap text in it. Instead of using innerHTML use textContent.
let paragraphs = document.querySelectorAll('p');
paragraphs.forEach(para => {
para.onclick = function(evt) {
updateText(evt.target)
}
})
function updateText(target) {
let node = target;
node.textContent = [...target.textContent].reverse().join("");
}
I have variables which:
display the result (result), and
reference the current node (thisNode).
What do I need to change in my code so that it would display the HTML class?
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.InnerHTML = thisNode.;
/* Here, in JS are there any ways like displaying the class name,
like nodeClass */
Please give recommendations for my code. There may be some errors. Thank you.
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
var block = false;
function buttonDown()
{
if(block == true)
{
thisNode = thisNode.parentElement.firstChild;
block = false;
}
thisNode = thisNode.nextSibling;
result.innerHTML = thisNode.nodeName;
if(thisNode == thisNode.parentNode.lastChild)
{
block = true
}
}
function buttonUp()
{
// not done now...
}
function buttonEnter()
{
thisNode = thisNode.firstChild;
result.innerHTML = thisNode.c;
}
function buttonBack()
{
// not done now...
}
I think you're asking for the className attribute. I copied your first sample and added some code so you can run it on this page. You'll get the second emoji replaced by the class name of the inserted element.
var thisNode = document.getElementById("thisNode"); // document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.innerHTML = thisNode.className; /*Here, in JS are there any ways like displaying the class name, like nodeClass*/
<div id="thisNode" class="sample-class">🙂</div>
<div id="resultOfButton">🙃</div>
Quoting MDN:
"The className property of the Element interface gets and sets the value of the class attribute of the specified element."
I'm trying to replace lengthy XML tags with int values. Example '' as '<1>' so every tag with the name 'child' in the whole XML file will be replaces as '1'. I'm using libxmljs in NodeJS for this. So far my code is ;
var libxml = require('libxmljs');
var xml = '<?xml version="1.0" encoding="UTF-8"?>' +
'<root>' +
'<child foo="bar">' +
'<grandchild baz="fizbuzz">grandchild content</grandchild>' +
'</child>' +
'<child foo="bar1">' +
'<grandchild baz="fizbuzz">grandchild content 1</grandchild>' +
'</child>' +
'<sibling>with content!</sibling>' +
'</root>';
var xmlDoc = libxml.parseXml(xml);
var allxml = xmlDoc.root(); //store all nodes as allxml
var allNodes = xmlDoc.childNodes(); //all child nodes to array
rec(allxml);
function rec(anElement){
for (var j=0; j<allNodes.length;j++ )
{
var firstnode = allNodes[j].name(); //get tagname of the element
var findelem = xmlDoc.find(firstnode); //find similar elements with the tagname to array
var currChild = xmlDoc.child(j); //get current child element
var currnode = xmlDoc.childNodes(); // child nodes of current element to array
if (hasChild(currChild)) { // check whether this has child elements
rec(currChild.childNodes()); //if yes recall this function
}
else{ replaceCurrentTag(findelem, j);} // if no child nodes replace the name
}
}
function replaceCurrentTag(currelem, j){
for (var i=0;i<currelem.length;i++){
currelem[i].name(j.toString());
}
}
function hasChild(xmlElement){
var e = xmlElement.childNodes();
if (e.length > 0){ return true; }
else return false;
}
console.log(xmlDoc.toString());
But I'm getting this error when I run it in terminal.
/home/compaq/node_modules/libxmljs/lib/document.js:0
(function (exports, require, module, __filename, __dirname) { var bindings = r
^
RangeError: Maximum call stack size exceeded
What is that I'm doing wrong in here.
Please help.
Thank you
Your rec function iterates over allNodes, rather than the some subset of the nodes (probably the children of anElement). Combined with recursing into rec again before calling replaceCurrentTag (which never gets called), your function continues to call rec until you fill the call stack.