is there better way coverting html string to DOM? - javascript

<div class="row data">
<div class="subdiv">
<div class="check"><input type="checkbox" name="buy" value="260" checked="" onclick="javascript:basket.checkItem();"> </div>
<div class="img"><img src="./img/basket1.jpg" width="60"></div>
<div class="pname">
<span>TX2</span>
</div>
</div>
<div class="subdiv">
<div class="num">
<div class="updown">
<input type="text" name="p_num1" id="p_num1" size="2" maxlength="4" class="p_num" value="2" onkeyup="javascript:basket.changePNum(1);">
<span onclick="javascript:basket.changePNum(1);"><i class="fas fa-arrow-alt-circle-up up"></i></span>
<span onclick="javascript:basket.changePNum(1);"><i class="fas fa-arrow-alt-circle-down down"></i></span>
</div>
</div>
</div>
<div class="subdiv">
<div class="basketcmd">삭제</div>
</div>
</div>
I saw the way using DOMParser().parseFromString, but this solution requires me to convert html code into one line string. Is there better way to convert or skills to make html code to string easily?
my final goal is to use appendChild() so that I can have many "row data" class div. which requires me to make html code to DOM.

As others have stated, going from strings to HTML in JavaScript is dangerous, as it can result in easy-to-exploit XSS (Cross-Site Scripting) vulnerabilities.
If you want to create an element safely, we can do so as follows.
let clicks = 0;
const container = document.createElement("div");
container.setAttribute("class", "container");
const heading = document.createElement("h1");
heading.textContent = "Created & Appended, Click Me!";
heading.addEventListener("click", (event) => {
heading.textContent = `Clicked ${++clicks} Times`;
});
container.append(heading);
document.body.append(container);
We can create elements with createElement, set any attribute with setAttribute, modify the classes with classList or setAttribute, and set the text node content with textContent. By doing this, we can prevent XSS.
We can even add events using addEventListener.

Related

Finding and replacing attribute in HTML File

I have a project folder which contain list of HTML file which contain some knockout syntax , I am looking some pointer where are I search for certain pattern of attribute and replace it will new syntax.
I tried something with JSDOM but was not successful.
Structure of HTML file is something like this , here I have find all occurrences of data-bind="attr :{id : <>}" and replace it with :id="[[componentid]]"
<div data-bind="attr :{id :componentid}" class="">
<div class="formlayout">
<input type='textbox>
</div>
</div>
<div data-bind=" attr :{id : pageid}" class="">
<div class="formlayout">
<input type='textbox>
</div>
</div>
After the change HTML file should look like below.
<div :id="[[componentid]]" class="">
<div class="formlayout">
<input type='textbox>
</div>
</div>
<div :id="[[pageid]]" class="">
<div class="formlayout">
<input type='textbox>
</div>
</div>
Note: There can be multiple whitespace for the data-bind property we should ignore those. I was trying with JSDOM and node js but was not successful and pointer will be really helpful
you can try this...
<script>
const getElement1 = document.querySelector(".data1");
const getElement2 = document.querySelector(".data2");
getElement1.removeAttribute("data-bind");
getElement1.setAttribute(":id", "[[componentid]]");
getElement2.removeAttribute("data-bind");
getElement2.setAttribute(":id", "[[pageid]]");
</script>

modify / move an existing html tag in the DOM (javascript)

I want to move my div class="contentlinks" tag with its content, to place it in the div class="row" after the div class="col-12".
Here is the basic html architecture :
<span id="data">
<section id="" class="thesectionQ">
<div class="container">
<div class="row">
<div class="col-12">
<h1>Title</h1>
</div>
</div>
</div>
</section>
<div class="col-12 contentlinks">
<a class="btn">link1</a><a class="btn">link2</a>
</div>
</span>
Tags are dynamically created in js... my problem is that I can't seem to use appendChild ...
my problem is that I can't seem to use appendChild ...
I'm trying to target my section with a class="thesectionQ" in a variable as well as my div class="contentlinks" that I want to move :
for example...
var thedata2 = document.getElementById('data').getElementsByClassName('thesectionQ');
var thedata = document.getElementById('data').getElementsByClassName('contentlinks');
thedata2.appendChild(thedata);
but I have errors ... and too often
give section id so it become easy.
document.querySelector('#sectionId div.row')
.appendChild(document.querySelector('div.contentlinks'))

auto complete on editable divs angular js

