How do I see what javascript modifies a particular bit of HTML? - javascript

When I load a page, there is a style attribute that has been added to the <body> tag that is not there in my templates. How do I discover what javascript has modified it?
Just to be clear, the body tag is now:
<body class="home page" style="margin-top: -43px;">
So the style is not coming from a style sheet. While the template does not include the "style=" bit at all. So I'm pretty sure that some running javascript is modifying the body tag.
I have both Firefox/Firebug and Chrome Inspector available to me. I have tried right clicking on the body tag in "HTML"/"Elements" view and choosing "break on attributes modification" but the change has happened by the time I can do that, and the break point does not survive a page reload.
I'm using Django and jQuery in case that alters the answer.

I currently use an extension of Firebug called FireDiff you can file its homepage here: http://www.incaseofstairs.com/firediff/

You could use mutation observers.
Try adding this code as the first thing that gets executed on page load:
var target = document.querySelector('body'),
observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
debugger;
});
});
  
observer.observe(target, { attributes: true });
As a side note, it'd be great if that particular kind of breakpoints survived page reload.

There is the possibility it is added server side too. If you search your source files for the stylesheet name it should appear in either a JavaScript or a Python file. i.e. grep for "mystylefile.css"
You could disable JavaScript and see if it is still added if you want to narrow it down.
Update
Finding what added the margin-top to the element will be harder! You could search your JavaScript files for "margin-top" and see how many results you get back - or add the JavaScript files one by one until one causes it to be added.

Related

highlight.js: CSS styling absent after setting innerHTML

I am using highlight.js for syntax highlighting in a webpage.
When I change the content by setting the relevant innerHTML using JavaScript, the content output on the page updates as expected. However the changed content is not highlighted in the browser.
What is the correct way to deal with this situation, generally or with highlight.js using only JavaScript, HTML and CSS?
I found a solution thanks to #Afsar's insightful comment.
The function initHighlighting from highlight.js:
initHighlighting()
Applies highlighting to all <pre><code>...</code></pre> blocks on a page.
... contains an internal check to see whether it has already been run. Since I was attempting to run it more than once, highlighting was not working correctly.
So one possible solution to updating highlighting after updating content via JavaScript with no page reload is:
var element = document.querySelector(".class_that_contains_code_blocks");
var blocks = element.querySelectorAll('pre code');
blocks.forEach(hljs.highlightBlock);

JavaScript does not work well inside a loaded content in a DIV

I am creating an application with Symfony2, where I have a main menu of options depending on the option selected dynamically opens a tab at a lower div with the content for that option. Content is loaded with load() of Jquery in the container div.You can see in the picture below:
The first problem was that in the HTML loaded in each tab could not use the js file initially loaded in the index.html, as you can see in this example you should check out a notice when we click the content of each tab, but does nothing .
The solution to this problem was included in each HTML code to load the appropriate script, and it worked properly. But to do it this way, if two HTML carry the same js, when one of the contents some event runs is repetite many times as tabs we have created, that is, if I open two different options (each in its own tab both charge the same js) by clicking on the first event associated performed twice, whereas if I do it in the second only done once. In short, whenever a function of a js used, is repeated as many times as there are dynamically loaded on the tabs.
And I tried event.preventDefault();orevent.stopPropagation(); and it does not solve the problem.
Would it be okay that it js is included twice in the overall structure of HTML? (Included in the initial head and then the container div)
Dynamically loading HTML + JavaScript is not the best approach for this case. I suggest that you use some JavaScript SPA framework, like AngularJS or ReactJS. Both are very big and well supported projects, so you can find tons of documentation and tutorials. You'll most likely end up using Symfony only as a RESTful service and Angular/React taking care of the rest (template loading, sending request to server, etc). Also, js frameworks will take care of deep linking and in the end you'll have a better working, easier to maintain application.
It is a bit more work initially, especially until you bootstrap the application, but then it gets easier to maintain and implement new functionality, so it pays off in the end. With your current approach you soon will find yourself in a big mess full of 100s of templates, js callbacks, inclusions, etc. I'm saying this from a personal experience!
Well...
Jquery works like this: when you attach an event to html, if the html does not exist, the event is attached to nothing. If the element exists then the event is correctly attached. It attaches only to existing elements when the on function is execute. That is a correct behaviour. In the past it used to exist a .live method that did exactly what you want: you attached an event and if you create the element after the attachment, the new element also contained the event.
Adding the js twice is not the solution. As you said after a click the button will be executed twice.
Why do not attach the events after loading the content? If you load it in the page start you can do in the main file:
$(function(){ // will force to execute the on method after all the page is loaded.
$('.submenu .button').on ('click', function (){
...
});
});
If you load the menu by ajax, in the callback and after adding the html menu to the main you must use the code I wrote above.

