DOM Traversal API - javascript

I am tryingto get the parent of nodes. I tried these.
Ist Approach:
function update(currentElement) {
document.getElementById("nodeNameField").value = currentElement.nodeName;
document.getElementById("nodeTypeField").value = currentElement.nodeType;
document.getElementById("nodeValueField").value = currentElement.nodeValue;
}
function nodeMove(direction) {
switch (direction)
{
case "parentNode": if (nodeMove.currentElement.parentNode)
nodeMove.currentElement = nodeMove.currentElement.parentNode;
else
alert("No parent");
}
update(nodeMove.currentElement);
}
window.onload = function () {
document.getElementById("parentBtn").onclick = function () {nodeMove("parentNode")};
nodeMove.currentElement = document.documentElement; // HTML
update(nodeMove.currentElement);
}
Since the current element is HTML, when i click on the parent button, I do get #document as it's parent.
2nd approach:
if (document.createTreeWalker) {
function myFilter(n) {
return NodeFilter.FILTER_ACCEPT;
}
var myWalker = document.createTreeWalker(document.documentElement,NodeFilter.SHOW_ALL,myFilter, false);
} else
alert("Error: Browser does not support DOM Traversal");
function update(currentElement) {
window.document.testform.nodeName.value = currentElement.nodeName;
window.document.testform.nodeType.value = currentElement.nodeType;
window.document.testform.nodeValue.value = currentElement.nodeValue;
}
var currentElement = myWalker.currentNode;
//var currentElement = document.documentElement;
update(currentElement);
</script>
<form>
<input type="button" value="Parent" onclick="myWalker.parentNode();update(myWalker.currentNode);">
In the 2nd case, i am unable to get the parent of HTML. How will I resolve it? Any suggestions?

If you declare myWalker inside if scope, it won't be visible for outer/global scope. Move declaration over this scope like here:
var myWalker;
if (document.createTreeWalker) {
function myFilter(n) {
return NodeFilter.FILTER_ACCEPT;
}
myWalker = document.createTreeWalker(document.documentElement,NodeFilter.SHOW_ALL,myFilter, false);
} else
alert("Error: Browser does not support DOM Traversal");
function update(currentElement) {
window.document.testform.nodeName.value = currentElement.nodeName;
window.document.testform.nodeType.value = currentElement.nodeType;
window.document.testform.nodeValue.value = currentElement.nodeValue;
}

Related

The if condition always return true

please help here: the if condition always return true though it is false??
these are the html code for variable div and variable your at the beginning
(<div class="div" id="div" style="background:yellow"></div>)
(<input type="text" id="your">)
$(document).ready(function generate() {
"use strict";
var x = $(".2").text(Math.floor((Math.random() * 10))),
z = $(".3").text(Math.floor((Math.random() * 10)));
$(".div").text(x.text() + z.text());
});
var show = document.getElementById("show"),
your = document.getElementById("your").value,
div = document.getElementById("div").textContent;
show.onclick = function () {
"use strict";
if (your == div) {
alert("yes");
} else {
alert("noo");
}
};
The problem is, that you are defining the values outside of the function. So in the onclick handler you are comparing the initial values.
If you want the actual values, you should access the values inside the function:
var show = document.getElementById("show"),
your = document.getElementById("your"),
div = document.getElementById("div");
show.onclick = function () {
if (your.value == div.textContent) {
alert("yes");
} else {
alert("noo");
}
};

How can I write my listener function somewhere else if it uses local variables?

