Finding and Executing / Extracting embedded JavaScript from AJAX result using jQuery - javascript

I'm performing an AJAX request to get a generated html page. I want to find a specific div in the result and inject it into the page where the request came from. I also want to include embedded script or script links which may be inside this div. Here is a simple sample of the page I want to get with AJAX
<html>
<head>
<script>alert("don't want this")</script>
</head>
<body>
<div id='findMe'>
<p>Some content</p>
<script>alert("want only this")</script>
</div>
<script>alert("don't want this")</script>
</body>
</html>
So I only want to extract the div with ID findMe. Here's what I have in the page that's doing the request
<script>
$(document).ready(function(){
$.ajax({
url: "ajax.htm",
success: function(data){
$(data).filter("#findMe").appendTo("#output");
},
dataType: "html"
});
});
</script>
<div id='output'></div>
But the script tag is missing and no alert appears. It seems to get taken out of the div. If I do
console.log($(data))
I can see each of the script tags as a document fragement, but how to I know which one was in the div before it was popped out?

You can try:
$(data).find('#findMe').appendTo('#output');
OR
$('<div/>').append(data).filter("#findMe").appendTo("#output");
Append data to a demo div (not exists in DOM) and make filter over that.

I think instead of .filter(), which filters the current jQuery collection, you have to use .find():
$(data).find("#findMe").appendTo("#output");
But I am unsure whether the script tag will be executed or not..

I had to treat the result as XML. Find the element I'm looking for in the XML object using jQuery .find(), select the actual node (array pos 0), convert the contents of the node to a string, and inject into the output div. This is the only method I've found that executes scripts only contained in the target div.
$.ajax({
url: "ajax.htm",
success: function (data){
var node = $(data).find("#findMe")[0];
if(node.xml)
{
$("#output").html(node.xml)
}
else if(new XMLSerializer())
{
$("#output").html((new XMLSerializer()).serializeToString(node));
}
},
dataType: "xml"
});

Related

jQuery - How to get an element's class from ajax request

