this is my script but it doesn't work:
var first = document.getElementById("sheet").rows[0];
var two = first.cells(4);
two.setAttribute('style','display:none');
Note that cells isn't a function or method, it's a property that returns an HTML collection that can be accessed by index:
var two = first.cells[4];
Rather than using setAttribute, just set the property directly:
two.style.display = 'none';
I dont know if youre really trying to set attribute OR add function onBlur - I will answer both
If you want to set an ATTRIBUTE:
Then your approach is actually right - considering two is a HTMLObject
two.setAttribute("class","unchecked"); //this sets class .unchecked to the "two"
This replaces all existing classes with the new class, fine if you only ever use just 1 class.
Historically you'd have work your own class merging, but for modern browsers, there is much more convenient way: two.classList.add("unchecked"); which adds to existing class list instead of replacing it, but only if the class is not there yet :-)
If you want to add a FUNCTION() which would fire onBlur
Then you have to use something to bind - the easiest way is to add a function inside an HTMLObject attribute(property) - notice! HTMLObject attribute (property) IS NOT the same as attribute you see inside your html code:
two.onblur=function(){ /*SomeJavaScriptCode*/ };
or if you already have a function:
two.onblur = cekUndo;
NOTICE! there are no () brackets - the onblur will run the function when its needed you dont want the function to fire immediatly...
I recommend you also to check a .addEventListener method - it is more adjustable and you can add e.g. more functions on one event
Note: You can do <td onblur="myFunction()"> - add it directly to HTML, but I dont think you can do that on the run like this you have to bind :) ...
EDIT: as to your second problem - as RobG said, you have to access the cells collection with [] brackets:
var two = first.cells[4];
Also check if you are actually have a cell of that index (cells are indexed from 0 to X => index 4 means 5th )
Related
I am using WebDriverIO to try to access (ie. getText, getAttribute, click, etc) an element after creating a list of elements. I am easily able to implement this element if I am using the browser.element() method, but the moment I use browser.elements(), I cannot access the individual objects in the array. According to the WebDriverIO docs, I should be able to access them using the value property.
Here is my pseudo-code. I assumed that these two functions should return the same thing:
usingElement() {
return browser.element('.someCss');
}
usingElements() {
return browser.elements('.someCss').value[0];
}
When I try to use the first block of code, it works perfectly fine.. but
when I try to use the second block, it gives me an error saying usingElements.click is not a function or usingElements.getText is not a function, etc.
How can I isolate a single element object after using the browser.elements() method?
I guess you might need to use one of the below two ways:
Way 1:
var elmnts = browser.elements('.someCss');
var element = elmnts.value[0].ELEMENT;
browser.elementIdClick(element);
Way 2:
var element = $$('.someCss')[0];
element.click();
Thanks,
Naveen
Your index reference was placed in the wrong spot. Try:
var myElement = browser.elements('.someCss')[0];
myElement.click();
You don't need to reference the value property, as WebdriverIO is smart enough to infer that for you.
I understand how the pushstack function works and I also understand how to use it for my plugins (I guess that's what its most used for , just for internal use and for end() to function properly and other similar methods) .
now below is the jquery source of pushstack , have a look :
pushStack: function( elems ) {
// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;
// Return the newly-formed element set
return ret;
},
theres a lot going on in that function really and I kind of get most part of it , but I have a small problem , understanding the below lines of code :-
ret.prevObject = this;
ret.context = this.context;
what is prevObject and context ? can somebody give me a clue , it definitely does't seem to be a javascript thing ?
Basically prevObject is used to allow flexibility for the jquery selectors chaining syntax.
Most of jQuery's DOM traversal methods operate on a jQuery object instance and produce a new one, matching a different set of DOM elements. When this happens, it is as if the new set of elements is pushed onto a stack that is maintained inside the object. Each successive filtering method pushes a new element set onto the stack
Everytime you make a new filter a new jquery instance is constructed matching your selector and the previous one is stored in it to allow the .end() and the addBack() functions to work (most of the DOM transversal functions use pushStack internally). If this property were not used every selector will forget about the previous one and it will not behave like a stack. Think parent instead of prevObject and it will make it easier to understand.
The context property is deprecated in jQuery 1.10 and only used for supporting live() method but it must be added because the returning object is constructed merging an empty jQuery constructor as first parameter and a set of elements as the second.
var ret = jQuery.merge( this.constructor(), elems );
Because .merge returns the first array modified it's context property might not have the correct value so is overwritten with the correct one this.context
Check this jsfiddle and open the console. You will see that the first value of prevObject is the document as we are making a new selector and then is the ul element since we filter using find. Moreover you can go to the last filter and lookup the whole chain of selectors up to the document again.
I recommend you to use the JQuery API instead of this property as reference in production but this will allow you for example to know the result of all the selectors that have been applied to obtain a given set of DOM elements.
$(function(){
var z = document.body.children[0];
var x=$("li", z);
x.name="Johnny";
alert(x.prop(name));
});
x should be an object containing all the elements within the first ul in the body.
Regardless of what the object contains, I would like to add a property with a value, and then use the prop() method to show it - but that doesn't seem to work. Why is that?
I saw a script containing the following: var $x = $("div"); - Do I have to add $ to the variable name if it's a jQuery object?
To select the first ul element inside a page you can do:
$("ul:first li")
This way you are going to select all lines inside the first list in the page.
To store arbitrary data in an element you can use the method data, like this:
$("element").data('key', 'value');
and to retrieve the data:
$("element").data('key');
More info, for the data method.
If you really want to add an attribute you can use the attr method, it works the same way as the data method, but it would reflect in the DOM.
If you want all li elements in the first ul element, then this should do the trick:
var elements = $("ul:eq(0) li");
Here is a very simple example of this in action.
In regards to setting a property, you can do element.name = "test" and it will work ok. But what you need to understand is that this is setting a name property on the jquery collection object and NOT on any of the actual elements.
What you can do however, is set the property like so:
elements.prop("name", "test");
and the access it like so:
var name = elements.prop("name");//name will be "test"
Here is a working example
As I mentioned in my comment, you don't need to prefix the variable with $. But this can be helpful to easily see which variables are JQuery objects.
Number 1. x is a jQuery object, you added to that instance a name property, then you're using name though it wasn't defined.
If you want to change a property of the element you got with jQuery the ways are:
$('selector').prop('property', 'value');
$('selector').attr('attribute', 'value');
$('selector').get(index).property = "value";
Number 2. no you don't have to, $ prefix is simply a convention to make the code more readable.
Is there any specific reason behind using $ with variable in jQuery
Using the selector from #musefan answer, you can take the collection returned, and use the attr() method to add an attribute and value to each item selected. However, I've modified his selector slightly to actually grab "all" elements in there, (just in case future visitors wonder)
var elements = $("ul:eq(0)").children();
elements.attr("attrName", value);
So if you wanted to set the title:
var elements = $("ul:eq(0)").children();
elements.attr("title", "Johnny");
You probably don't want to alert these values, browsers may ask you to stop allowing alerts on the page... but if you really did, then you could throw in an .each() after that.
var elements = $("ul:eq(0)").children();
elements.attr("title", "Johnny").each(function(){
alert($(this).attr("title");
});
Is this:
var contents = document.getElementById('contents');
The same as this:
var contents = $('#contents');
Given that jQuery is loaded?
Not exactly!!
document.getElementById('contents'); //returns a HTML DOM Object
var contents = $('#contents'); //returns a jQuery Object
In jQuery, to get the same result as document.getElementById, you can access the jQuery Object and get the first element in the object (Remember JavaScript objects act similar to associative arrays).
var contents = $('#contents')[0]; //returns a HTML DOM Object
No.
Calling document.getElementById('id') will return a raw DOM object.
Calling $('#id') will return a jQuery object that wraps the DOM object and provides jQuery methods.
Thus, you can only call jQuery methods like css() or animate() on the $() call.
You can also write $(document.getElementById('id')), which will return a jQuery object and is equivalent to $('#id').
You can get the underlying DOM object from a jQuery object by writing $('#id')[0].
Close, but not the same. They're getting the same element, but the jQuery version is wrapped in a jQuery object.
The equivalent would be this
var contents = $('#contents').get(0);
or this
var contents = $('#contents')[0];
These will pull the element out of the jQuery object.
A note on the difference in speed. Attach the following snipet to an onclick call:
function myfunc()
{
var timer = new Date();
for(var i = 0; i < 10000; i++)
{
//document.getElementById('myID');
$('#myID')[0];
}
console.log('timer: ' + (new Date() - timer));
}
Alternate commenting one out and then comment the other out. In my tests,
document.getElementbyId averaged about 35ms (fluctuating from 25ms up to 52ms on about 15 runs)
On the other hand, the
jQuery averaged about 200ms (ranging from 181ms to 222ms on about 15 runs).
From this simple test you can see that the jQuery took about 6 times as long.
Of course, that is over 10000 iterations so in a simpler situation I would probably use the jQuery for ease of use and all of the other cool things like .animate and .fadeTo. But yes, technically getElementById is quite a bit faster.
No. The first returns a DOM element, or null, whereas the second always returns a jQuery object. The jQuery object will be empty if no element with the id of contents was matched.
The DOM element returned by document.getElementById('contents') allows you to do things such as change the .innerHTML (or .value) etc, however you'll need to use jQuery methods on the jQuery Object.
var contents = $('#contents').get(0);
Is more equivilent, however if no element with the id of contents is matched, document.getElementById('contents') will return null, but $('#contents').get(0) will return undefined.
One benefit on using the jQuery object is that you won't get any errors if no elements were returned, as an object is always returned. However you will get errors if you try to perform operations on the null returned by document.getElementById
No, actually the same result would be:
$('#contents')[0]
jQuery does not know how many results would be returned from the query. What you get back is a special jQuery object which is a collection of all the controls that matched the query.
Part of what makes jQuery so convenient is that MOST methods called on this object that look like they are meant for one control, are actually in a loop called on all the members int he collection
When you use the [0] syntax you take the first element from the inner collection. At this point you get a DOM object
In case someone else hits this... Here's another difference:
If the id contains characters that are not supported by the HTML standard (see SO question here) then jQuery may not find it even if getElementById does.
This happened to me with an id containing "/" characters (ex: id="a/b/c"), using Chrome:
var contents = document.getElementById('a/b/c');
was able to find my element but:
var contents = $('#a/b/c');
did not.
Btw, the simple fix was to move that id to the name field. JQuery had no trouble finding the element using:
var contents = $('.myclass[name='a/b/c']);
var contents = document.getElementById('contents');
var contents = $('#contents');
The code snippets are not the same. first one returns a Element object (source).
The second one, jQuery equivalent will return a jQuery object containing a collection of either zero or one DOM element. (jQuery documentation). Internally jQuery uses document.getElementById() for efficiency.
In both the cases if more than one element found only the first element will be returned.
When checking the github project for jQuery I found following line snippets which seems to be using document.getElementById codes (https://github.com/jquery/jquery/blob/master/src/core/init.js line 68 onwards)
// HANDLE: $(#id)
} else {
elem = document.getElementById( match[2] );
Just like most people have said, the main difference is the fact that it is wrapped in a jQuery object with the jQuery call vs the raw DOM object using straight JavaScript. The jQuery object will be able to do other jQuery functions with it of course but, if you just need to do simple DOM manipulation like basic styling or basic event handling, the straight JavaScript method is always a tad bit faster than jQuery since you don't have to load in an external library of code built on JavaScript. It saves an extra step.
One other difference: getElementById returns the first match, while $('#...') returns a collection of matches - yes, the same ID can be repeated in an HTML doc.
Further, getElementId is called from the document, while $('#...') can be called from a selector. So, in the code below, document.getElementById('content') will return the entire body but $('form #content')[0] will return inside of the form.
<body id="content">
<h1>Header!</h1>
<form>
<div id="content"> My Form </div>
</form>
</body>
It might seem odd to use duplicate IDs, but if you are using something like Wordpress, a template or plugin might use the same id as you use in the content. The selectivity of jQuery could help you out there.
All the answers are old today as of 2019 you can directly access id keyed filds in javascript simply try it
<p id="mytext"></p>
<script>mytext.innerText = 'Yes that works!'</script>
Online Demo!
- https://codepen.io/frank-dspeed/pen/mdywbre
jQuery is built over JavaScript. This means that it's just javascript anyway.
document.getElementById()
The document.getElementById() method returns the element that has the ID attribute with the specified value and Returns null if no elements with the specified ID exists.An ID should be unique within a page.
Jquery $()
Calling jQuery() or $() with an id selector as its argument will return a jQuery object containing a collection of either zero or one DOM element.Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM.
All the answers above are correct. In case you want to see it in action, don't forget you have Console in a browser where you can see the actual result crystal clear :
I have an HTML :
<div id="contents"></div>
Go to console (cntrl+shift+c) and use these commands to see your result clearly
document.getElementById('contents')
>>> div#contents
$('#contents')
>>> [div#contents,
context: document,
selector: "#contents",
jquery: "1.10.1",
constructor: function,
init: function …]
As we can see, in the first case we got the tag itself (that is, strictly speaking, an HTMLDivElement object). In the latter we actually don’t have a plain object, but an array of objects. And as mentioned by other answers above, you can use the following command:
$('#contents')[0]
>>> div#contents
Here's what I'm aiming to achieve:
HTML
<fieldset id="addmore">
<p>blah</p>
<a class="remove">remove me</a>
</fieldset>
<a class="add">add more fieldsets</a>
Javascript
var addmore = new AddMore($('fieldset'));
addmore.buildCache(/*this will pull the innerHTML of the fieldset*/);
// bind the buttons
addmore.bind('add', $('a.add'));
addmore.bind('remove', $('a.remove'));
I've found myself having a lot more 'addmore' stuff in my HTML lately so I've been trying to build a class that will do all the leg work for me that I can just reuse in all my projects. The above code will, hopefully, be all I have to add each time and then the rest is done for me.
I've been winging this thing so, off the top of my head, here's what the class has to do:
Apply the jQuery bindings to the supplied 'button' objects so we can add/remove fieldsets
When a new fieldset is added, we have to recall the bind function so the new fieldset's 'a.add' button will work (I've found jQuery's .live() function to be buggy, for whatever reason, and try to avoid it)
It will hopefully do this with no memory leaks :}
Javascript Class
/*
Class to handle adding more data to the form array
Initialise the class by passing in the elements you want to add more of
Then bind 'add' and 'remove' buttons to the functions and the class will do the rest
*/
/*
Pass the jQuery object you want to 'addmore' of
Ex: var x = new AddMore($('fieldset.addmore'));
*/
function AddMore($element)
{
if (!$element || typeof($element) != 'object')
throw 'Constructor requires a jQuery object';
this.element = $element; // this is a jQuery object
this.cache = null;
}
/*
Supply clean HTML to this function and it will be cached
since the cached data will be used when 'adding more', you'll want the inputs to be emptied,
selects to have their first option selected and any other data removed you don't want readded to the page
*/
AddMore.prototype.buildCache = function(fieldset)
{
if (!fieldset)
throw 'No data supplied to cache';
this.cache = fieldset;
}
/*
use this to create the initial bindings rather than jQuery
the reason? I find .live() to be buggy. it doesn't always work. this usually means having to use a standard .bind()
and then re-bind when we add in the new set
that's what this class helps with. when it adds in the new data, it rebinds for you. nice and easy.
*/
AddMore.prototype.bind = function(type, $button)
{
if (!type || !$button && (type != 'add' && type != 'remove'))
throw 'Invalid paramaters';
// don't reapply the bindings to old elements...
if ($button.hasClass('addmore-binded'))
return;
// jQuery overwrites 'this' within it's scope
var _this = this;
if (type == 'add')
{
$button.bind('click', function()
{
_this.element.after(_this.cache);
});
}
}
I was going to have the .bind() method (in my class) call itself upon adding the new fieldset to reapply the binding but lost confidence with efficiency (speed/memory).
How should I tackle this? Do you have any pointers? Can you recommend improvements?
Thanks for the help.
In the most simplest form, you can do something like this:
var html = '{put html to add each time here}';
$('.add').click(function() {
$(html).insertAfter($('fieldset').last());
return false;
});
$('.remove').live('click', function() {
$(this).parent().remove();
return false;
});
You may need to tweak it based on your exact needs, but this should accomplish what you described in your example.
Update: sorry, remove should use the live method.
For creation of the new DOM elements, allow the specification/parameters to be any of the following:
simple HTML as a string (like the example above),
a function returning either a DOM element or HTML text. You can skip bind() or live() issues by adding
the onclick element when creating the HTML/element in the function. Although doing it in the AddMore() scope would be more tedious
if it's not a DOM element that gets returned.
inputs to a helper/factory method (maybe a template and name/value pairs) - postpone this unless you know enough patterns already.
Option #1 seems almost useless, but #3 might be hard unless you have extra time now.
Notes:
You might want to use $(theNewDomElement).insertBefore(_this.button); rather than _this.element.after(theNewDomElement); so that new items are append to the end of the list.
Actually, for insertBefore() you might just use this rather than _this.button since presumably the button (or anchor) is this, but then that limits the functionality - just make it some sort of DOM element (or a jQuery object that equates to one).
In most cases, I'd presume your DOM elements represent data that you'll want to save/send/transmit to your server, so provide a before-removal function, too. Even allow the function to skip removal -- like after a confirm().
Good luck.