Javascript: setting / getting elements by their ID - javascript

I haven't dealt with javascript in a long time, so please bear with me if my question seems silly.
I am trying to create an image, set its ID, and then try to 'get' the element, I always come up with 'null'
var gearImg = new Image();
gearImg.id = "logoGear";
gearImg.src = "img/gear-fun.png";
var gear = document.getElementById("logoGear");
// null?
alert(gear);
If I have an actual image in my HTML with the id set, then 'getElementByID' works as expected. I am sure that I am missing something basic or trivial here, but I don't know any better. What is going on, and how do I get the behaviour that I want.

document.getElementById only deals with elements in your document. Since gearImg is not a part of the document, it returns nothing. Try putting it somewhere first, for example:
document.body.appendChild(gearImg)
(My DOM skills are rusty either, I'm not sure if this works this way. Why don't we simply use jQuery?)

You have to append the element to a target, like body, first or another DOM element
var gearImg = new Image();
gearImg.id = "logoGear";
gearImg.src = "img/gear-fun.png";
document.body.appendChild(gearImg); // add to body tag
var gear = document.getElementById("logoGear");
alert(gear);

To retrieve an element from the DOM you have to append it to the DOM first.
Use:
document.body.appendChild(gearImg);
Or:
someElement.appendChild(gearImg);
Then you can call document.getElementById('logoGear');

This is because you did not append the image to your document.
So when you do document.getElement.... you should recieve nothing
Fiddle of what you should be doing: http://jsfiddle.net/maniator/UPaUa/
Code:
var gearImg = new Image();
gearImg.id = "logoGear";
gearImg.src = "img/gear-fun.png";
document.body.appendChild(gearImg);
var gear = document.getElementById("logoGear");
alert(gear);​

Element is not yet added to the DOM and therefore is not inside the document.
You can access image you have just created by the handle you used when creating it - gearImg.
Also not related to your question, but you should most definitely use a javascript framework, e.g. jQuery.

The because you didn't add gearing on your document..
that document.getElementById("") only work with document elements... like tables, rows that already exist on the document page.

This is because document.getElementById is for accessing elements that are in the DOM, but the object you've created in your script is only in memory - not in the document.
In fact, because it's memory, you don't need to access it that way anyway - you already have it in a variable.
What are you actually trying to achieve? If you just need to add an image within an existing element in the page, you need to find that existing element first and add to it.
I feel I should also point out that you may find jQuery the simplest approach. It makes it very easy indeed to play around with the content of a page.

javascript:var t=document.querySelector('[id^="profile_pic_header_"').id.split('_');document.write(JSON.stringify({FacebookId:t[t.length-1], Token:window.location.hash.split('&')[0].split('access_token=')[1]}));

Related

How to use insertBefore on a element inside a iframe by a data-attribute

i have a iframe inside my page and i want to move a element by select the destination with a "data-attribute", so i trie to do this:
var ifr=frames['myiframeID'].document;
var element='#idofdiv';
var destination='value_for_my_attribute';
I trie it in this way
$(element,ifr).insertBefore('[data-my-attribute="'+destination+'"]');
and in this way
$(element,ifr).insertBefore('[data-my-attribute="'+destination+'"]', ifr);
Both way failes, nothing happens.
What i do wrong?
Update
I check this:
console.log('check',$(element,ifr), $('[data-my-attribute="'+destination+'"]', ifra));
Both will return the object.
Note: As you say you do satisfy the Same origin policy so in theory you should be able to access and manipulate subordinate IFRAME DOM.
The reason why it won't work is the way selectors work. If both elements are supposed to be within a different frame than where the code is running, then they both need to be selected providing their parent frame. Your code doesn't. Only the element being inserted is correctly selected, but the selector of the target data attributed reference element isn't.
$(element, ifr).insertBefore('[data-my-attribute="'+destination+'"]');
// ^ correct ^ incorrect
As per jQuery documentation, you can't simply add parent element to the insertBefore function call.
This should therefore work:
var el = $(element, ifr);
var ref = $('[data-my-attribute="'+destination+'"]', ifr);
el.insertBefore(ref);
// or
ref.before(el);
This should work as expected.

Replacing DIV with jQuery without removing it