I am not able to perform the auto suggestion functionality on divs with contenteditable attribute. Also when I write mass-autocomplete to divs, it is showing an error message like "mass-autocomplete not allowed on element div".
The following is code I have written. Could you please give the solution for this?
$scope.getClients = {
suggest: suggest_Client
};
<div class="row">
<div class="col-xs-12">
<div class="marginTB15" mass-autocomplete>
<div class="reach_box" contenteditable="true" ng-model="user.communities" mass-autocomplete-item="getNetworks">
<span class="form-control-feedback form-control-feedback_left_textbox"><img src="images/icon7.png" ></span>
<div class="reach"></div>
</div>
</div>
</div>
</div>
Seems that you using the mass-autocomplete directive incorrectly, it need so have an <input> tag as a element. Consider just having 2 blocks inside your div - one is a normal autocomplete:
<div mass-autocomplete>
<input ng-model="user.communities" mass-autocomplete-item="getNetworks">
</div>
while another one is a static end result of the autocompletion - say <div>{{user.communities}}</div>. And those two will be toggled by click for example. By this you wont' need content-editable at all.
So full code may look like this:
//controller
$scope.stateEdit = false;
$scope.toggleWidgetState = function(){
$scope.stateEdit = !$scope.stateEdit;
}
$scope.getClients = {
suggest: suggest_Client,
on_select:toggleWidgetState //here we put our widget back to read-only state
};
//other logic to handle mass-autocomplete
//template
<div class="row">
<div class="col-xs-12">
<div mass-autocomplete ng-show="stateEdit">
<input ng-model="user.communities" mass-autocomplete-item="getNetworks">
<ul> <li>Cardiologist Connect<button type="button">X</button></li></ul>
</div>
<div ng-show="!stateEdit" ng-click="toggleWidgetState()">
{{getNetworks}}
<span class="form-control-feedback form-control-feedback_left_textbox"><img src="images/icon7.png" ></span>
<div class="reach"></div>
</div>
</div>
</div>

How to get an element inside nested divs by class name?

A webpage with HTML looks like this:
<div id="Parent-div" > </div>
<div class="first-child-div"> </div>
<div class=" second-child-div">
<div class="first-grand-child"> </div>
<div class="second-grand-child"> </div>
<div class="Third-grand-child">
<div class="Grand-grand child">
<button class="Confirm-button">Confirm!</button>
</div>
</div>
</div>
I've Tried This code using greasemonkey to remove
a button from the div with the class named "Grand-grand child"
This is what I did:
var targetDiv = document.querySelector("#<Parent-div>. Grand-grand.child");
targetDiv.innerHTML = "Hello world!";
The Button wasn't replaced by the Hello world! text, What did I do wrong?
document.querySelector('.Grand.grand.child');
Demo: http://jsfiddle.net/yGv3v/
You should change <div class=" Grand grand child"> to <div class="Grand-grand-child"> and then you can select it with $('.Grand-grand-child').
Edit
If you want to use pure JavaScript, then you can select the node element via
var grandChildChildNode = document.getElementsByClassName('Third')[0].children[0]
This should work in sufficiently modern browsers.

Get elements just 1 level below the current element by javascript

I need to access the DOM tree and get the elements just 1 level below the current element.
Read the following code:
<div id="node">
<div id="a">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
I want to get the 3 elements "a", "b", "c" under "node". What should I do?
var nodes = node.getElementsByTagName("div") <---- I get all the divs but not the 3 divs I need.
var nodes = node.childNodes; <---- works in IE, but FF contains Text Node
Does anyone know how to solve the problem?
You could use a function that rules out all non-element nodes:
function getChildNodes(node) {
var children = new Array();
for(var child in node.childNodes) {
if(node.childNodes[child].nodeType == 1) {
children.push(child);
}
}
return children;
}
I'd highly recommend you look at JQuery. The task you're looking to do is straightforward in pure Javascript, but if you're doing any additional DOM traversal, JQuery is going to save you countless hours of frustration. Not only that but it works across all browsers and has a very good "document ready" method.
Your problem solved with JQuery looks like:
$(document).ready(function() {
var children = $("#node").children();
});
It looks for any element with an id of "node" then returns its children. In this case, children is a JQuery collection that can be iterated over using a for loop. Additionally you could iterate over them using the each() command.
This is simplier than you think:
var nodes = node.querySelector("node > div");
Try this (late answer, but can be useful for others):
var list;
list=document.getElementById("node").querySelectorAll("#node>div");
Universal selectors can do the trick:
var subNodes = document.querySelectorAll("#node > *");
Query parts:
#node is unique container selector
> next slector should be applied only on childs
* universal selector that match every tag but not text
Can I use universal selector
In my opinion the easiest way to do this is to add a class name to the
first level child nodes:
<div id="node">
<div id="a" class="level_1">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b" class="level_1">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c" class="level_1">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
and then to use the method getElementsByClassName, so in this case:
document.getElementById('node').getElementsByClassName('level_1');
I think node.childNodes is the right place to start. You could (to make it work with FF too), test the nodeName (and possibly nodeType) of all child nodes you get, to skip text nodes.
Also you might have a look at some javascript library like prototype, which provide a lot of useful functions.
I've added some text so we can see that it is working, and JavaScript that will add "added!" to the bottom of each of the divs at the base:
var cDiv = document.querySelectorAll('body > div > div'), i;
for (i = 0; i < cDiv.length; i++)
{
cDiv[i].appendChild(document.createTextNode('added!'));
}
<div id="node">
<div id="a">a
<div id="aa">aa
<div id="ab">ab
<div id="aba">aba</div>
</div>
</div>
</div>
<div id="b">b
<div id="ba">ba
<div id="bb">bb
<div id="bba">bba</div>
</div>
</div>
</div>
<div id="c">c
<div id="ca">ca
<div id="cb">cb
<div id="cba">cba</div>
</div>
</div>
</div>
</div>

Categories