How to change h1 tittle when clicked/make the section centered - javascript

I'm working on some simple questions as practice for my exam, but most of the questions don't have any answers for me to check if I don't know. There is one I'm really unsure about, so I thaught I'd check here. The question is:
Suppose we have an HTML document that contains these two lines:
<Body>
<H1 title = "When this is clicked, the section changes"> Title </ h1>
<P id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </ P>
</ Body>
Type the code that would change the look of this page so that:
• When you click on the h1 title, the section changes from "First section: Original Version" to "First section: modified version ".
• When you click on the section, the position of the title changes and gets centered.
Hope someone can help learn me this so I have an answer if something similar shows up on my exam:)

var h1 = document.querySelector('h1');
var first = document.querySelector('#first');
h1.addEventListener('click', function() {
first.innerText = 'First section: modified version.';
});
first.addEventListener('click', function() {
h1.style.textAlign = 'center';
});

As others have mentioned, you should be able to find everything on Google. But to help you out, this is what the answer should be:
var heading = document.getElementsByTagName("h1")[0];
var section = document.getElementById("first");
heading.addEventListener("click", function() {
section.innerText = "First section: modified version";
});
section.addEventListener("click", function() {
heading.setAttribute("style", "text-align: center");
});
<h1 title="When this is clicked, the section changes">Title</h1>
<p id="first" title="When this is clicked, the title is centered">First section: Original version.</p>