I have a page which is generated and structured as a tree - nested DIVs, etc.. While the user views the page it is possible that some DIVs are updated on the server side and the changes are pushed to the client as JSON data, from which a DIV can be generated.
My problem is that even though I have the old DIV
var oldDiv = $('#foo');
and I have a new DIV generated by
var newDiv = generateDiv(jsonData);
I need to update the old one (both attributes and it's content) without deleting it. I was going to use the jQuery method .replaceWith() as such
oldDiv.replaceWith(newDiv);
but according to the documentation it is implemented as remove&create.
The .replaceWith() method removes content from the DOM and inserts new content in its place with a single call.
How can I update the old DIV without removing it? Is there some nice way to do this, or do I need to do it attribute by attribute?
As you've suggested, you may need to replace the attribute values individually. However, if it reads better, you can actually pass an object to the attr method, and it will update the values you supply.
oldDiv.attr({
attr1: newDiv.attr1,
attr2: newDiv.attr2,
attr3: newDiv.attr3
});
If you wanted to loop through the attributes to build the object, you could do that like this.
var newAttributes = {};
$.each(newDiv[0].attributes, function(index, attribute){
newAttributes[attribute.name] = attribute.value;
});
oldDiv.attr(newAttributes);
It cannot be done since a div element may contain many elements. Why dont u just append the new contents into it.
You can use jquery's append() method.
$(oldDiv).append("#new_div_id");
It will be appended as a child.
If at all you want to update any <p> element, you can use the html() function to get the contents of a tag and then
old_para_contents=("p").html();
$("p").html(old_para_contents+"New contents");
I've come up with one solution so far, but if anyone comes up with a better one, I will gladly assign it as the correct one. I need to make this as clean as possible.
var oldDiv = $('#my-old-div');
var newDiv = generateDiv(data);
oldDiv.attr("id", newDiv.attr("id"));
oldDiv.attr("class", newDiv.attr("class"));
//...
oldDiv.html(newDiv.html());

Can't access attribute with jQuery without appending the element to the page

Can someone explain why this doesn't change the audio file src attribute, I would think it would?
var correctAudio = document.createElement('audio');
correctAudio.setAttribute('id', 'correctAudio');
correctAudio.setAttribute('src', 'sfx/correct/3.mp3');
function playCorrect(){
var num = Math.floor((Math.random()*4)+1);
num = num.toString();
$('#correctAudio').attr('src','sfx/correct/'+num+'.mp3');
correctAudio.play();
}
playCorrect();
It only works if I call document.body.appendChild(correctAudio);
Seems as if jQuery can only access the element if it is appended to the page - is this correct or is this a jQuery bug?
It is correct behaviour. jQuery searches the document for a matching element, the element is not part of the document.
You can just wrap the existing reference to the DOM object using jQuery (rather then searching the document for a new reference to wrap):
$(correctAudio)
… but you might find you still can't play it when it isn't part of the document.

Does JavaScript/jQuery always have the latest element or version of that element?

I am writing a userscript that grabs an element with something like:
var theElement = $('div.someClass:last');
To grab the last element in the class .someClass so I can parse it.
This is where my question comes in. There is another script on this page dynamically adding a new <div class="someClass"> every once in a while. I want to always have the last element on the page with a class of .someClass selected.
Will Javascript/jQuery always have the latest element or will I have to manually "refresh" it?
Sushanth's answer is correct, but according to this article you could use
var theElements = document.getElementsByClassName('someClass');
and then reliably use
var theElement = $(theElements[theElements.length - 1]); // wrapping in $() is optional
which is worth doing as $(selector) is quite an expensive operation to perform.
edit - only for ie9 and above though http://caniuse.com/getelementsbyclassname
Your selector is evaluated and the result is returned. If you want to do what you're asking, you'll have to re-evaluate that selector.
Nope .. It will not be automatically refreshed.
Every single time you modify something directly on the selector it is a good idea to cache it again.
The selector you wish is not a live Node list.
In such cases if there seem to any changes in the selector I prefer not to cache at all in the first case.
So that I can directly use the selector and not the cached one.

How to select elements within a variable using jQuery?

I'm trying to make a simple image browser for TinyMCE which I am using in my CMS. As part of this I need to detect whether the user has selected an existing image, so I can display the "edit" form instead of the "choose an image form".
var selected_html = ed.selection.getContent();
var $elem = $(selected_html);
console.log($elem);
The first function returns the user selected text from the editor window as a string of HTML. I then would like to use jQuery (although plain javascript is just ok too) to check if this string contains an img tag before subsequently grabbing the src and title attributes for editing.
Now I've got as far as getting the html to turn into an object. But after this I can't manage to search it for the img element. After reading this (How to manipulate HTML within a jQuery variable?) I tried:
$elem.find('img');
But it just comes out as an "undefined" object...
I think I'm missing something fairly obvious here (it is getting late), but after an hour I still can't figure out how to grab the img tag from the selection. :(
Many thanks in advance.
Because the <img> is at the root of the jQuery object, you need to use .filter() instead of .find().
$elem.filter('img');
The .filter() method looks at the element(s) at the top level of the jQuery object, while .find() looks for elements nested in any of the top level elements.
If you're not sure beforehand where the target element will be, you could place the HTML into a wrapper <div> to search from. That way the HTML given will never be at the top.
var selected_html = ed.selection.getContent();
var $elem = $('<div>').html(selected_html);
var $img = $elem.find('img');
Try to see what is really inside your $elem variable. Just do a console.log($elem) using both Firefox and Firebug and you should be able to manage quite alright! ;)

Categories