Can't get access elements with querySelector? - javascript

I wish to access elements in a site with javascript and I have been using javascript for quite some time, especially with the querySelector functions. But for some reason, it won't work in this case; whenever I try to access any of the top-level elements, as illustrated below, no elements are found.
Does anyone have an idea about what the problem could be, and maybe even how to fix it?

That's normal,
It's because when you use the chrome developer console you can change the document context and in your screen you are inside the iframe.
You can see it here:

Related

Scope of inline JavaScript vs script element [duplicate]

It is common for me to register javascript functions for certain events by doing something like:
myBtn.Attributes.Add("onClick", "Validate(getElementById('"+txtFirstName.ClientID + "'));");
I've always used getElementById by itself, or in other words, sans document being prepended to it. But I'm having pages break on me lately when I try to use getElementById instead of document.getElementById. Why is this? Oddly, I have a website where one page allows me to use just getElementById, but another other page throws a javascript error because it can't find the element if I do just getElementById, and it'll only work if I do document.getElementById.
Anyone know why this is? Should I be using document.getElementById everywhere, regardless of whether it works without the document prefix?
EDIT:
Could it have anything to do with the fact that one page is using AJAX and the other isn't?
When you use getElementById() and it works that mean that the function where it's called is running on the context of the document, that's is this == document.
So, you should ALWAYS use document.getElementById to avoid that kind of errors.
Anyway, I would even stop using getElementById altogether and start using JQuery, i'm sure you'll never regret it.
Your code would look something like this if you used JQuery:
$("#myBtnID").click(function () { Validate($("#myTextboxID"))});
Any function or variable you access without an owning object (ex: document.getElementById) will access the property from window.
So getElementById is actually window.getElementById, which isn't natively defined (unless you defined it before (ex: getElementById = document.getElementById).
You should use the full document.getElementById(). If you find that too verbose, you could use jQuery:
$('#' + id)
or you could create an alias at the top of your script:
var byID = document.getElementById;
You should only use document.getElementById (even if I'd recommend using libraries like prototype or jquery to be able to use the $ sign).
If you are able to use getElementById on its own, it's just because the browser you're using is doing some kind of trick to get it to work, but the correct way is to use the document variable.
I dont really know how to explain it but its because the getElementById() finds an element in the html structure of a page. Some browsers know that by default you want to search the document, but other browsers need that extra guidance hence document.
The correct way is indeed document.getElementById().
The reason (speculation) it might work by itself is that depending on where you use it the current context may in fact be the document object, thus inexplicitly resulting in document.getElementById().

Why $('div#my') is returning Object Reference instead of HTML Tag? [duplicate]

This question already has an answer here:
Why sometimes jQuery selector returns something like "a.fn.init"? [closed]
(1 answer)
Closed 6 years ago.
I don't know what happen to my Chrome browser, but all of sudden the behavior of doing $('div#my') in console is totally different from before. One time I've experienced this but later it somehow recovered, so I don't know how to reproduce it, and today it happened again.
Please watch the video:http://peaceevertvimg.org/jq.php.
In the video I do $('div#my') in two different browsers:
the first browser is not chrome but I believe it imitates Chrome so its behavior is what I expect and what I have almost always been experienced. Because currently my chrome is not working as expected so I have to use it to demonstrate my expection: when you do $('div#my)` you see directly the html TAG, and you can easily see the tag's html content, which is "something" in this case.
In contrast, in my chrome browser, the result is different, when I do $('div#my') I see an Object(n.fn.init), and I can't see the "something" immediately, which of course is very inconvenient. But before, I am pretty sure it was not like this, the behavior WAS exactly like that in the first browser.
The simple webpage in this video is http://peaceevertvimg.org/jquery.php, you can go test for yourself in chrome browser. And I am pretty sure most of you will see the first behavior. What happened to my chrome?(I've disabled all expansions and updated it to the latest version)
By the way, is "HTML Tag" and "Object Reference" the right words to describe these two different outcome?
*************Update*************
If the video is not sufficient to understand what I ask and what I want to fix, these two pictures may help.
Picture#1: This is the "normal" behavior I've expected:
Picture#2: This is the current behavior I am experiencing:
You can see the big differences, the first one is much more intuitive, revealing key information immediately, while the 2nd one is not, at least to me. What causes this problem and how do I go back to the first one?
$('div#my') doesn't return a DOM reference. It returns a jQuery wrapper around the found elements.
$('div#my')[0] would return a DOM reference. Or, forget jQuery and use:
document.getElementById("my");
...and you will get a DOM reference directly
Also, since there should/will only ever be one element with a given ID, it is unnecessary to use div#my, just use #my.
Assuming we have a <div id=someDiv>, and then we write:
console.log($("#someDiv"));
console.log($("#someDiv")[0]);
Chrome shows this:
In the first log, we see that the result is a jQuery object that contains one element (the div). In the second, we see the element directly.
Now, depending on what version of Chrome you have, you may see the first one reported simply as [Object object], but that doesn't change the underlying result.
From: Devx (http://www.devx.com/codemag/Article/40923)
Selectors let you select DOM elements so that you can apply
functionality to them with jQuery's operational methods. jQuery uses a
CSS 3.0 syntax (plus some extensions) to select single or multiple
elements in a document. You're probably already familiar with the CSS
syntax from HTML styling. Even if you're not, it's fairly easy to pick
up the key CSS selector features. I'll go as far as saying that jQuery
is the reason I really started to grok CSS. Using CSS syntax you can
select elements by ID, CSS class, attribute filters, or by their
relationship to other elements. You can even chain filter conditions
together. Look at this simple example, which selects all second-column
TD elements in a table using a simple selector: $("#gdEntries
td:nth-child(2)").
The jQuery Object: The Wrapped Set: Selectors return a jQuery object
known as the "wrapped set," which is an array-like structure that
contains all the selected DOM elements. You can iterate over the
wrapped set like an array or access individual elements via the
indexer ($(sel)[0] for example). More importantly, you can also apply
jQuery functions against all the selected elements. - See more at:
http://www.devx.com/codemag/Article/40923#sthash.l8Mo8CbH.dpuf
What you are seeing is said jQuery object returned by jQuery.fn.init().
What is going on is that jQuery() is being defined as jQuery.fn.init() which is another way to say jQuery.prototype.init() which is the selector function! What this means is that no one would call jQuery.fn.init() or jQuery.init() because jQuery() IS .init().
Some more info and a look at the jQuery code here: Help understanding jQuery's jQuery.fn.init Why is init in fn
As for a solution to your problem: https://chrome.google.com/webstore/detail/jquery-console-fix/jlmkkpkcgomkdpfhgjlpaaonhafnjgob?hl=en

Content Scripts: Page-worker - <body> element with 0 width

I want to automatically open a website and reveal details about the rendered DOM. For that purpose I use a page-worker (https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/page-worker). When in the content script I execute something like the following:
var body = document.getElementsByTagName("body")[0];
console.log(getComputedStyle(body).width);
console.log(body.getBoundingClientRect().width);
The output is "0" for both of the width values. The same also applies to other elements. Should I conclude that DOM elements are not rendered properly when using a page-worker? Is there a way to gain authentic data from that? Or is there any other proper way to get details about the rendered DOM that behave exactly like the website was opened in a web browser by hand? Because if I open the same website manually and execute the same commands, it reveals (correctly) the width of the window (1440), of course.
edit
I probably should have said that before, but:
It's not that gaining the values does not work at all. If I go deeper in the DOM structure, I get correct values. I only have problems with the root body element, I think. Weirdly enough if I execute the exact same commands on the firefox console, the return values are perfectly correct.
It's very interesting the way you do it.
You don't have to do getElementsByTagName to get the body element, its a property of the document object var body = document.body;
getComputedStyle is a function of the window object so that's why it works without you putting window. in front of it but still just want to let you know.
You dont do a getPropertyValue which is required for getComputedStyle, I just tried it without it and it worked but i never saw it used like that before so maybe that has something to do with it:
So doing this from bootstrap or from scratchpad window: gBrowser.contentWindow.getComputedStyle(gBrowser.contentDocument.body).getPropertyValue('width')
works for me.
From your content-script scope do:
window.getComputedStyle(document.body).getPropertyValue('width')
If it still doesn't work I would thinky maybe myabe maybe, thers a chance you might be executing the code to early.
Let me know how that works.

How is this element accessible when not found with selector

In my company, some of the code accesses html elements purely by id, rather than document.getElementById or jQuery $("#id"). For example, if there is a select with an id of test they then use alert(test.selectedIndex) in the javascript and this works.
This breaks my model of how elements can be found / accessed in the DOM and I would have expected the alert to say that test was undefined. However, this works (and I have set up a fiddle to double check this). Can anyone please explain why elements can be accessed by their id, without any need for a getElementById / jQuery selector?
Many thanks.
See http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object (noting that 'globals' in javascript are just looked up from properties on the window object, so window[id] is exactly the same as just id, if id is not defined as a local variable)
This was previously non-standard behaviour, added by IE, that has now become part of the HTML5 spec.
In general I wouldn't recommend relying on it though because, as you've noticed, it can be quite confusing.

How to find the snippet of JavaScript that modifies an element?

The page I'm trying inspect has a hidden <input type="hidden" name="Foo" value="123 /> element on a page, where Javascript/AJAX modifies the value. I'm trying to find where on earth in Javascript is the code that modifies this value from time to time.
Is there a tool that could help me find the places in javascript that use/modify that element? Does Firebug provide this, if so, how?
Note: If tried looking for "Foo" in the code, but I haven't found any matching titles. There's JSON and Mootools loaded, +application specific code, which results several thousands lines of code. The element is probably accessed indirectly.
Firebug 1.5 will have "Break-on-Modify" on the HTML panel. See http://getfirebug.com/doc/breakpoints/demo.html#html - Break on DOM (HTML) Mutation Events.
How do you know that the javascript is modifying this value? Since it looks you already know when it's called (since you know it changes), I would suggest a breakpoint in Firebug in the first event that initiates the changing (probably an onclick attribute in other element).
It's kind of hard telling you a "generic" way of knowing where in javascript it's changing Foo's value since there are a lot of different approachs, different libraries, each one with it's syntax.
For example, if you tried searching "Foo" and didn't find it, the script may be traversing the DOM and changing the input's value as a "first child of something". I would try to search for names or ids of input's parent elements and understand the code from there.
I usually just try to understand the javascript logic from every script I use with Firebug's debugging techniques - but just on the script that uses the libraries.
If Firebug doesn't let you define breakpoints on setting some value, you could insert something like this in the page (Firefox-only):
$("textarea")[0].__defineSetter__("value", function(val) {
alert("called");
})
And either breakpoint on the function in Firebug or use console.log or whatever to dump the stack to the firebug console.
I remember seeing somewhere a presentation on Firebug plans, which included a section on various kinds of breakpoints to be supported, but I can't find a link to it right now.
[edit] The above is for the case the value is set by assigning to the value property: .value = .... If you need to catch the moment an attribute is changed (.setAttribute("value", ...)), you can use DOM mutation listeners.

Categories

Resources