I'm loading my website's pages with ajax by replacing the content inside the main tag.
Problem is, using Wordpress, each page has its own body classes that are useful for styling purposes, so I want to replace the old page's body classes by the next page's classes.
I thought i'd run a new ajax request to get the whole html page, then check for the body element, then use .attr("class") to get the list of class and finally replace the old body classes by the new one...
But the classes always return undefined instead of a list of classes.
EDIT: I tried to use .cd-main-content instead of body and weirdly it works, I get the classes of this element. So I assume now that the problem doesn't come from my syntax but from the element itself.
How can I possibly get it to work on the body element ? (I already tried to replace .find by .filter but it doesn't work either.)
HTML stucture
<body id="body" class="home page-id-number other-classes">
<main>
<div class="cd-main-content">
<!-- inside is the dynamically loaded content-->
</div>
</main>
</body>
jQuery
$.ajax({url: url,
success: function(data){
var body = $(data).find("#body");
var classes = body.attr("class");
console.log(data); //returns the html as expected
console.log("body : "+body); //returns [object Object]
console.log("classes : "+classes); //returns undefined
}
});
"body" tag filtering by jQuery when getting from string.
So $(data)[0] will back all content, without body.
Also use filter, not "find"
So you can get classes like that:
$.ajax({url: url,
success: function(data){
//replace body tag
data = data.replace("<body", "<container").replace("body>", "container>");
var classes = $(data).filter("container").attr("class");
$("body").attr("class", classes);
}
});
Your jQuery code is wrong:
$.ajax({url: url,
success: function(data){
var body = $(data).find("body"); //not #body
var classes = body.attr("class");
console.log(data); //returns the html as expected
console.log("body : "+body); //returns [object Object]
console.log("classes : "+classes); //returns undefined
}
});
The right selector is body not #body, which is an id selector
So, to change your body classes use this code:
$.ajax({url: url,
success: function(data){
var classes = $(data).find("body").attr("class"); //get the classes
$("body").attr("class", classes); //set the classes
}
});
jQuery Selectors
I found a solution, it's not ideal but it fixed the problem.
First, I have to assume that it is not possible to get the attributes of the body element as it appears to be filtered by jQuery. However it is possible to get the child elements.
I ended up adding the body classes to both the body and main elements (in the header.php file of wordpress).
Here's my code now :
HTML
<body id="body" class="home page-id-number other-classes">
<main class="home page-id-number other-classes">
<!-- if I had the possibility, I'd have added "data-body-class" instead of "class" -->
<div class="cd-main-content">
<!-- inside is the dynamically loaded content-->
</div>
</main>
</body>
jQuery
$.ajax({url: url,
success: function(data){
var classes = $(data).filter("main").attr("class"); //get the classes
$("body, main").attr("class", classes); //set the classes
}
});

How to get source code of html page

This is a link for an example of Edit source Code:
http://neokoenig.github.io/jQuery-gridmanager/demo/tinymce.html
the button which value is </>.
He get the code HTML even if he changes the content of the grid.
How to get the source code HTML using JavaScript or jQuery?
Thanks.
Using JavaScript
document.documentElement.outerHTML
More info
or
document.documentElement.innerHTML
More info
you can use the html method with jquery, i.e for get the whole page html like this:
$( document ).ready(function() {
console.log($("html").html());
})
I'm not sure what you want to do exactly but if you want to get raw source code from jQuery you can use the following:
var html = $('element').html();
And with pure javascript from an id
var html = document.getElementById('id').innerHTML;
or from classname
var html = document.getElementsByClassName('class').innerHTML;
And to get the content of your example (which is an editor called tinymce) you can use the command tinymce.activeEditor.getContent(); or tinyMCE.get('myTextarea').getContent()
EDIT:
If you want to listen for changes with jQuery and display to html dynamically you'd want to do something like this:
$('yourTextArea').keyup(function() {
var html = $(this).val();
$('yourElementToDisplayTheHTML').html(html);
});
I've built a simple API, just use this:
<script src="https://cdn.jsdelivr.net/gh/Parking-Master/viewsource#latest/vs.js"></script>
In your JavaScript:
getSource('https://example.com/');
in http response header, you can find "content-type" header. that header indicates how contents of page should be rendered. so, if you want to render page as plain text("source code", as you mentioned), just change that header like this -> "content-type : text/plain; charset=UTF-8"
if you can use ajax in jquery or javascript
use like this
$("button").click(function(){
$.ajax({url: "page_you_want.html", success: function(result){
alert(result);
}});
});

How to disable HTML tags in a div?

I have a page to show a log file, sometimes the log file contains some html tags and they make my page run slower since the tags are converted to contents like pictures etc., I want to disable that, so my goal is to show those tags as texts only, they should never be converted to contents.
This is the jquerythat I use:
<script type="text/javascript">
$(document).ready(function() {
setInterval(function() {
$.ajax({
url: "ssh.log",
success: function(result) {
$("#ssh").html(result);
}
});
var textarea = document.getElementById("ssh");
textarea.scrollTop = textarea.scrollHeight;
}, 1000);
});
</script>
And my div looks like this:
<div id="ssh"></div>
How can I accomplish that?
Use .text() to render content as a text:
$("#ssh").text(result);
Change:
$("#ssh").html(result);
to
$("#ssh").text(result);
As the previous answers have said, use .text() to render it as just plaintext. If for some reason you need to keep it as .html(), you can use simple string replacement to escape the tags.
result = result.replace('<','<');
$('#ssh').html(result);

JQuery ignore html created with ajax

I have an html table and it's content created with ajax
And I have a button which adds a row at the begining of the table
But JQuery don't know about the ajax content and adds row only after it
$("#add-row-first").on("click", addrowfirst);
function addrowfirst(){
$("#table").prepend("<tr><td>1</td><td>cell</td><td>cell</td><td>cell</td></tr>");
}
ajax
function genTable(){
$.ajax({
type: "POST",
dataType: "html",
url: "inc/gen-table.php",
success: function(data){
$("#table").html(data);
}
});
}
html
<button id="add-row-first">create row</button>
<table id="table"></table>
SOLUTION
So the solution was very simple.
My ajax reqest return string "<tr><td>some text</td></tr>".
So there is no <tbody> tag and the prepend insert code into tbody tag which not exsists.
And it automaticly creates it after ajax generated code. So your ajax should return <tbody><tr><td>some text</td></td></tdbody>
if element #add-row-first is created after the document is created you can't use it that way. You can use the .on() with another parameter so it will find the element like this instead
$("#table").on("click", "#add-row-first",addrowfirst);
If I am understanding your issue correctly, this should do it. The documentation is a little hard to digest, but basically, the first element #table needs to exist at the time of the document being loaded, and the element #add-row-first can be added to the DOM later, as long as it is a child of #table jQuery knows how to find it.
Simplest solution of this case could be
var data = "<tr><td>1</td><td>cell</td><td>cell</td><td>cell</td></tr>";
$('#table').html( data + $('#table').html());

Getting element by tag name after getting a page using jQuery $.get

I am requesting a full page using $.get in jQuery and would like to get the content of a specific element. Separately, here is how things look:
$.get( "/page.html").done(function( data ) {
// get textArea.
});
and I want to get:
document.getElementByTagName("textArea")[0].value;
but I can't do getElementByTagName on data so what is the best way to do this?
I tried using find but that did not work so I ended up using filter and that returned the value of textArea that I needed:
$.get( "/page.html").done(function( data ) {
var textArea = $(data).filter("textarea")[0].innerText;
});
It's slightly different of what you are doing but i think it can help. You can call .load instead of get and add the whole page to a div say <div id="mydiv"></div>
var value;
$('#mydiv').load('xyz.html',function(){value=$('#mydiv').find('#mytextarea').val()})
however if you do not want mydiv to show you can hide at the beginning once the main page gets loaded and if you also don't want this div on your page you can remove it after the above task is performed.
$(document).ready(function(){
$('#mydiv').hide();
var value;
$('#mydiv').load('xyz.html',function(){value=$('#mydiv').find('#mytextarea').val()});
$('#mydiv').remove();
})
//str represents page.html
var str = 'gibberish gibberish <textarea class="test">hello world</textarea>gibberish';
$.each( $.parseHTML(str), function( i, el ) {
if(el.firstChild) console.log(el.firstChild);
});
Fiddle: http://jsfiddle.net/ez666/7DKDk/
You could try jquery load() function.
It will load from remote server and insert document into selected element.
It also allow us to specify a portion of remote document to be inserted.
Assume your remote textarea's id is "remote" and you want to fetch the remote content into a textarea which id is "local"
var result="";
$("#local").load("/page.html #remote", function(response, status, xhr){
result=$(this).find("#remote").val();
});
I'm not sure if you want to get the remote textarea and insert into the element of the current document.
If you just want to get the value of the remote textarea, you could just hide the load function invoking element
Hope this is helpful for you.
Since you're using jQuery anyway… have you tried $(data).find('textarea').first().val() yet?
This is assuming that data is a fragment. If it is not you will want to wrap it in a div or something first.

Categories