Is this what you are looking for?
$(document).on("click", "h1", function() {
$(this).css("text-align", "center");
})
p, h1 {
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 title="When this is clicked, the section changes"> Title </h1>
<p id="first" title="When this is clicked, the title is centered"> First section: Original version. </p>

First of all Please correct your html markup to standards and add some javascript code. Check below snippet:
$(document).on('click', 'h1', function(){
$('#first').text('First section: Modified version.');
});
$(document).on('click', '#first', function(){
$('h1').css('text-align','center');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h1 title = "When this is clicked, the section changes"> Title </h1>
<P id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </ P>
</body>

I really have no idea why you're being downvoted here. From what I gather you've tried your best on all your assigned questions and this one happened to stump you...
Anyways.. this question has a few different problems that need to be solved for you to complete the question. I'm going to try to break these down into the components, and then explain the pieces that help us get to where you want to be.
Question 1
Thinking through this a bit, here are the following steps to solve your problem.
Find a way to "listen" for a "click event" on the <h1> element.
Find a way to change the text within the <p> element to the desired text when the <h1> element is clicked.
There are some substeps buried in this but this should get us started.
To solve this issue, we'll need to find a way to select elements on a page. A Google search yields a few methods to do this in vanilla JS based solely on the code you've given.
Query Selectors: document.querySelector and document.querySelectorAll
Tag selectors: document.getElementsByTagName
There are many others as well, but using only the code that you've supplied, and assuming we're not allowed to add class attributes or anything, we'll roll with the above choices.
The selectors above all return HTML "nodes" from the page. You can think of a HTML nodes as objects that make up an HTML page. They have all sorts of properties and we can perform many operations on them.
Your best bet is to use the first suggestion, document.querySelector because it returns a single HTML node based on the passed selector. Be careful though. If we had more than one of the same element, it would only return the first which isn't at all useful.
Here's some documentation you can read and a few examples to help you understand how it works.
document.querySelector documentation
So now we have a way of selecting the <h1> element on the page.
document.querySelector(h1);
Now, we need a way to listen for events. A search of "listening for events in vanilla JS" would bring you to the addEventListener method, which allows us to listen for events on a given HTML element.
eventListener documentation
Now we can put these two together and we have an <h1> element that listens for events. I'm going to skip ahead a bit and fill in the function so we have.
let title = document.querySelector('h1');
title.addEventListener('click', function() {
alert('I just clicked the title');
});
If you plug that in and click the title, you'll see a modal pop up indicating that you clicked the title. One step down.
Now, we have to find a way to change the "text content" of the <p> element to the desired text. To do this, we first need to select the <p> element and store it in a variable. You now know how to do this so I'll leave you to it.
Now that we have the reference to the node we want to modify, we need to change a property of that node related to the text. A Google search of this will return a few different properties, but I'm going to nudge you in the right direction and let you know you want the elem.textContent property.
Putting this all together, here's the code I have that works and satisfies your requirements for the first question.
let headerTxt = document.querySelector('h1');
let sectionTxt = document.querySelector('p');
headerTxt.addEventListener('click', function() {
sectionTxt.textContent = 'First section: modified version';
});
Question 2
Some similarities from the first question here. We need to...
Select both the <h1> and <p> elements on the page (DONE)
add a click event listener to the <p> element that centers the <h1> element.
We can skip the first piece since we did that in question 1. I'm also going to skip adding an event listener to the <p> since we did something similar to that in the first question.
After adding the event listener, we need a way to change the text-alignment of some text in an HTML element.
A Google search brings us to the textAlign CSS property which we can modify using JS.
textAlign
Putting this all together, here's the complete solution
let headerTxt = document.querySelector('h1');
let sectionTxt = document.querySelector('p');
headerTxt.addEventListener('click', function() {
sectionTxt.textContent = 'First section: modified version';
});
sectionTxt.addEventListener('click', function() {
headerTxt.style.textAlign = 'center';
});
<body>
<h1 title = "When this is clicked, the section changes"> Title </h1>
<p id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </p>
</body>
Hope this helps man. One takeaway of advice I have for you is get used to searching and get used to reading documentation. I'm a beginner too and I've figured that out quickly lol.
Good luck!

Related

back and forth between nodes in vanilla javascript

I'm expanding a site (menright.com) that displays about fifty years of photos. This link goes to the first photo page: (https://menright.com/pages/photoPages/photos-1967.php). Each photo is followed by a caption, and there is a button that allows the viewer to see a longer description that replaces the caption. The button isn't working here but allows you to see what I'm talking about.
To implement this I have an img (the button) inside of a p tag (the caption). Clicking the button substitutes the longer description drawn from the alt and the title in a second img (the picture) immediately above the caption.
I can't use IDs since there are many captions and pictures on each page.
Here is the HTML skeleton of the significant parts of the problem:
<img alt='long description' title='location image taken' />
<p class='the caption'> <img class='get long description button' /> </p>
I'm thinking I have to find the node of the target (the button), track its parent (the caption), and then get the alt and title from something like a previousSibling (the picture) and use the innerHTML of the parent (the caption) to display the long description.
Am I correct in this assumption, or is there another way to do this? And if this is the technique I need to use, how do I do it? I'm totally new to using nodes in my vanilla Javascript, and I don't want to add JSquery or other libraries to my pages.
This is my first post here, though I've used the site for years. Thanks for any help you might provide!
I'm thinking I have to find the node of the target (the button), track its parent (the caption), and then get the alt and title from something like a previousSibling (the picture) and use the innerHTML of the parent (the caption) to display the long description.
Am I correct in this assumption, or is there another way to do this?
If you stick to that structure, yes, that's what you'd do (probably previousElementSibling so you don't have to worry about intervening Text nodes), and setting textContent rather than innerHTML unless you want < and & in the text to be interpreted as HTML. You'd probably do it via event delegation on whatever container has all of these in it (body, if there's nothing nearer):
theContainer.addEventListener("click", event => {
const btn = event.target.closest(".get.long.description.button");
if (btn && theContainer.contains(btn)) {
const p = btn.parentElement;
const alt = p.previousElementSibling?.alt;
if (alt) {
p.textContent = alt; // `textContent` assuming you don't have tags
}
}
});
But if you can wrap all of that in an element:
<div class="wrapper">
<img alt='long description' title='location image taken' />
<p class='the caption'>
<img class='get long description button' />
</p>
</div>
...you can make it more robust:
theContainer.addEventListener("click", event => {
const wrapper = event.target.closest(".container");
if (wrapper && theContainer.contains(wrapper)) {
const p = wrapper.querySelector(".the.caption");
const alt = wrapper.querySelector(".location.image.taken")?.alt;
if (alt) {
p.textContent = alt; // `textContent` assuming you don't have tags
}
}
});
That doesn't rely on the exact relationship between the elements, just that they're all in the same container, so you can move them around as the page design evolves without changing your code.

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.

Change blockquotes when selecting faces

I have bunch of code already written (JS fiddle project) and I'm almost done, but I need some kind toggle thing i JS when you click a person's face, then the quote (scroll down at the result if you can't see it) will change to that person's quote.
I've already got a switch in the JS with this part:
$(function() {
var $profiles = $("#profile1, #profile2, #profile3, #profile4, #profile5, #profile6, #profile7, #profile8, #profile9, #profile10, #profile11");
$profiles.click(function(e) {
$profiles.removeClass("focused");
$(this).addClass("focused");
});
});
but I need to combine it with the quotes somehow.
If you really don't want to help me out with specific, I'd be just happy with just pseudo code or help on how to think. I've been sitting with this piece for way too long now to be able to think straight.
What would you recommend?
Cheers all, you guys rock!
I solved your problem like this:
$profiles.click(function(e) {
var profileNr = parseInt($(this).attr("id").substring(7));
$profiles.removeClass("focused");
$(this).addClass("focused");
$(".thequote .show").removeClass("show");
$(".thequote blockquote").eq(profileNr-1).find("p").addClass("show");
});
It extracts the index of the quote from the profile number and then selects the appropriate quote with jQuery eq(). I updated your JS Fiddle as well and tested that it works.
You have to have some kind of reference in your blockquote, for example a data attribute which indicates to which profile the quote belongs. For example:
<blockquote data-profileid="profile8">
<p>
"Sist är starkast... eller något sånt."
</p>
</blockquote>
Then in the onclick function, show the blockquote with the data attribute that matches the clicked id. You can get the clicked id like this:
var id = $(this).attr('id');

Wrap a new div element around specific text

I am struggling with this one.
How can I wrap a new <div> element around text that does not have any class or ID?
Below is the scenario:
<div class="ContentDiv">.....</div>
Share your knowledge. Be the first to write a review »
I need the new div to wrap around "Share your knowledge. Be the first to write a review »"
I have tried the following:
$(document).ready(function() {
$('.ContentDiv').each(function() {
$(this).add($(this).next()).wrapAll('<div class="NewDiv"></div>');
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ContentDiv">.....</div>
Share your knowledge. Be the first to write a review »
but it is not working because it wraps around the <a> element only and leaves the text below it. I need the rest of the text in there as well.
You need to get the next textnode after .ContentDiv and wrap that:
$('.ContentDiv').each(function() {
$(this).next('a').add(this.nextSibling).wrapAll('<div class="NewDiv"></div>');
});
FIDDLE
Since jQuery does'nt really get textnodes, the native nextSibling should work.
For this you can add a div after $('.ContentDiv') and then add the html to it.
$("<div id='new_div'></div").insertAfter($('.ContentDiv')).html("Share your knowledge. <a href='URL'>Be the first to write a review »</a>");

Getting my head around jQuery

OK, I'm designing a site and thought I'd stick some jQuery in as I really need so js experience.
Page with my problem is here: http://new.focalpix.co.uk/moreinfo.php
JS in question is:
$(document).ready(function(){
$(".answer").css("display","none");
$("#maincontent a.animate").click(function() {
$("#maincontent .answer").slideUp('slow');
var id = $(this).attr('href');
$(id).slideDown('slow');
return false;
});
});
This works fine, but if you click on a link where the answer has already slid down, then it slides up, then back down again.
I'm not sure on the cleanest way to stop this happening - any ideas?
You should be using the .slideToggle() effect.
$(document).ready(function() {
$(".answer").css("display","none");
$("#maincontent a.animate").click(function() {
$("#maincontent .answer").slideToggle('slow');
});
});
First, I'd suggest the following structure for your faq's:
<div id="faq">
<div class="qa" id="faq_greenandflies">
<span class="q">What is green and flies</span>
<div class="a">
Super Pickle!
</div>
</div>
<div class="qa" id="faq_redandbadforteeth">
<span class="q">What is Red and bad for your teeth</span>
<div class="a">
a Brick
</div>
</div>
<!--
More FAQ's here
-->
</div>
and then defining your jQuery as follows:
<script type="text/javascript">
$(function(){
// hide all answers
$('div#faq .qa .a').hide();
// bind a click event to all questions
$('div#faq .qa .q a').bind(
'click',
function(e){
// roll up all of the other answers (See Ex.1)
$(this).parents('.qa').siblings().children('.a').slideUp();
// reveal this answer (See Ex.2)
$(this).parents('.qa').children('.a').slideDown();
// return true to keep any other click events
return true;
});
// check location.hash to see if we need to expand one (direct link)
$(location.hash).find('.q a').click();
});
</script>
Explanation:
(Ex.1)
this is the link that was clicked
get the element that contains this and has a class of 'qa' (the box that contains both question and answer)
select all of its siblings. (we now have all qa's as a jQ object)
hide the answers
(Ex.2)
this is the line or link that was clicked
get the element that contains this and has a class of 'qa' (the box that contains both question and answer)
reveal the answer
A working demo is here.
This does several things for you:
If a user deep-links to an answer, the answer is automatically revealed
If a user clicks on one answer, all other answers are hidden
You can give your divs proper ids, so which helps search engine optimization of links to individual answers
Use slideToggle() like Soviut said, but just as a tip -- you can declare the display property in the actual CSS file instead of declaring it inside the javascript. jQuery will pick up on the fact that it is hidden in the stylesheet and still perform the appropriate slide function.
You can also use $(".answer").hide();
Instead of setting the display CSS property. Just thought I would let you know.
try using the one method, something like:
$(selector).one('effect', 'data for effect', callback function);
it makes sure an effect only happens once per element.

Categories