How to override html property created by script (mediaelement.js)

for some reason when using mediaelement.js, it creates a div for the progress bar called "mejs-time-rail", but then proceeds to set the html width value to "0" through an inline style.
Since this div is created when the script runs, I cannot edit this property in the source code, but if I edit it (the inline style) in Firefox's inspector, I get the desired result. Also, it seems that this html property created by mediaelement.js overrides any css rules I set.
Any ideas how to circumvent this issue? Maybe editing the actual js script?
Thanks
I can't post a picture because I don't have enough reputation, but I can update this post with a screenshot when I do have enough and/or if it helps
First, it seems the issue is that as the DOM loads, the external script is setting that desired value to 0 like you said. Try adding a custom JavaScript/jQuery file that simply runs after the DOM is completed and
.find the element you want to edit. Then try
.attr('desiredAttr', 'new val');
this should find, and then reset the attribute to whatever you like. Even if the external script changed it on load.

Inserting HTML comments onto page using Javascript

I have a Javascript function that is supposed to insert a string formatted in a certain fashion onto a page for a data analytics tool used by another team. The Javascript executes without error, but whenever I look at the page source of the page, it appears that the comment is not present on the page. Does anyone have any ideas what the issue could be? Has anyone had any experience with writing comments onto the page? I thought maybe jQuery was having any issue with writing HTML comments, but it turns out that using just plan Javascript DOM manipulation functionality doesn't work either.
var test_comment = "<!--This is my comment for data analytics-->";
renderTealeafGrid: function(analyticsString) {
var homePage,
analyticsInfo;
if($('.analyticsInfo').length===0) {
homePage = document.getElementById('homePage');
analyticsInfo = document.createElement('span');
analyticsInfo.setAttribute('class','analyticsInfo');
analyticsInfo.innerHTML = analyticsString;
homePage.appendChild(analyticsInfo);
}
}
renderTealeafGridUsingJQuery: function(analyticsString) {
if($('.analyticsInfo').length===0) {
$('#homePage').after('<span class="analyticsInfo hide">' + analyticsString + '</span>');
}
}
None of the logic that you presented does anything with the test_comment variable.
As others have noted, simply View Source will display the original source code of the page, not any DOM changes after the page has been loaded. You will need to Inspect the source using Firebug or Chrome Dev Tools.
Also, if you want to properly add a comment to the DOM, you would use the document.createComment() method.
// Assuming you are simply viewing source of the page.
Your problem is, jQuery manipulates DOM after it had been built.
And DOM is built based on the source of the page which is what you are seeing through 'view source'.
To view the modified source, either inspect element or use firebug like tool.
You can also get the source through jQuery. Try alerting a .html() of the element you are updating.
If you use the old-fashioned view source tool, you will probably see the original source. You can verify the changes in FF by using the Inspect Element array of tools. They show the current DOM, after updates.

I can't get the toggle control with document.GetElementByID() in the windows8 setting charm

I'm very new to javascript, so this is confusing me. All of the settings charm tutorials only show how to put the controls into the settings charm, but none of them say how to find the information gotten in them.
I tried to do one of these (like I do in the main program):
var muteToggle = document.GetElementById("Mute");
where "Mute" is the id in the separate html file.
muteToggle just ends up being null all of the time. I tried putting it after
WinJS.UI.ProcessAll().then(function completed() {...
but that didn't work either. Everything else is the same as in this page: http://msdn.microsoft.com/en-us/library/windows/apps/hh780611.aspx
Make sure you're doing it in the ready function of the js file that is referenced from your settings HTML. Try opening the JavaScript console or QuickWatch while broken at that line and also look at the DOM Explorer to see if you can find your toggle control. You should be able to access it though. Also, try element.getElementById instead of document.getElementById. Either should work actually, but as long as you're troubleshooting. Good luck.
Your problem is that you are trying to get a reference to the HTML element from the code running during the app activation. Although that piece of code may define the HTML to be loaded for a settings pane, it does Not actually load the HTML into the DOM. You just simply can't get the instance from that location.
What you need to do is have the settings flyout have its own js file that implements IPageControlMembers. In particular, you need to implement the ready method. This method is called once all the HTML and controls are loaded for the page, including your toggle. The link has an example of how to do this.
Also see:
WinJS.UI.Pages.define
Using single page navigation

Categories