Access view-source instead of prepared DOM - javascript

Hopefully I can explain my question correctly, so sorry in advance for any wrong use of jargon or other:
Is it possible to access with javascript the original markup as viewed in the source code rather then the code from the DOM after it has been 'modified'
Let's say an element #div1 has the actual text that will be used in another element with id #div2, in the source code the text will be visible in #div1 but in the DOM while inspecting #div1 will be empty and #div2 will have that text,
I know it would be a matter of the order of loading the scripts, but I was hoping there could be another way.
Hopefully this makes some sense.

Yep, the simpliest way to access original html is to place your js code before any other scripts (or place only libs like jquery before).
The second opportunity is to load document again with ajax, parse and get what you want. Here is code example:
<div id="div1">
Hello
</div>
<div id="div2">
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
$('#div2').html($('#div1').html())
$('#div1').html('')
</script>
<script>
alert($('#div1').html())
// ajax get
// empty string in get request means current location
$.get("", function (html) {
var el = $(html).filter('#div1');
alert(el.html())
});
</script>

Related

Javascript: Can I Use JS to Copy an HTML Element From One Page to Another?

New to JS. Couldn't find any good solutions for this after researching, and seems like it shouldn't be too complicated.
Say I have a page called page1.html with this code:
<div class="page1">
<div class="wrapper">
<p>Some text.</p>
</div>
</div>
Now, I have a second page, page2.html, with this code:
<div class="page2">
</div>
I want to make a copy of the div with class wrapper from page1.html, and insert it into page2.html, within the div with class page2.
Both pages share the same script.js file.
I tried something like this:
page1content = document.querySelector('.wrapper');
page2content = document.querySelector('.page2');
page2content.append(page1content);
However, I'm getting errors on page1.html because the js can't find the div with class page2, and I'm getting errors on page2.html because the js can't find the div with class wrapper.
I found a similar question here, and a couple comments suggest using localStorage.
I am unfamiliar with localStorage so I tried to do some research, and tried something like this:
On page1.html I inserted this script at the bottom:
<script>
var pageContent = document.querySelector(".page1").innerHTML;
sessionStorage.setItem("page1content", pageContent);
</script>
On page2.html I inserted this script at the bottom:
<script>
document.querySelector(".page2").innerHTML=sessionStorage.getItem("page1content");
</script>
It didn't work for me, but perhaps I used it incorrectly.
I also tried to use cloneNode(), but again, wasn't sure how to transplant the clone of the element onto a new page, only onto the same page I'm cloning from.
Is there another way to accomplish what I'm trying to do?
Obviously this is a very basic example; my actual code will be pumping in much more content from page 1 to page 2, but I just want to get the concept working at least.
The code I had in my example in the description was almost correct, I just had to change sessionStorage to localStorage and it worked.

How can I load the HTML resulting from external .js call?

Googlebot sees content differently (doesn't index it at all) than the visitor if the content was generated dynamically from a JS file (see image above). Let's say I have the following code:
<body>
<div>Bunch of Content</div>
<script type="text/javascript" src="/js/somefile.js" />
<div>Bunch of Content</div>
</body>
How can I display the actual resulting HTML in the document when the page loads:
<body>
<div>Bunch of Content</div>
<p>Javascript dynamically created this string and this string.</p>
<p>Date: timestamp by JS</p>
<p>Other info dynamically created by JS.</p>
<div>Bunch of Content</div>
</body>
I have JS doing the heavy lifting to generate some content dynamically specifically for the page. The problem is, because the content is being generated in a JS file, the content never gets loaded in the DOM for indexing by crawlers.
Is there a way to do this? Thanks!
Google CAN index dynamic content, but it does not mean it will index it, or display it in search results, as it usually only looks for it in search of negative aspects (like black-hat SEO practices), although for some sites it may decide to use it for its index (it's a blind guess really, when it comes to how Google handles this, as they don't disclose this kind of details).
If your JS is making an AJAX request, and you're the owner of the API or whatever endpoint you're calling from the request, then your best bet is to cache the result on the server side, and modify your HTML page (which should be dynamic) so it renders the latest cached result in the HTML sent to the browser, but wrapped in a container tag (like a <div>) with an inocuous CSS rule like opacity: 0; so the content isn't visible to users by default, which should be changed to opacity: 1; by your JS file once the up-to-date HTML is loaded.
You could use jQuery to accomplish this, like in the example below:
$(document).ready(function() {
var el = "<section>Dynamically added content</section>";
$('.a').after(el);
})
div {
padding: 10px;
background-color: #ccc;
}
section {
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">Bunch of Content</div>
<div>Bunch of Content</div>
Update: If you're using Ajax to get data from the server, then you would include the update on your code from the returning data object. You could extend this to iterate through the values you get.
$.getJSON('[Your url]', { param: 'value' },
function (data) {
var el = "<section>" + data.value + "</section>";
$('.a').after(el);
});
});

