Edit: Adding more to the code
I'm learning how to create functions that traverse and act on elements in the DOM, but I'm running into an issue where the bellow variable "child" won't hold the value of children[i] so I can't act on it. I can't even act just on children[i] so when I check for the classList, there isn't anything there. What is it that I don't understand?
var newFunc = function(className){
var current = document.body;
var children = current.childNodes;
var results = [];
if( current.classList.contains(className) ){
results.push(current);
}
for (var i=0; i<children.length; i++){
var child = children[i];
if (child.classList.contains(className)){
results.push(child);
}
}
return results;
};
Thanks! I've been looking through MDN for awhile and done some googling but I think I may be asking the wrong question.
Related
Hi I work on js practise about dom, and I found discripancy in code.
var numberOfDrumButtons = document.querySelectorAll(".drum").length;
for(var i = 0; i<numberOfDrumButtons; i++){
document.querySelectorAll(".drum")[i].addEventListener("click", function(){
alert("I got clicked.");
});
}`
The code above works properly, but the following two snippets of code won't work...
First one is that function is nested inside for loop.
var numberOfDrumButtons = document.querySelectorAll(".drum").length;
for(var i = 0; i<numberOfDrumButtons; i++){
document.querySelectorAll(".drum")[i].addEventListener("click", handleClicked)
function handleClicked(){
alert("I got clicked.");
}
Second is that I define function first, which means outside for loop.
var numberOfDrumButtons = document.querySelectorAll(".drum").length;
function handleClicked(){
alert("I got clicked.");
}
for(var i = 0; i<numberOfDrumButtons; i++){
document.querySelectorAll(".drum")[i].addEventListener("click", handleClicked)
}
I would like to ask why this happens.
I have a document with Google drawings that for whatever reason are not selectable within the UI. I am not sure how they were ever placed.
I was hoping to write a script to delete them, but I'm not finding a function that applies to drawings specifically.
I'm wondering if anyone knows a trick to accomplish this..
The closest thing I found was their sample for deleting images:
function myFunction() {
var body = DocumentApp.getActiveDocument().getBody();
// Remove all images in the document body.
var imgs = body.getImages();
for (var i = 0; i < imgs.length; i++) {
// Retrieve the paragraph's attributes.
var atts = imgs[i].getAttributes();
// Log the paragraph attributes.
for (var att in atts) {
Logger.log(att + ":" + atts[att]);
}
imgs[i].removeFromParent();
}
}
Never too late (I hope). The trick here is that inline drawings (InlineDrawing) are children of Paragraph or ListItem (source).
If you want to remove some inline drawings, the code below works for me. If you want to find all drawings, please see the TODO comment. It is a simple code, please enhance it if you intend to use it. Just for reference.
Unfortunately, to this time, I didn't find out how to remove drawings that are not inline (drawings that are above or below text). Please forgive my limitation.
function eraseSomeDrawingsFromDoc() {
var body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs()
paragraphs.forEach(paragraph => {
const childIfAny = paragraph.getNumChildren() > 0 && paragraph.getChild(0) //TODO: analyze all children
const childType = childIfAny && childIfAny.getType()
const iAmADrawing = childType === DocumentApp.ElementType.INLINE_DRAWING
if(iAmADrawing) childIfAny.removeFromParent()
})
}
I'm working on a project which contains a list of images in an unordered list and I thought it would be neat to be able to perform an action which would duplicate the list item and add it to a second unordered list. Essentially this would be creating a list of favorites while maintaining the original list.
I'm fairly new to html so I'm not sure how I could go about achieving this. Any help would be appreciated.
Here's the entire JSFiddle (without actual images) in pure JS.
I implemented exclusion of duplicates through the for loop inside the following function:
function copyToFavorites(event) {
var image = event.srcElement;
var src = image.src;
var dup;
// determine if it's a duplicate
var ul = document.getElementById("fav");
var images = ul.getElementsByTagName("img");
for (var i = 0; i < images.length; ++i) {
dup = (images[i].src === src);
if (dup) {
break;
}
}
// if not a duplicate - add to favorites
if (! dup) {
var li = document.createElement("li");
var newImg = document.createElement("img");
newImg.src = src;
li.appendChild(newImg);
ul.appendChild(li);
} else {
alert("This ismage is already in Favorites");
}
}
Could not come up with anything more elegant.
You can achieve it using javascript, jQuery or any other help. Check this example using jQuery. It only have text in the example but it will work perfect with any content inside the li tag. http://goo.gl/bplTrm
I'm using the mootools wall plugin, Its working well in my application, however if I add multiple (image) walls it only works for one wall ::: My understanding of scripting is not good enough to add a each function or similar :::
I need to "bind" the code below to say 2 divs like this :::
My First wall:
<div id="viewport">
<div id="wall">
Second wall:
<div id="viewport">
<div id="wall_02">
Any assistance would be appreciated.
var wallIMAGES = new Wall( "wall", {
"width": scArray[1],
"height": scArray[1],
callOnUpdate: function(items){
items.each(function(e, i){
var el = wall[counterFluid];
if (el) {
var a = new Element("img[width="+scArray[1]+"][height="+scArray[1]+"][src={thumb}]".substitute(el));
a.inject(e.node).set("opacity", 0).fade("in");
e.node.store("tubeObject", el);
}
counterFluid++;
// Reset counter
if( counterFluid >= scArray[10].length) counterFluid = 0;
})
}
});
wallIMAGES.initWall();
Maybe something like this:
var my_wall_ids = ['wall', 'wall_02'];
var myWalls = [];
var baseWallOptions = {
"width": scArray[1],
"height": scArray[1],
callOnUpdate: function(items){
items.each(function(e, i){
var el = wall[counterFluid];
if (el) {
var a = new Element("img[width="+scArray[1]+"][height="+scArray[1]+"][src={thumb}]".substitute(el));
a.inject(e.node).set("opacity", 0).fade("in");
e.node.store("tubeObject", el);
}
counterFluid++;
// Reset counter
if( counterFluid >= scArray[10].length) {counterFluid = 0;}
}); // end items.each
}
}
for (var i=0;i<my_wall_ids.length;i++){
var id = my_wall_ids[i];
var wallOptions = baseWallOptions;
// if your customization was something like changing
// the height , but only on the 'wall' element
if (id === 'wall') {
wallOptions.height = 400;
}
myWalls[i] = new Wall(id, wallOptions);
myWalls[i].initWall();
}
If you read Wall's documentation, you'll notice that, just like most other classes, the first argument it takes is an element id.
So, if your initialization code states
new Wall("wall", { …
…then it will be applied to the element that has the id "wall".
You could simply duplicate your code and use one with "wall", the other one with "wall_02". However, that would be bad practice. Indeed, if you later wanted to change some options, you'd have to do it in two distinct blocks, and they would probably get out of sync.
If your only difference lies in the target id, and the options are to be shared, simply store the options object (second parameter to the Wall class) in a variable and use it twice! That is:
var wallOptions = { width: … };
var wallImages = new Wall("wall", wallOptions),
wallImages2 = new Wall("wall_02", wallOptions);
wallImages.initWall();
wallImages2.initWall();
It could be even better to embed initalization in a function, but this solution is probably the easiest if you simply want to have two Wall instances without learning much more about JS.
I have a tree with nodes, and a delete button, first user select the node and click this delete button, I want this node to be removed from the tree, Its not XML, every node in tree is of type Object
{label:'folder',children:[{label:'file1'}]}
I tried delete myTree.selectedItem (but compiler wont let me do it)
also tried myTree.selectedItem = null (just unselects the item)
and also how can I access reference to parent object of myTree.selectedItem?
Without a parent node reference this is going to be quite hard. I would suggest to create a class TreeNode or so instead of a vanilla object. Besides the "label" and the "children" property, give the node a "parent" property and set the parent when you create the model for the tree.
Then when you select and item and click the remove button, you can get the parent node of the selected node and call a "removeChild" or so on it. This should then remove the given childnode.
It might be that you need to invalidate the model of tree after removing a node. You can do this with:
myTree.invalidateList();
var item:* = tree.selectedItem;
var parent:* = tree.getParentItem(item);
var p:int = tree.getItemIndex(parent);
var i:int = tree.getItemIndex(item);
var index:int = i - p - 1;
tree.dataDescriptor.removeChildAt(parent, item, index);
Almoust the same, but it works better for me.
Here is a way to remove leaf nodes with the MX Tree using the dataDescriptor.
var parent:Object = tree.getParentItem(tree.selectedItem);
var p:int = tree.itemRendererToIndex(tree.itemToItemRenderer(parent))
var i:int = tree.itemRendererToIndex(tree.itemToItemRenderer(tree.selectedItem))
tree.dataDescriptor.removeChildAt(parent,tree.selectedItem,i - p - 1);
you can use this as your removal function:
private function removeEmployee():void {
var node:XML = XML(tree.selectedItem);
if( node == null ) return;
var children:XMLList = XMLList(node.parent()).children();
for(var i:Number=0; i < children.length(); i++) {
if( children[i].#name == node.#name ) {
delete children[i];
}
}
}