How to get Text of Nested Span HTML element? - javascript

I want to get text from Nested SPAN element in Following HTML code:
<span id='result_box'>
<span class="hps">text_content</span>
</span>
I want to get "text_content" value using JavaScript.
I have tried this but have a problem:
var resBox=document.getElementById('result_box');
var strTrans=resBox.getElementsByTagName('span')[0].innerHTML;
alert(strTrans);
EDIT: Actually i want to do this from Online Page

your code works fine. i guess your problem is you are executing these code when DOM not loaded completely.if you are testing something, you can try this.
window.onload = function () {
//put your code here,it will alert when page loaded completely.
};
or put the script after your span element. like this.
<span id='result_box'>
<span class="hps">text_content</span>
</span>
<script type='text/javascript'>
var resBox=document.getElementById('result_box');
var strTrans=resBox.getElementsByTagName('span')[0].innerHTML;
alert(strTrans);// it will alert
</script>

you get the element by classname.. document.getElementsByClassName() and then grabbing the first item off the resulting node list
window.onload = function () {
document.getElementsByClassName("hps")[0].innerHTML
};
jsfiddle

var resBox=document.getElementById('result_box');
var strTrans=document.getElementsByTagName('span')[0].innerText;
alert(strTrans);​
or better
strTrans = document.querySelector(".hps").innerText ;

got you, i guess you embed a link in your html page,then you wanna manipulate DOM in the page you embed,right? if so, you can check browser same origin policy.
if you wanna implement online translation via google, you can google 'google translate api', google provides a api to others for implementing online translation in their own applications.
it seems like bing also provides a api.i'm not sure.

Related

Document.querySelector returns a NULL value - script is at bottom of page