Insert just opening HTML tags after an element?

I would like to insert a couple of opening DIV tags after the H1 element on a page, without inserting the corresponding closing tags (since the closing tags are contained in an included footer file which I don't have access to).
i.e.
Existing code:
<body>
<h1>Heading One</h1>
... page content...
</div>
</div>
</body>
New code:
<body>
<h1>Heading One</h1>
<div id="foo">
<div id="baa">
... page content...
</div>
</div>
</body>
DOM methods insert the div as a complete (closed) element, 'createTextNode' inserts escaped characters and 'innerHTML' needs an element to insert into. Have even tried to insert a script element with document.write without any luck.
Any ideas (jQuery would be fine)?
Update
The following worked:
document.body.innerHTML = document.body.innerHTML.replace('</h1>','</h1><div id="foo"><div id="baa">')
As pointed out by Asad the solution (which now seems obvious of course) is to use string methods on the HTML rather than DOM methods.
If you're dealing with DOM manipulation, use DOM manipulation methods. If you're dealing with HTML manipulation, use string manipulation methods.
h1.parentElement.innerHTML = h1.parentElement.innerHTML.replace("<h1>Heading One</h1>","<h1>Heading One</h1><div><div>");
i think this will answer your question, it is all about valid XML formation.
http://www.w3schools.com/xml/xml_syntax.asp
Forget DOM methods, insert it as a string using .replace().
Your approach is fundamentally wrong. The browser parses the DOM as it sees it, and automatically closes any tags that ought to be closed. It's impossible to use JavaScript to insert only the opening tag.
You say "the closing tags are contained in an included footer file which I don't have access to." Closed tags that haven't been opened are ignored, so as far as the DOM parser is concerned, those closing tags don't exist.
Your solution is either:
Put the opening tags in a header, or somewhere else on the server-side, or
Use JavaScript to grab ALL the following DOM elements, including the footer, and .wrap() them all in the desired divs.
This kind of practice seems a bit unorthodox, but perhaps something like this would help.
Existing HTML
<h1 id="testH1">Test H1</h1>
<div id="existingDiv">
<div id="existingDivContent">Existing Div Content</div>
</div>
New HTML
<h1 id="testH1">Test H1</h1>
<div id="newDiv">
<div id="existingDiv">
<div id="existingDivContent">Existing Div Content</div>
</div>
</div>
JS
The javascript is fairly rudimentary, but I think the concept can be applied to safely and properly achieve your goal.
$(document).ready(function() {
//-- parent node you wish to copy
var existingDiv = $('#existingDiv');
//-- new parent div node
var newDiv = $('<div id="newDiv">');
//-- where we want to insert the new parent node
var testH1 = $('#testH1');
//-- stuff our previous parent node into our new parent node
newDiv.html(existingDiv);
//-- insert into the DOM
testH1.after(newDiv);
});
http://jsfiddle.net/8qzvN/

How can I execute the code inside a <script></script> only when I'll show its container?

I have this code :
HTML
Show Agency
<div id="invisibleDiv">
<script src="http://platform.linkedin.com/in.js" type="text/javascript"></script>
<script type="IN/CompanyProfile" data-id="1035" data-format="inline" data-related="false"></script>
</div>
jQuery
$("#showDiv").click(function () {
$("#invisibleDiv").show();
});
CSS
#invisibleDiv
{
display:none;
}
When I load the page, I see the scripts loaded from external source, also if the div is hidden. The scripts call with some API and generate HTML/Javascript.
Well, what I'm looking for is to force the script to be unloaded if the parent is hidden; than, when I'll show it (through the link), load the script inside the div.
How can I do it? I'll avoid AJAX.
UPDATED:
DEMO: http://jsfiddle.net/HqeD2/
Show Agency
<div id="invisibleDiv">
<script type="IN/CompanyProfile" data-id="1035" data-format="inline" data-related="false"></script>
</div>
$(function() {
$("#showDiv").click(function() {
$.getScript("http://platform.linkedin.com/in.js");
});
});
If I understand it correctly, you just want to delay the running of arbitrary scripts that are provided by the third party? Would something like this work?
<div id="invisibleDiv" style="display:none">Please wait while we load some stuff from Facebook...</div>
$("#showDiv").click(function(){
$("#invisibleDiv").show().load("http://facebook.com/whatever/andStuff");
});
Has the downside that you can't pre-fetch the HTML content, but I don't see any other way.
EDIT: ok, it looks like you edited the question whle I was typing this up... so YOU control the content of invisibleDiv, but you want to delay the loading of in.js? try this...
$("#showDiv").click(function(){
$("#pleaseWaitDiv").show();
$.getScript("http://platform.linkedin.com/in.js", function(){
$("#pleaseWaitDiv").hide();
$("#invisibleDiv").show();
});
});
Again, you have to make the user wait while the script downloads, hence my addition of pleaseWaitDiv
More edit:
New up a script node and append it.
var scriptNode = $("<script></script>")
.attr("type","IN/CompanyProfile")
.attr("data-id","1035")
.attr("data-format","inline")
.attr("data-related","false");
$("#invisibleDiv").append(scriptNode);
$.getScript("http://platform.linkedin.com/in.js", function(){
$("#pleaseWaitDiv").hide();
$("#invisibleDiv").show();
});
You can bind it to your showDiv click function, inline scripts are processed right away...the only other thing I can think of is to have the script be loaded via ajax which you don't want.
Try this :
http://jsfiddle.net/sXJa6/6/

jQuery: Parse/Manipulate HTML without executing scripts

I'm loading some HTML via Ajax with this format:
<div id="div1">
... some content ...
</div>
<div id="div2">
...some content...
</div>
... etc.
I need to iterate over each div in the response and handle it separately. Having a separate string for the HTML content of each div mapped to the id would satisfy my requirements. However, the divs may contain script tags, which I need to preserve but not execute (they'll execute later when I stick the HTML into the document, so executing during parsing would be bad). My first thought was to do something like this:
// data being the result from $.get
var clean = data.replace(/<script.*?</script>/,function() {
// insert some unique token, save the tag, put it back while I'm processing
});
$('<div/>').html(clean).children().each( /* ... process here ... */);
But I worry that some stupid dev is going to come along and put something like this in one of the divs:
<script> var foo = '</script>'; // ... </script>
Which would screw it all up. Not to mention, the whole thing feels like a hack to begin with. Does anyone know a better way?
EDIT: Here's the solution I've come up with:
var divSplitRegex = /(?:^|<\/div>)\s*<div\s+id="prefix-(.+?)">/g,
idReplacement = preDelimeter+'$1'+postDelimeter;
var r = data.replace(<\/div>\s*$/,'').
replace(divSplitRegex,idReplacement).split(preDelimeter);
$.each(r,function() {
var content;
if(this) {
callback.apply(null,this.split(postDelimeter));
}
});
Where preDelimiter and postDelimeter are just unique strings like "###I'd have to be an idiot to embed this string in my content unescaped because it would break everything###', and callback is a function expecting the div id and the div content. This only works because I know that the divs will have only an id atribute, and the id will have a special prefix. I suppose someone could put a div in their content with an id having the same prefix and it would screw things up too.
So, I still don't love this solution. Anyone have a better one?
FYI, Using unescaped in any JavaScript script causes this issue in a browser. Developers have to escape it anyway so there is no excuse. So you can "trust" that would break in any case.
<body>
<div>
<script>
alert('<script> tags </script> are not '+
'valid in regular old HTML without being escaped.');
</script>
</body>
See
http://jsbin.com/itevu
to see it break. :)
In some cases removing script tags results in invalid html:
<html>
<head>
</head>
<body>
<p>This should be
<script type="text/javascript">
document.writeln("<b");
</script>>bolded</b>.
</body>
</html>

Categories

Resources