Object oriented 5.3 of JS learning notes

1. Object oriented and process oriented

1.1 pop (process oriented programming)

Process oriented is to analyze the steps needed to solve the problem, and then use functions to realize these steps step by step, and call them one by one.

Process oriented is to solve problems according to the steps we have analyzed.

1.2 object oriented programming (OOP)

Object oriented is to decompose transactions into objects, and then divide and cooperate among objects.

Put the elephant into the refrigerator. The object-oriented approach is to find out the objects first and write out the functions of these objects:

1. Elephant object

go in

2. Refrigerator object

open

close

3. Use the function of elephant and refrigerator

Object oriented is to divide problems by object functions, not steps.

Object oriented features: encapsulation, inheritance, polymorphism

2. Classes and objects in ES6

Object oriented thinking characteristics:

1. Extract (Abstract) the attributes and behaviors shared by objects, organize (encapsulate) them into a class (template)

2. Instantiate the class and get the object of the class

2.1 # object

In JavaScript, an object is an unordered collection of related attributes and methods. All things are objects, such as strings, values, arrays, functions, etc.

Objects are composed of properties and methods:

Attribute: the characteristic of a thing, which is represented by an attribute in an object (a common noun)

Method: the behavior of things is expressed by means in the object (commonly used verb)

class 2.2

The concept of class is newly added in ES6. You can use the class keyword to declare a class, and then instantiate the object with this class.

Class abstracts the common part of an object. It generally refers to a large class

Object refers to a specific object that is instantiated through a class

2.3 creating classes

Syntax:

class name {
  // class body
}       

Create instance:

var xx = new name();    

Note: the class must instantiate the object with new

2.4 class constructor

The constructor() method is the constructor of the class (the default method). It is used to pass parameters and return the instance object. When the object instance is generated through the new command, this method will be called automatically. If the definition is not displayed, a constructor() will be automatically created inside the class

Syntax:

class Person {
  constructor(name,age) {   // Constructor construct method or constructor
      this.name = name;
      this.age = age;
    }
}       

Create instance:

var ldh = new Person('Lau Andy', 18); 
console.log(ldh.name)    

2.5 adding method of class

Syntax:

class Person {
  constructor(name,age) {   // Constructor constructor or constructor
      this.name = name;
      this.age = age;
    }
   say() {
      console.log(this.name + 'Hello');
   }
}       

Create instance:

var ldh = new Person('Lau Andy', 18); 
ldh.say()   

Note: methods cannot be separated by commas, and methods do not need to add function keyword.

3. Inheritance of class

3.1 succession

Inheritance in programs: subclasses can inherit some properties and methods of the parent class.

Syntax:

class Father{   // Parent class
} 
class  Son extends Father {  // The subclass inherits the parent class
}       

example:

class Father {
      constructor(surname) {
        this.surname= surname;
      }
      say() {
        console.log('What's your last name' + this.surname);

       }
}
class Son extends Father{  // In this way, the subclass inherits the properties and methods of the parent class

}
var damao= new Son('Liu');
damao.say();      

3.2 super keyword

super keyword is used to access and call functions on the parent class of an object. You can call the constructor of the parent class or the ordinary function of the parent class

Syntax:

class Person {   // Parent class
      constructor(surname){
         this.surname = surname;
     }
} 
class  Student extends Person {       // The subclass inherits the parent class
     constructor(surname,firstname){
          super(surname);             // Call the constructor(surname) of the parent class
	this.firstname = firstname; // Define properties unique to subclasses
     }
}       

Note: the subclass uses super in the constructor, which must be placed before this (the constructor of the parent class must be called first, and the constructor of the subclass must be used)

3.3 # precautions

1. In ES6, classes do not have variable promotion, so you must define classes before instantiating objects through classes

2. The common attributes and methods in the class must be used with this

3. this in the class points to the problem

4. This in the constructor points to the instance object, and this in the method points to the caller of this method

4 cases

Object oriented tab bar switching

Functional requirements:

1. Click the tab bar to switch the effect

2. Click the + sign to add tab items and content items

3. Click x to delete the current tab item and content item

4. Double click the text of tab item or content item to modify the text content

Abstract object: Tab object, which has the functions of switching, adding, deleting and modifying

Add features:

1. Click + to add new tabs and contents

2. Step 1: create a new tab li and a new content section

3. Step 2: add the two created elements to the corresponding parent element

4. Advanced method: use insertAdjacentHTML() to directly add string format elements to the parent element 5 AppendChild does not support appending sub elements of strings. insertAdjacentHTML supports appending elements of strings. 6 insertAdjacentHTML (where to append, 'string element to append')

7. The additional position is: before end after the last child node inside the element

8.The method address:  https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML 

Delete function:

1. Click × You can delete the current li tab and the current section

2.X does not have an index number, but its father li has an index number. This index number is the index number you want

3. So the core idea is: click the x sign to delete the li and section corresponding to the index number

4. However, when the new li and index number are deleted dynamically, the element x also needs to be retrieved The init method needs to be called

Editing function:

1. Double click the text in the tab li or section to realize the modification function

2. Double click the event: ondbllick

3. If you double-click the text, the text will be selected by default. At this time, you need to double-click to prohibit the selection of the text

4.window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

5. Core idea: when double clicking the text, a text box is generated inside. When the focus is lost or press enter, then give the value entered in the text box to the original element

index code:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>object-oriented Tab</title>
    <link rel="stylesheet" href="./styles/tab.css">
    <link rel="stylesheet" href="./styles/style.css">
</head>

<body>