I am trying to get the patientNumber (ClinicA100-PF-TR1-P1) using querySelector. I keep getting a NULL value. The patientNumber is at the top of the page and the script is at the bottom. Even after the page is loaded, I click a button that runs the function and it still returns a NULL value.
Here is a screenshot of the selectors (https://recordit.co/IypXuuXib0)
<script type="text/javascript">
function getPatientNumber(){
var patientNumber = document.querySelector("patientNumber");
console.log(patientNumber);
console.log("hello");
return patientNumber;
}
var patientNumber = getPatientNumber();
console.log(patientNumber);
_kmq.push(['identify', patientNumber]);
</script>
Thank you for any help you can provide.
ADDITIONAL HTML INFORMATION:
I am using Caspio (database management software) to create this HTML code. I don't know if that may be the cause of the issue. Here is the HTML CODE.
<p class="sponsorName" id="sponsorNameID">[#authfield:User_List_Sponsor_Name]</p>
<p class="clinicNumber" id="clinicNumberID">[#authfield:User_List_Site_Number]</p>
<p class="protocolNumber" id="protocolNumberID">[#authfield:User_List_Protocol_Number]</p>
<p class="patientNumber" id="patientNumberID">[#authfield:User_List_Patient_Number]</p>
You are missing a dot.
var patientNumberNode = document.querySelector(".patientNumber");
var patientNumber = patientNumberNode.innerText;
if you select the item with class".", if you select with id, you should use"#".
var patientNumber = document.querySelector(".patientNumber"); // class select
var patientNumber = document.querySelector("#patientNumber"); // id select
Your selector is incorrect. It should be
var patientNumber = document.querySelector(".patientNumber");
Why is it failing:
When you use patientNumber as the selector, JavaScript looks for an element with a name of patientNumber. Since that's not the case, and you are looking for an element with a class of patientNumber, you need to use the . notation.
Addon Suggestion (can be ignored):
Since you are also using IDs, consider using document.getElementById() as it is faster than using document.querySelector().
Note that if you use document.getElementById(), your .patientNumber selector won't work. You need to write it as
document.getElementById('patientNumberID');
//ID based on the screenshot of the DOM you've shared
While the code is at the bottom of the page, and the element is at the top, it is not loaded asynchronously as it comes from a third party database. i put a delay in the getPatientNumber() and it works now.

Remove any specific html code using javascript

In the past I used Google Developer Console to delete some specific divs on a page. I could do it manually of course but in some cases where the divs where many I had to use the console. I had a single line code that did the job (I found it while searching the internet) but I lost my note.
So how can I delete using javascript any html code (by copy pasting the code).
Something like:
elements = $('<div ... </div>');
elements.remove();
OR
$('<div ... </div>').remove();
Any ideas? I am not an expert in javascript (obviously) and I've been searching stackoverflow for hours without finding anything that works.
UPDATE: I think some people might get confused with my question. Google developer console accepts javascript command lines. So even though I ask for javascript I will use the code on the google developer console.
UPDATE 2 :
Here is an example of a div I need to delete. Keep in mind I want to copy paste the entire code in the javascript code. Not just identify the div.
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
It's the data-entry-status="declined" that makes that div unique so I can't just identify the div using an id selector or a class selector. I need to put the entrire thing there and remove it.
I tried:
$('<div class="entry-status-overlay" data-entry-status="declined"><div class="entry-status-overlay__inner"><span class="entry-status-overlay__title">Declined</span></div></div>').remove();
It didn't remove the div.
Try to search the dom by its outerHTML.
function deleteDomByHtml(html){
html=html.replace(/\s/g,'');
$("*").each(function(){
if(this.outerHTML.replace(/\s/g,'')===html){
$(this).remove();
}
});
}
And try this line on this page:
deleteDomByHtml(`<span class="-img _glyph">Stack Overflow</span>`);
You cannot do by simply pasting the code. That will remove all the div element.
You may need a specific selector like id,class or child to specific parent to remove the element from the dom.
Consider this case the divs have common class but the data-entry-status is different. So you can get the dom using a selector and then check the dataset property.
For demo I have put it inside setTimeout to show the difference. In application you can avoid it
setTimeout(function() {
document.querySelectorAll('.entry-status-overlay').forEach(function(item) {
let getStatus = item.dataset.entryStatus;
if (getStatus === 'declined') {
item.remove()
}
})
}, 2000)
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
<div class="entry-status-overlay" data-entry-status="accepted">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">accepted</span>
</div>
</div>
Just add any attribute with [] and it will remove the element.
$('[class="entry-status-overlay"]').remove();
/*OR*/
$('[data-entry-status="declined"]').remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
function del(){
var h = document.body.outerHTML;
h = h.match('<div>...</div>');
h.length--;
return h;
}
I guess this will work just give it a try... i tried on browser console and it worked, this way you can match the exact you want.
I might as well add my take on this. Try running this in your console and see the question vanish.
// convert the whole page into string
let thePage = document.body.innerHTML,
string = [].map.call( thePage, function(node){
return node.textContent || node.innerText || "";
}).join("");
// I get some string. in this scenario the Question or you can set one yourself
let replacableCode = document.getElementsByClassName('post-layout')[0].innerHTML,
string2 = [].map.call( replacableCode, function(node){
return node.textContent || node.innerText || "";
}).join("");
// replace whole page with the removed innerHTML string with blank
document.body.innerHTML = thePage.replace(replacableCode,'');
If you want to identify divs with that particular data attribute, you can use a data-attribute selector. In the example below, I've used a button and click event to make the demo more visual, but in the console the only line you'd need would be:
$('div[data-entry-status="declined"]').remove();
$(function() {
$("#testbutton").click(function() {
$('div[data-entry-status="declined"]').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
<div id="x">Some other div</div>
<button type="button" id="testbutton">Click me to test removing the div</button>
See https://api.jquery.com/category/selectors/attribute-selectors/ for documentation of attribute selectors.
P.S. Your idea to paste some raw HTML into the jQuery constructor and then execute "remove" on it cannot work - you're telling jQuery to create an object based on a HTML string, which is, as far as it's concerned, a new set of HTML. It does not try to match that to something existing on the page, even if that exact HTML is in the DOM somewhere, it pays it no attention. It treats what you just gave it as being totally independent. So then when you run .remove() on that new HTML...that HTML was never added to the page, so it cannot be removed. Therefore .remove() has no effect in that situation.

Try It Yourself Editor JS

I have created a very simple editor that has been working great. However, I just tried to put JavaScript into it and I can't get it to work.
The code for the editor:
<div id="buttoncontainer">
<input id="button" onclick="update();" type="button" value="Update page">
</div>
<div id="tryitcontainer">
<textarea id="codebox"></textarea>
<iframe id="showpage"></iframe>
</div>
The JavaScript for the editor:
<script>
function update() {
var codeinput = document.getElementById('codebox').value;
window.frames[0].document.body.innerHTML = codeinput;
}
</script>
I just wanted to run some simple JavaScript that changes an image when it is clicked. This code works fine when I run it in a full browser, so I know its the editor thats the problem.
Is there a simple fix for this that I'm missing?
The button is not finding the update() method. You need that function to be globally available:
http://jsfiddle.net/t5swb7w9/1/
UPDATE: I understand now. Internally jQuery basically evals script tags. There's too much going on to be worth replicating yourself... either use a library to append, or eval the code yourself. Just a warning that eval'ing user input is rarely a good thing and is usually a welcome mat for hackers.
window.myScope = {
update: function() {
var div = document.createElement('div'),
codeinput = document.getElementById('codebox').value,
scriptcode = "";
div.innerHTML = codeinput;
Array.prototype.slice.apply(div.querySelectorAll("script")).forEach(function(script) {
scriptcode += ";" + script.innerHTML;
div.removeChild(script);
});
window.frames[0].document.body.appendChild(div);
// hackers love to see user input eval'd like this...
eval(scriptcode);
}
};
And then you would update your button like so:
<input id="button" onclick="myScope.update();" type="button" value="Update page">
Or, even better, use addEventListener and forget the onclick part altogether. I'll let you do that research on your own ;)
JavaScript inserted via innerHTML will not be executed due to security reasons:
HTML5 specifies that a <script> tag inserted via innerHTML should not execute.
from MDN: Element.innerHTML - Security considerations, see also: W3: The applied innerHTML algorithm.
A possible solution using the jQuery method .append() works around that, as it somehow evals the content. But this will still not solve your problem, as the JavaScript code is executed in the current scope.
Here's a test scenario:
function update() {
var codeinput = document.getElementById('codebox').value;
$(window.frames[0].document.body).append(codeinput);
}
Try it here
Try to insert this script:
<script>
alert( document.getElementById('tryitcontainer') );
</script>
and this one:
<p id="test">Test</p>
<script>
window.frames[0].document.getElementById('test').innerHTML = 'updated';
</script>
The first one will return a [object HTMLDivElement] or similar. Here you can see, that you're still in the same scope as the parent frame. The second one will correctly update the content within the iframe. Keep that in mind, when experimenting with those things.
Maybe Executing elements inserted with .innerHTML has some more infos for you.

Grails rendered content accessing id elements dynamically

AJAX content is being rendered with a remoteLink function inside the form to populate a accordion (just a little background info).
The function attatchEmail(test) which is being called on the double-click of each paragraph content of the JQuery Accordion widget. This is what happens running the function... Screenshot of 1st alert & Screenshot of 2nd alert.
Is it not possible to select the paragraph and get the contents from the paragraph like below?
(I have tried changing .val to .html and .text. I have also tried $('#'+testingID))
_form.GSP
function attatchEmail(test) {
$(document).ready(function()
{
var testingID = test.id;
alert(testingID);
var testingValue = $(testingID).val();
alert(testingValue);
});
};
_contactListAjax.GSP
<g:each in="${contactList}" status = "i" var="contact">
<h3>${contact.contactSurname +', '+ contact.contactForename}</h3>
<div><p id="contact${contact.id}" ondblclick="attatchEmail(this)">${'Email: '+contact.email}</p></div>
</g:each>
Run out of avenues to explore, I'm sure I've done something simple like this before perfectly fine :/
See two screenshots please for better insight, thanks
Well, it looks like you're using jQuery but it also looks like you're not really buying into the jQuery methodology. Mixing behavior with markup is not really considered a good practice these days, especially when using a library like jQuery. I'm not sure of your exact issue but I would recommend changing it to something like the following:
<g:each in="${contactList}" status = "i" var="contact">
<h3>${contact.contactSurname +', '+ contact.contactForename}</h3>
<div><p class="contact-email" data-id="${contact.id}">${'Email: '+contact.email}</p></div>
</g:each>
$(function() {
$("body").on("dblclick", ".contact-email", attachEmail);
});
function attatchEmail(event) {
var $element = $(event.target);
var id = $element.data("id");
};
This should help fix any issues with dynamic rendering because of the way the jQuery on function works.

Replace html placeholder text with html element using javascript

I have a scenario where i have in my page a placeholder text that I will replace after the page is fully loaded.
My problem is that the text i need to replace is a plugin of the recaptcha image, for example:
I have the text loading... which will be replaced by:
<recaptcha:recaptchacontrol ID='recaptcha' runat='server' PublicKey='kfldsjfh4378qyf43h4eidfhew' PrivateKey='sdflkdsfy908s6dfdsfkj' Theme='clean' />
I couldn't find a way to do so, any help will be appreciated.
found the answer in chat:
as the <recaptcha:...> tags are parsed by some server side plugin, they were not rendered after writing them in client side JS. so replacing works fine, but plugin didn't...
you can do any string operations (like search and replace) on document.body.innerHtml:
document.body.innerHtml = document.body.innerHtml.replace(/Loading\.\.\./g,
"<recaptcha...>");
Wrap your "Loading..." text in a <span> with a unique id, such as
<span id="removeme">Loading...</span>
Then, if you don't want to do much DOM-fu with that complex, namespaced tag, you can do the following:
var removeme = document.getElementById('removeme');
removeme.innerHTML = "<recaptcha:recaptchacontrol ...";
var recaptchaThing = removeme.firstChild;
removeme.removeChild(recaptchaThing);
var parent = removeme.parentNode;
parent.insertBefore(recaptchaThing, removeme);
parent.removeChild(removeme);
This will replace the <span> with the <recaptcha:recaptchacontrol> element, after letting the browser figure out how to build the DOM for that bizarre element. If it turns out <recaptcha:recaptchacontrol> can't be placed inside of a <span> element, make it a <div style="display:inline"> instead.

Categories