I am a beginner in Javascript development and I have to do the classical to-do app. It has to be object-oriented and my program has two classes: Task and Tag.
A task contains some tags.
When the user clicks on a tag, he can modify its name. First, I did wrote an anonymous callback function which was listening to the modification form submission and it worked well. But, I have to create a named function declared somewhere else instead of my existing listener. However, I need to access to some of the properties of my object (which is edited) and I have absolutely no idea how to do a thing like that.
Here is a small part of my code:
module.Tag = class Tag {
constructor(name = 'untitled', parent = null) {
this.name = name;
this.parentTask = parent;
}
//Method which displays the tag name
display_name() {
return $('<li>').addClass('tag').text(this.name);
}
//Method which displays the tag
display() {
let tag_item = this.display_name();
let field = $('<input>').prop('type', 'text').prop('value', this.name);
let button = $('<button>').addClass('validationButton').prop('type', 'submit').text('✓');
let removeButton = $('<button>').addClass('removeButton').text('X');
let form = $('<form>').append(field).append(button).append(removeButton);
let in_edit = false;
tag_item.click((event) => {
event.stopPropagation();
event.preventDefault();
let target = $(event.target);
if (target.is('li') && !in_edit) {
tag_item.empty();
tag_item.append(form);
in_edit = true;
}
if (target.is('button') && target.prop('type') === 'submit') {
if(field.val() !== '') {
this.name = field.val();
module.StorageManager.storeTasks();
}
tag_item.empty();
tag_item.text(this.name);
field.val(this.name);
in_edit = false;
}
if (target.is('button') && target.hasClass('removeButton')) {
if(confirm('Voulez-vous vraiment supprimer ce tag ?')) {
tag_item.remove();
this.removeTagFromParent();
module.StorageManager.storeTasks();
}
}
});
return tag_item;
}
//Method which removes the tag from the parent task
removeTagFromParent() {
this.parentTask.removeTag(this);
}
};
My listener is in the display method and it uses Tag.name property and some of the variables created in the method body. I can't see how to write this function somewhere else and Google didn't help me.
I hope my problem is clear, English is not my native language.
Some advices?
You can extract your anonymouse function to be another class method. It is an event handler so in order to correctly access the defined object you'll have to bind it correctly.
Here is an example of the modified script:
module.Tag = class Tag {
constructor(name = 'untitled', parent = null) {
this.name = name;
this.parentTask = parent;
}
//Method which displays the tag name
display_name() {
return $('<li>').addClass('tag').text(this.name);
}
//Method which displays the tag
display() {
let tag_item = this.display_name();
let field = $('<input>').prop('type', 'text').prop('value', this.name);
let button = $('<button>').addClass('validationButton').prop('type', 'submit').text('✓');
let removeButton = $('<button>').addClass('removeButton').text('X');
let form = $('<form>').append(field).append(button).append(removeButton);
let in_edit = false;
tag_item.click(this.handleClick.bind(this));
// this is where you invoke the function and
//bind it to the context of the class
return tag_item;
}
//Method which removes the tag from the parent task
removeTagFromParent() {
this.parentTask.removeTag(this);
}
// extracted method defined here:
handleClick(event) {
let tag_item = this.display_name();
let field = $('').prop('type', 'text').prop('value', this.name);
event.stopPropagation();
event.preventDefault();
let target = $(event.target);
if (target.is('li') && !in_edit) {
tag_item.empty();
tag_item.append(form);
in_edit = true;
}
if (target.is('button') && target.prop('type') === 'submit') {
if(field.val() !== '') {
this.name = field.val();
module.StorageManager.storeTasks();
}
tag_item.empty();
tag_item.text(this.name);
field.val(this.name);
in_edit = false;
}
if (target.is('button') && target.hasClass('removeButton')) {
if(confirm('Voulez-vous vraiment supprimer ce tag ?')) {
tag_item.remove();
this.removeTagFromParent();
module.StorageManager.storeTasks();
}
}
}
};

javascript multiple functions at once

