Break On Attribute Change
13 June 2016
Today I discovered a neat feature available in both Firefox and Chrome: break on attribute change. This allows us to break when some code changes a DOM element attribute.
I was debugging an issue where some code involved with adding and removing styles for error indication on a table was incorrectly doing the following:
$("td").each(function() { if (!$(this).hasClass("qc-error")) { $(this.parentNode).attr("style", ""); } else { $(this.parentNode).attr("style", "border: 1px solid #f00; background: #eee"); } });
The templating code was responsible for the initial hiding of the row and would insert this style when rendered:
<tr id="second-fee-row" ${'style="display: none"' if bid.fee_type != constants.FEE_TYPE_PER else '' | n}>
Additionally, some code elsewhere on the page was also attempting to manage this row by setting the display in response to changes in a dropdown:
if ($("#fee-type").val() !== constants.FEE_TYPE_PER) { $("#second-fee-row").css("display", "none"); } else { $("#second-fee-row").css("display", "table-row"); }
After first verifying that Firefox thought it should display the element, I
looked at the page source. Checked out. display: none
was definitely
there.
Then I spent some time looking for modifications to #second-fee-row
. I
inspected all the sites that were modifying that row (by looking for that id).
Nope. Nothing setting the style to empty.
After a quick google to confirm that display: none
hadn't suddenly become
unsupported, I came across this Stack Overflow link:
https://stackoverflow.com/questions/13303650/break-when-style-has-changed-in-chrome-dev-tools.
This in turn led me to search for the same feature in Firefox (my day-to-day
browser) which resulted in: https://getfirebug.com/doc/breakpoints/demo.html.
I went ahead and set such a breakpoint on the afflicted element. Lo and behold, the offending code was found and repaired with:
$("td").each(function() { if (!$(this).hasClass("qc-error")) { $(this.parentNode).css({ border: null, background: null }); } else { $(this.parentNode).css({ border: "1px solid #f00", background: "#eee" }); } });
Not a perfect solution (should probably track the original value instead) but acceptable in this case.