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

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.

Related

Inspecting console.log variables in Chrome

As a thought, i would like to know if is possible to inspect for log properties of any variable in the chrome or any other browsers within the console mode. As i already know that you can already inspect the DOM in inspector element and you can go through debugging mode also. I want to demonstrate my point and why i and most novice would benefit this.
So as you can see in the picture below:
So as you can see i am trying to access some element of Array[15] but in the end it always giving me undefined. It nice just to test out some code before recompiling it again which takes time. Plus sometime you don't always knows enough that the function you are calling in JS is compatible with what you trying to achieve.
Put your entire code inside:
$(document).ready (function (){
//Paste your code here
});
The whole point is you are trying to access an element in the DOM before it exists.
When your trying to access the class the item doesnot exist.
Alternative:
Move your script below the elements in the html.
This is a very generic solution I gave without seeing the code. Request you to post the code as well.
Hope it helps.
You need to add a debugger where you are outputting your array. It seems to me you are trying to access the variable after execution is over, so the variable value is lost, as it goes out of scope. When execution stops at the debugger, you can console.log your variable and properties. At that point the variable will be in scope.

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

jQuery and selectors: how can I make sure that there really is the element I'm looking for?

I'm no experienced JavaScript developer (I know quite a lot about Ruby, though), and so far, when I had to implement some lines of JS, it seemed enough to use jQuery and hack together something.
As far as I understand jQuery, it doesn't assume HTML elements to really be there, but it simply executes a query, and if there is a matching element (or many), some stuff is done with it. This works well for generic code which may want to apply some action to some elements on a page (which may be there or not), but when it comes to specific logic, it's a problem.
What do I mean with this? Let me give an example.
Let's suppose I have one single page with one single HTML element (with the ID '#my_element'). For exactly this page I have to run some JS code, and I have to be sure that it finds this element and does the things to it that I want.
Doing this with jQuery, I simply do something like $('#my_element').addTooltip(), which seems fine first: when I hover over the element, a tooltip is displayed.
Let's assume that some months later I already have completely forgotten about this JS script, and I change the ID of the element to something else. What happens? Nothing. I won't notice the problem with the missing tooltip until I stumble over it by accident.
So I wonder how I can make sure that my JS is really applied, which means: the required elements are found, the stuff is done to them, etc.
Is jQuery's philosophy the "wrong" tool for this? Do I need another framework? Maybe something more sophisticated pattern, e.g. something like MVC? I played with KnockoutJS before, and it seems that this may be better for this, as it's bound directly to elements using data-bind attributes, so it fits tighter on the code than jQuery does.
The comments mentioned always checking the .length property before performing actions on returned results (which is probably the best answer,) but in the case of an actual syntax error your statement that "nothing happens" isn't always true.
If you're using Chrome developer tools or a similar tool in another browser (firebug, etc.) you should see the error in the "Console"
You can also turn on javascript debugging for more information. When you call the "addTooltip()" on something which is null (the jQuery collection) you'll see an error pop up in the Console and may get an exception in the debugger.
This is one of the easiest ways to find errors in your client-side javascript.
You could add a specific plugin to verify the existence of a non-zero- length collection, and use that in the chain:
(function ($) {
$.fn.verify = function() {
if (this.length) {
return this;
}
else {
console.log("No elements found with supplied selector.")
}
}
})(jQuery);
$("#myElement").verify().addTooltip();
This does, of course, rely on the verify() plugin being manually applied, there is – to the best of my knowledge – no error-reporting built in to jQuery to automatically enable logging of invalid selectors, or reporting of selectors returning zero elements.

How does one figure out what piece of JavaScript changes a given HTML tag?

I often want to change some releatively minor detail about how JS changes the DOM, but I can never figure out which function in what script changes a given tag. How does one do this?
For example, on this page, I want whatever JS is adding the "selected" class to various a tags to also add it to the enclosing li tags. However, I have no idea how to figure out where this is taking place.
Clarification: As much as I'd like an answer to my current, specific conundrum, I'd much rather be taught how to figure it out myself.
CLARIFICATION:Is there a way to point at a certain object in the DOM and find out what script(s) are/were accessing/modifying that object? In other words "watch" that object for JS access/modification.
What you need is DOM breakpoints in WebKit's Developer Tools.
They're designed for tracking DOM mutation events - such as change of an attribute of an element (which is your case), element removal, or addition of subelement. You can refer to tutorial in DevTools documentation.
In basic cases you might want to use grep for searching the strings such as "selected" in your code.
I’m not aware of any debugging tools that’ll tell you when a DOM element is being acted upon by a script.
(If anyone knows of any, dear lord please tell me about them — I’m a freelancer, so I spend most of my working days trying to figure out old, knotty DOM-manipulating JavaScript that someone else wrote.)
You basically have to search through every bit of JavaScript file included in the page, and identify lines that might be taking the action you’re seeing.
In the case of a class name being added to an element, an obvious search is for the class name itself, although that’s not guaranteed to work. E.g.
el.className = el.className + 'sel' + 'elected'
If jQuery is in use, I’d definitely search for addClass.
Once you think you’ve found the right line, then if you have access to the JavaScript code, you can change it and see if your change takes effect.
(And, because view source is still a part of the web, you can get access to the code by saving it all to your computer.)

__defineSetter__ on innerHTML stops it from rendering

i'm trying to create a watch method for HTML elements, using __define[GS]etter__ when a property is changed. It reacts just fine when i set the value, but if the property listened to, is innerHTML, it somehow fails to render the given string. So basically, when im adding something to innerHTML it doesn't show.
Im using the watch method described in this previous question:
Watch for object properties changes in JavaScript
I could of cause just not listen to innerHTML changes, but i'm also wondering if the __defineSetter__ somehow prevents original handling of setting the value.
Thanks!
That shim code doesn't actually write-through: when you set a property, the value is only remembered on the watch-wrapper and not passed down to the underlying object. It's designed for pure JavaScript objects whose properties have no side-effects (like changing the DOM, in innerHTML's case).
Making it write-through would be a pain since there's no way to directly call the prototype's setter. You'd have to temporarily remove the property, write to the underlying property, then put it back in place.
However it's not really worth pursuing IMO. DOM Nodes are permitted to be ‘host objects’, so there is no guarantee any of the native-JavaScript object-property functions will work on them at all.
(In any case, adding new members onto the Object prototype is generally considered a Really Bad Idea.)
I could of cause just not listen to innerHTML changes
I think that's best, yes.
Ok update.
I found this page on MSDN, which has exactly what i need:
http://msdn.microsoft.com/en-us/library/dd229916(VS.85).aspx
But the Object.getOwnPropertyDescriptor way of doing things apparently only works in IE. Bummer. Any ideas would be appreciated.
I found another webpage with something that looked interesting, but i couldn't quite get it to do what i wanted:
http://www.refactory.org/s/recent/tag/accessors
I've decided to find a workaround for now, something with a timer that checks the attribute for changes and attribute change evnets for browsers that support that.
But if any one finds a solution for the question plz post :)

Categories

Resources