The last programming challenge of the advanced JavaScript class on MOOC, I am also doing and searching. I hope to deepen my understanding of node acquisition method through this final summary.
HTML structure for effect analysis
The whole structure is divided into two parts from top to bottom. The title block is made in the form of a list, and the content is quickly made in the box model. The contents of the content block use
for line breaking, but it is also possible to use
for each line (I don’t know how to use CSS).
<div id="tab">
<ul class="tit"> <li> Property </li> <li> home </li> < LI > second-hand housing </li> < LI > 2.75 million buy changping adjacent iron sanju total price 200000 buy a house <br> 2 million buy the fifth ring road sanju 1.4 million settle down east third ring Road < BR > Beijing's first zero down payment real estate 530000 buy east 5 ring 50 flat building straight down 5000 < br > Beijing citic office park building king of existing < br > < / div > < div > 40 flat about the big transformation Beautiful girl mashup fossa < br > 90 classic pure and fresh and Jane's love family old room resurgent < br > the cool color of Chinese style new warmth < BR > < DIV > < DIV > < BR > The design of ceramic tile is like choosing a good wife bathroom flue. Tongzhou luxury 3, 2.6 million second ring scarce 2, 250W cast < BR > West 3 ring transparent 2, 2.9 million, 1.3 million 2 limit snap up < BR > Yellow Chenggen primary school district only 2.6 million 121 square seven hundred thousand throw! <br> </div> </div>Copy the code
The effect is like this,
Effect implementation CSS
Here, the effect is more difficult to think of is the border change, do think of two methods:
- Set a border at the bottom of the list
border-bottom
And then eachli
Set the background white and the bottom border to none to block the listul
Bottom border function.
- Each content box sets a top border
border-top
And then eachli
Set the background to white and the bottom border to none when clicking on the title blockli
To block the border of the corresponding part of the content box.
Here is the CSS that takes the first approach:
*{
margin: 0;
padding: 0;
}
#tab{ width:290px; /*padding:5px; */ height:150px; margin:20px; }#tab ul{list-style:none; /*display: block; */ height:30px; line-height:30px; border-bottom:2px saddlebrown solid; }#tab ul li{
display: inline-block;
cursor: pointer;
list-style: none;
height: 28px;
width: 60px;
line-height: 28px
margin:0 5px;
text-align: center;
border: 2px solid #aaa;border-bottom: none; } `Copy the code
The effect is basically achieved, now do the content block!
Following the previous thought, each box has a border, but no top border.
#tab div{
font-size: 14px;
height:120px;
line-height: 25px;
border:2px solid saddlebrown;
border-top: none;
padding:5px;
}
Copy the code
Content block to achieve the effect!
At this point, the style setting is basically complete, but according to the effect requirements, the title block of “property” is the default clicked state, so I add a class named on on the title of li, in order to better match the later JS to add the click event, I also set the style of on class:
#tab ul li.on{
height: 30px;
border:2px solid saddlebrown;
border-bottom: none;
background:#fff;
}
Copy the code
The second and third content blocks are hidden by default, so add the class name hide on both boxes and set the style of the hide class:
.hide { display:none; }
JavaScript for interactive effects
The first is the title block click effect — > add a mouse-click event to each LI: when one li is clicked, the class name of the current LI is on, and the class name of the other Li is empty.
var lis = document.getElementsByTagName("li");
//console.log(divs)
for(let i=0; i<lis.length; i++){
lis[i].onclick = function() {
for( let n=0; n<lis.length; n++){
lis[n].className = "";
}
this.className = "on"; }}Copy the code
The next step is to set up the content block. How do I set up the content block to show only the corresponding content block when the title is clicked? What do they have in common that binds the content to the title? So if I were to sort them, heading 1 corresponds to item 1, heading 2 corresponds to item 2, so I’m using index,
The index() method returns the index position of the specified element relative to other specified elements.
This is a position that we can set. When adding events to each li, the for parameter I is used to represent 0 and 1, 2 can represent the relative positions of the header blocks (lis[I].index = I), which are also the relative positions of the box blocks. We can use divs[this.index] to retrieve the box corresponding to the clicked title.
var divs = document.getElementById("tab").getElementsByTagName("div");
//console.log(divs)
for(let i=0; i<lis.length; i++){
lis[i].index = i;
lis[i].onclick = function() {
for( let n=0; n<lis.length; n++){
lis[n].className = "";
divs[n].className = "hide";
}
this.className = "on";
divs[this.index].className = ""; }}Copy the code
By now, all the effects required by the title have been achieved, looking back, feeling is not very difficult, but at that time when I just saw the title is still very meng, do not know how to get clicked title (think of bubbling and capture, behind also need to learn this), do not know how to set CSS…. I still need to learn more.
—————————— splitter ————— Many gurus have advised me that the previous method consumes memory: add a click event to each LI with a for loop. Here, I update this method with the event delegate:
window.onload = function() {
var uls = document.getElementById('tit');
var lis = uls.getElementsByTagName('li');
var divs = document.getElementById('tab').getElementsByTagName('div');
// console.log(lis)
console.log(divs)
uls.onclick = function(ec) {
for(let i=0; i<lis.length; i++){
lis[i].className = ""; // Iterate over each li setting class name
divs[i].className = "hide";
}
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.className = "on";
// we define a data-index attribute in each li
divs[target.getAttribute("data-index")].className = "";
console.log(target); }}}Copy the code
I gave each li a data-index attribute in HTML:
<li class="on" data-index="0"</li> <li data-index="1"> </li> <li data-index="2"</li>Copy the code
Then use getAttribute in JS to get the property value of li
divs[target.getAttribute("data-index")].className = "";
Copy the code