As I needed help here
#ryanpcmcquen offered great help, but as a "noob" at javascript I would like to know 2 more things
When I want to create another function how do I make it?
document.addEventListener('DOMContentLoaded', function () {
'use strict';
var unitBlock = document.querySelector('select#unit_block');
var unitRowBig = document.querySelector('select#unit_row_big');
var unitRow = document.querySelector('select#unit_row');
var unitColumn = document.querySelector('select#unit_column');
var unitSize = document.querySelector('select#unit_size');
unitBlock.addEventListener('change', function () {
if (unitBlock.value === 'A') {
unitRowBig.disabled = false;
unitRowBig[4].disabled = false;
} else {
unitRowBig.disabled = false;
unitRowBig[4].disabled = true;
}
});
unitBlock.addEventListener('change1', function () {
if ((unitRowBig.value === '1') && (unitBlock.value === 'A')) {
unitRow.disabled = false;
unitRow[8].disabled = true;
unitRow[9].disabled = true;
unitRow[10].disabled = true;
unitRow[11].disabled = true;
unitRow[12].disabled = true;
}
});
});
Because it doesn't seems to work my way.
No need to add a new event, besides change1 is not a valid event, you can find a list of events here:
https://developer.mozilla.org/en-US/docs/Web/Events
Just put that conditional inside the original event handler:
document.addEventListener('DOMContentLoaded', function () {
'use strict';
var unitBlock = document.querySelector('select#unit_block');
var unitRowBig = document.querySelector('select#unit_row_big');
var unitRow = document.querySelector('select#unit_row');
var unitColumn = document.querySelector('select#unit_column');
var unitSize = document.querySelector('select#unit_size');
unitBlock.addEventListener('change', function () {
// You may want to comment out all of this section:
if (unitBlock.value === 'A') {
unitRowBig.disabled = false;
unitRowBig[4].disabled = false;
} else {
unitRowBig.disabled = false;
unitRowBig[4].disabled = true;
}
// Down to here.
// Here's your code!
if ((unitRowBig.value === '1') && (unitBlock.value === 'A')) {
unitRow.disabled = false;
unitRow[8].disabled = true;
unitRow[9].disabled = true;
unitRow[10].disabled = true;
unitRow[11].disabled = true;
unitRow[12].disabled = true;
// Including an antithetical clause,
// to account for the user changing their mind.
} else {
unitRow.disabled = true;
unitRow[8].disabled = false;
unitRow[9].disabled = false;
unitRow[10].disabled = false;
unitRow[11].disabled = false;
unitRow[12].disabled = false;
}
});
});
Note that I also included the opposite disabled conditions in an else clause, in case the user makes one choice, and then changes to another.
In case you really need two separate functions (what is not the case here), just do it like this:
unitBlock.addEventListener('change', function () {
console.log('First event listener')
});
unitBlock.addEventListener('change', function () {
console.log('Second event listener')
});
document.addEventListener stores all the functions you sent to him, so when the change event will be fired, it will execute all of them, in the order you passed them to it.
In short, when the change event is fired, you will have:
> "First event listener"
> "Second event listener"
I hope this helped you!

Listen for keyup on all input fields

Im trying to capture the keyup on all input fields on a page.
My current code is:
var els = document.querySelectorAll('input');
for (var i = 0; i < els.length; i += 1) {
addEvent('keyup', els[i], makeHandler(els[i]));
}
function makeHandler(field) {
console.log(field.value);
}
function addEvent(evnt, elem, func) {
if (elem.addEventListener) {
elem.addEventListener(evnt,func,false);
} else if (elem.attachEvent) {
elem.attachEvent("on"+evnt, function(e) {
e = e || window.event;
if (!e.preventDefault) {
e.preventDefault = preventDefaultOnIE;
}
func.call(this, e);
});
} else { // No much to do
elem[evnt] = func;
}
}
But for some reason its only capturing the value on page load, not once i begin to type in any of the fields.
Any ideas what I'm doing wrong?
The problem is with your makeHandler function. makeHandler(els[i]) is being evaluated and the return value (undefined, in this case) is being passed to addEvent as a handler. Try:
function makeHandler(field) {
return function() {
console.log(field.value);
};
}
This way, makeHandler(els[i]) will return a function that addEvent can then attach to keyup.
Alternatively, you could also just use:
function makeHandler() {
console.log(this.value); // 'this' will be the field that the event occurred on
}
and then use:
addEvent('keyup', els[i], makeHandler);
Side-note
I noticed a slight error in your code:
else { // No much to do
elem[evnt] = func;
}
I think you really want to set elem["on" + evnt] instead.
I like to embed the script in a function so I can minimize it in my IDE and turn it on and off globally. In other words, give it a name.
attachKeyupListenerToInputElements();
function attachKeyupListenerToInputElements(){
var inputs = doc.querySelectorAll('input');
for (var i = 0; i < inputs.length; i += 1) {
inputs[i].addEventListener("keyup", keyupHandler);
}
function keyupHandler() {
console.log(this.value);
}
}
Is this what you are looking for:
<script>
$(document).ready(function () {
$("input").keyup(function () {
alert("keyup");
});
});
</script>

Copy/Paste element with jQuery

I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});

Categories

Resources