    <main>
        <h4>
            Js Object oriented dynamic adding tabs
        </h4>
        <div class="tabsbox" id="tab">
            <!-- tab label -->
            <nav class="fisrstnav">
                <ul>
                    <li class="liactive"><span>Test 1</span><span class="iconfont icon-guanbi"></span></li>
                    <li><span>Test 2</span><span class="iconfont icon-guanbi"></span></li>
                    <li><span>Test 3</span><span class="iconfont icon-guanbi"></span></li>
                </ul>
                <div class="tabadd">
                    <span>+</span>
                </div>
            </nav>

            <!-- tab content -->
            <div class="tabscon">
                <section class="conactive">Test 1</section>
                <section>Test 2</section>
                <section>Test 3</section>
            </div>
        </div>
    </main>

    <script src="js/tab.js"></script>
</body>

</html>

css code:

@font-face {font-family: "iconfont";
  src: url('./iconfont/iconfont.eot?t=1553960438096'); /* IE9 */
  src: url('./iconfont/iconfont.eot?t=1553960438096#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAK4AAsAAAAABmwAAAJrAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAp4fwE2AiQDCAsGAAQgBYRtBzAbpQXIrrApw71oi3CCOyzEy8RvE4yIN8TD036/zp03qCYRjaJZNBFFS/gREoRGipQKofjuNrb+9XbTqrmXcqWzfTRDqFqWkhAJzYToaE6LQ7Q30CirRqSKMnj58DdIdrNAdhoTQJa5VGfLrtiAy+lPoAcZdUC57UljTR4TMAo4oL0xiqwYG8YueIHPCdTqYajty/t+bUpmrwvEnUK42lQhLMssVy1UNhzN4kmF6vSQVvMY/T5+HEU1SUXBbti7uBBrx++cgqJULp0GhAgBna5AgSkgE0eN6R1NwTitNt0yAI5VG7wr/8AljmoX7K+zq+tBF1Q8k9JTPWp1AjnJDgCzmM3bU0V31dsvV3M2eC6fHjaGfX/qS7U5Gr58vj6uD0bgxudyrV/OtHHyP+NZnpO1txbktjdY+3FB61+7nxeOzq8niGYnRwT3v3aZxeXf6rrNxl5//49WlEtZUUL1Pj3Bv1EO7MuG2namrCkbvcnApLUJtWpRhv2tzlRLx43kQ7WO2/FW6c5QqDZEZnYKFeosoVK1NdSa5E/XaVM1Ra7BhAEQmk0kjV5QaLbIzG5U6HRRqTkK1DqJtivrjMT1zJaNnIsihAiyQE3JdbszcW0Xiadzdl4d8UO0HSUGNDNXzl2hifYSO5pPjrorgdjUAAavoa5TKDZVUXD3kuuOOzh70fShvUiN2owtNsRxIREIIiATUCYpGO2aqXy/CxEeHcfuaKrLDiGbQ5kcEMsNIK8M5qCmR3mn8RFHOpcECBtlAAwWIZ2OAqV5kQoJXHvShORYBzrDZKhhb3uT8QPlrA3bmsKZV6i89DiTV2o1AAAA') format('woff2'),
  url('./iconfont/iconfont.woff?t=1553960438096') format('woff'),
  url('./iconfont/iconfont.ttf?t=1553960438096') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('./iconfont/iconfont.svg?t=1553960438096#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-guanbi:before {
  content: "\e676";
}

* {
    margin: 0;
    padding: 0;
}

ul li {
    list-style: none;
}

main {
    width: 960px;
    height: 500px;
    border-radius: 10px;
    margin: 50px auto;
}

main h4 {
    height: 100px;
    line-height: 100px;
    text-align: center;
}

.tabsbox {
    width: 900px;
    margin: 0 auto;
    height: 400px;
    border: 1px solid lightsalmon;
    position: relative;
}

nav ul {
    overflow: hidden;
}

nav ul li {
    float: left;
    width: 100px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border-right: 1px solid #ccc;
    position: relative;
}

nav ul li.liactive {
    border-bottom: 2px solid #fff;
    z-index: 9;
}

#tab input {
    width: 80%;
    height: 60%;
}

nav ul li span:last-child {
    position: absolute;
    user-select: none;
    font-size: 12px;
    top: -18px;
    right: 0;
    display: inline-block;
    height: 20px;
}

.tabadd {
    position: absolute;
    /* width: 100px; */
    top: 0;
    right: 0;
}

.tabadd span {
    display: block;
    width: 20px;
    height: 20px;
    line-height: 20px;
    text-align: center;
    border: 1px solid #ccc;
    float: right;
    margin: 10px;
    user-select: none;
}

.tabscon {
    width: 100%;
    height: 300px;
    position: absolute;
    padding: 30px;
    top: 50px;
    left: 0px;
    box-sizing: border-box;
    border-top: 1px solid #ccc;
}

.tabscon section,
.tabscon section.conactive {
    display: none;
    width: 100%;
    height: 100%;
}

.tabscon section.conactive {
    display: block;
}

js code:

var that;
class Tab {
    constructor(id) {
        // Get element
        that = this;
        this.main = document.querySelector(id);
        this.add = this.main.querySelector('.tabadd');
        // Parent element of li
        this.ul = this.main.querySelector('.fisrstnav ul:first-child');
        // section parent element
        this.fsection = this.main.querySelector('.tabscon');
        this.init();
    }
    init() {
            this.updateNode();
            // The init initialization operation causes related elements to bind events
            this.add.onclick = this.addTab;
            for (var i = 0; i < this.lis.length; i++) {
                this.lis[i].index = i;
                this.lis[i].onclick = this.toggleTab;
                this.remove[i].onclick = this.removeTab;
                this.spans[i].ondblclick = this.editTab;
                this.sections[i].ondblclick = this.editTab;

            }
        }
        // Because we add elements dynamically, we need to get the corresponding elements again
    updateNode() {
            this.lis = this.main.querySelectorAll('li');
            this.sections = this.main.querySelectorAll('section');
            this.remove = this.main.querySelectorAll('.icon-guanbi');
            this.spans = this.main.querySelectorAll('.fisrstnav li span:first-child');
        }
        // 1. Switching function
    toggleTab() {
            // console.log(this.index);
            that.clearClass();
            this.className = 'liactive';
            that.sections[this.index].className = 'conactive';
        }
        // Clear all li and section classes
    clearClass() {
            for (var i = 0; i < this.lis.length; i++) {
                this.lis[i].className = '';
                this.sections[i].className = '';
            }
        }
        // 2. Add functions
    addTab() {
            that.clearClass();
            // (1) Create li element and section element 
            var random = Math.random();
            var li = '<li class="liactive"><span>new tab </span><span class="iconfont icon-guanbi"></span></li>';
            var section = '<section class="conactive">test ' + random + '</section>';
            // (2) Append these two elements to the corresponding parent element
            that.ul.insertAdjacentHTML('beforeend', li);
            that.fsection.insertAdjacentHTML('beforeend', section);
            that.init();
        }
        // 3. Delete function
    removeTab(e) {
            e.stopPropagation(); // Prevent bubbling and trigger switching click events of li
            var index = this.parentNode.index;
            console.log(index);
            // Delete the corresponding li and section remove () methods according to the index number to directly delete the specified element
            that.lis[index].remove();
            that.sections[index].remove();
            that.init();
            // When we delete a li that is not in the selected state, the original selected li remains unchanged
            if (document.querySelector('.liactive')) return;
            // When we delete the selected li, the previous li will be selected
            index--;
            // Manually invoking our click event does not need to be triggered by the mouse
            that.lis[index] && that.lis[index].click();
        }
        // 4. Modify function
    editTab() {
        var str = this.innerHTML;
        // Double click to suppress the selected text
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        // alert(11);
        this.innerHTML = '<input type="text" />';
        var input = this.children[0];
        input.value = str;
        input.select(); // The text in the text box is selected
        // When we leave the text box, we give the value in the text box to span 
        input.onblur = function() {
            this.parentNode.innerHTML = this.value;
        };
        // Press enter to return the value in the text box to span
        input.onkeyup = function(e) {
            if (e.keyCode === 13) {
                // Manually calling the event that the form loses focus does not require the mouse to leave the operation
                this.blur();
            }
        }
    }

}
new Tab('#tab');

Tags: Javascript Front-end ECMAScript

Posted by askbapi on Tue, 03 May 2022 20:00:27 +0300