Javascript Compare Objects to Elements - javascript

http://jsfiddle.net/PhilFromHeck/KzSxT/
In this fiddle, you can see at line 38 in the Javascript that I've attempted to make a comparison that isn't working. I believe it because one of the variables is an Object, where the other is an Element; does anyone have any advice as to how I can can find a match between these two?
menuID[0] = document.getElementById('menuOne');
menuID[1] = document.getElementById('menuTwo');
menuID[2] = document.getElementById('menuThree');
menuID[3] = document.getElementById('menuFour');
$('.menu').mouseenter(function () {
for (var i = 0; i < 3; i++) {
if(menuID[i] == $(this)){
//this condition is not met, there's an alert which will add more detail in the fiddle
}
}
}

Method document.getElementById returns a DOM element an not a jQuery object. In the mouseenter event handler this refers to a DOM element as well.
So in order to compare them you shouldn't convert this to a jQuery object:
if (menuID[i] === this) { ... }

You want to use jQuery's .is() for this.
if($(this).is(menuID[i])){

A few issues I see here:
One is simply that, in your jsfiddle, the first 4 lines of code that you list aren't running before the bottom block runs. I'm not sure why you have both an init function that you attach to window.onload and a document.ready() function; but you'll want to make sure that init runs.
Secondly; as VisioN said, I think the main issue is that you're trying to compare a jQuery wrapper around a DOM element $(this) with a DOM element (the result of getElementById). As he says, this == menuID[i] will work.
At a design level, why not simply use the id to identify the element? this.id will give you the the id; why not simply use that to determine which menu div you're looking at?

Related

jQuery objects and elements

I know I've seen a beautifully straightforward answer to a similar question before, but I haven't been able to remember or locate it, so apologies in advance.
I'm not new to coding, but I've had no formal training with Javascript/jQuery. Everything else I used has been strictly typed, so I'm still struggling with how JS does typing. I have a function that fires every time a child of a specific class is changed (I'm writing this for Sharepoint, so there is some working-around that has to be done.)
Why is it when I write this:
$(".listen *").change(function(event) {
var element = event.target;
if (element.title == 'Workstation')) {
alert(element.val());
}
}
I get an error that .val() is not a function, and I have to instead write
$(".listen *").change(function(event) {
var element = event.target;
if (element.title == 'Workstation')) {
alert($('#' + element.id).val());
}
}
What is the difference between the object that "element" is and the object retrieved by using the id? Aren't they both jQuery objects? I realize that not all objects returned by my function might actually have a value to return, but I don't understand how the distinction is being made.
Thanks!
In your first code block the 'element' variable is not a jQuery object, it is a DOM object. The .val() method is not defined for DOM objects. It is only defined for jQuery objects.
In your second code block $('#' .element.id) returns a jQuery object that does have the val() method defined.
So to answer your question, No they are not both jQuery objects, only the second one is.
You must make jQuery object from your dom (event.target) like that;
$(".listen *").change(function(event) {
var element = $(event.target);
if (element.attr('title') == 'Workstation')) {
alert(element.val());
}
}
Then you can use your jQuery object as you want. By the way, if you want to catch the changed element, you can use $(this) instead of $(event.target).
$(".listen *").change(function(event) {
var element = $(this);
if (element.attr('title') == 'Workstation')) {
alert(element.val());
}
}

JQuery to Javascript Document.Write

Fiddle (Uses JQuery) - http://jsbin.com/ponikasa/1/edit
I know JQuery is Javascript, but for the sake of an argument how do you write the following in pure Javascript without the need for a js library like JQuery?
$(document).ready(function() {
$('.preview-site').on('click', function(){
window.open('javascript:document.write("'+ $('.workflow').val() +'")', 'Opened Page', 'width=660, height=440');
return false;
});
});
I tried this, but doesn't work.
Any help is greatly appreciated.
window.onload = function() {
var preview = document.getElementsByClassName("preview-site"),
code = document.getElementsByClassName("workflow")[0].value;
preview.onClick = function() {
window.open('javascript:document.write("'+ code = +'")', 'Opened Page', 'width=660, height=440');
return false;
}
}
Well to write in javascript you would do the following
document.addEventListener('DOMContentLoaded', function() {
var previewSite = this.querySelectorAll('.preview-site');
var handler = function() {
var workflow = document.querySelector('.workflow')
window.open('javascript: document.write(' + workflow.value + ')', 'Opened Page', 'width=660, height=440')
return false;
};
for( var i = 0; i < previewSite.length; i++) {
previewSite[i].addEventListener('click', handler);
}
});
The problem you had is getElementsByClassName returns a collection, so you cannot use value or onclick on the collection.
I use querySelectorAll because it's easier and has almost better support that getElementsByClassName
I don't usually answer questions like this, but I am highly supportive of anyone that uses jQuery that want's to actually learn javascript it's self
also, in your question, you have onClick, for the event handler you want onclick
For one minor performance improvement you could move workflow out of handler, that way it won't fetch it on every click, only do this if you don't intend to add dynamic .workflow
Yeah, and also. (as pointed out in comments) window.onload is not the same as document ready, window.onload will wait for images & media to be fully loaded, so use DOMContentLoaded
One of the things jQuery selectors do is try to abstract the "array" when calling functions and assigning handlers. Consider something like this:
$('.preview-site').on('click', function(){
// code
});
This code doesn't just assign the click handler. On a lower level than that presented by the jQuery interface, this iterates the array of .preview-site elements and assigns the click handlers to each element. Sometimes it's one element, sometimes it's many. (Sometimes it's none.) jQuery makes the interface the same regardless of the count.
Without it, you need to handle that difference explicitly. These values are arrays:
var preview = document.getElementsByClassName("preview-site"),
code = document.getElementsByClassName("workflow");
Even if each one only finds a single element by that class name, the result from document.getElementsByClassName() is an array. So even if the array has only one element, it's still an array. And you can't assign a handler to an array, you need to assign it to each element in the array. Potentially something like this:
for (var i = 0; i < preview.length; i++) {
preview[i].addEventListener('click', function() {
window.open('javascript:document.write("'+ code[i].value[0] +'")', 'Opened Page', 'width=660, height=440');
return false;
}
}
Naturally, you'd probably want to put in some checks to ensure that the two arrays are the same length before assuming that for each preview element there exists a code element. But the principle is the same. You just need to account for the enumeration of the array manually.

Select ALL elements with specific data attribute Javascript?

With jquery, I've got the following code:
$('a[data-hello]').click(function(){ = That select all "a" elements with "data-hello".
I'm trying to make this with raw Javascript. I stop here:
document.querySelectorAll("data-hello").onclick = function() {
(btw, theres a way to select all the A elements with data-hello and not all with data-hello? o.O)
But querySelectorAll returns a Array. Because of this, it only works if I determine a position. This way:
document.querySelectorAll("data-hello")[5].onclick = function() {
But I want ALL ELEMENTS, not specific elements, like with jQuery. I cant use jQuery.
It is so simple with Jquery :( I must make a "for" to wade through all the positions in JS? Is this necessary? sorry I do not understand...
What I want to do:
I want to get the data attribute value of the element that is clicked. I use this for this inside the function and, then, I applied another function that add a class in a specific element.
Basically, there is buttons with classes in data attribute value. This classes will be applied to a specific element.
Put the array (actually a NodeList) of elements in a variable and loop through them to set the event handler on each of them. That's what the jQuery methods do to apply something to all elements in a jQuery object. There is no way around the loop, with jQuery it's just hidden within the methods. You can use the same selector syntax as in jQuery with querySelectorAll.
var arr = document.querySelectorAll("a[data-hello]");
var f = function() {
// do something
};
for (var i = 0; i < arr.length; i++) {
arr[i].onclick = f;
}
querySelectorAll accepts a string of comma-separated CSS selectors, just like jQuery, so you can give it the same string: 'a[data-hello]'.
The difference between native and jQuery that you are running into is in calling methods on the elements returned. jQuery returns a jQuery object, which has methods that often loop over all the elements, .click() being one such methods. You need to replicate that with the array of elements that querySelectorAll is returning by looping over the array and applying the same handler to each element's onclick property.
Try this:
var myElements = document.querySelectorAll("a[data-hello]");
Array.prototype.forEach.call(myElements, function (element) {
element.onclick = function () {
// Your onclick handler code goes here.
console.log('clicked', element);
};
});
as simple as that:
var dataElems = document.querySelectorAll("[data-hello]")
for (var i=0;i<dataElems.length;i++) {
dataElems[i].onclick = function(i,v) {
alert(this.innerHTML)
}
}
example http://jsfiddle.net/acrashik/W86k8/

Javascript change width of div onclick

I'm trying to do three things onclick:
have element with id="notes_content" change display:none to display: block
have element with id="oct" change width = "1190px" to width = "550px"
have elements with class="oct_days" change width = "168px" to width = "73px"
Fiddle of full code: http://jsfiddle.net/ascottz/jX3wh/
The first two happen, but the third does not. I suspect it is a syntax error, but can't catch it myself.
getElementsByClassName returns an array of dom elements, it is not a single instance. You must loop over the array and style each element.
Have a look at the updated fiddle.
for( var i = 0; i < days.length; i++ ){
days[i].style.width = "73px";
}
http://jsfiddle.net/jX3wh/4/
document.getElementsByClassName returns somewhat an array of elements, so you cannot simply refer to it as a DOM element in hope that it will work as you refer to each element of the collection (that is possible in jQuery, btw), so you have to use the foreach loop (doesn't matter how are you gonna achieve this -- via simple for(), or for(x in y), or any other way).
I usually use Array.forEach function, but the specific type of an array returned by the document.getElementsByClassName does not have such function in prototype, so you have to use [].forEach.call(inWhat,function(what){}) syntax, or fallback to for(...) syntax.
Check out this: http://jsfiddle.net/jX3wh/1/
Dunno if it works.
Also, what the f is this???
<div onclick="javascript:showDiv();" class="oct_days">
I am really very surprised this works. You should use onclick="showDiv()" instead, I think.
Somebody, please, tell me how does it work!

Adding onclick properties to each item in DOM object list in Javascript

I'm trying to move away from jQuery for my everyday site functionality, and I'm having a little bit of trouble with the onclick event. I'd like to put together a function like jQuery's .click(), but simply using document.getElementsByTagName and adding a func onclick won't work.
The question then is how would one add a single function to fire onclick to all elements in the list object returned by querying document.getElementsByTagName('h4')
EDIT: Just in case someone finds this and would like some code, here's what I did:
var headings = document.getElementsByTagName('h4')
for (var g in headings) {
headings[g].onclick = function() {
//code
}
}
You need to loop through the list and pass the event to each item.
I think there is no simpler way to do this, expect you need a library like jQuery or you write your own eventManager...

Categories