day18 面对对象

概述:

面向对象是一种编程思想(oop) , 它是相当于面向过程的一个抽取和简化. 主要是以类来构建对象,以对象来存储对应的行为和属性 , 抽取对应的行为作为方法 , 抽取对应的属性作为属性 .

核心 : 万物皆对象(所有的内容都可以抽取为一个对象)

关键点 : 找有这个行为的对象去完成这个行为

面向对象和面向过程 :

面向过程以过程为核心
示例 ( 去饭店吃饭 )
  • 先找饭店

  • 找服务员点餐

  • 等待上菜

  • 吃饭

  • 结账

面对对象以对象为核心
示例
  • 我找饭店 ( 我这个对象 , 找饭店这个对象 )

  • 结账 , 吃饭 , 点餐属于我的行为

  • 饭店提供的服务属于饭店的行为

对象的构建

需要调用new关键词 去执行构造函数来创建对象
通过类来构建对象(构造器) (es6)
//通过类来构造对象 (区分对应的类型)
class Person{
    constructor(username){ //构造器,他是一个函数,new的时候会调用对应的构造函数
        this.name = username //this指向当前构造的实例对象
    }
}
var person = new Person('jack')
通过构造函数来构建 (es3)
//通过构造函数创建 , 首字母要大写
function Person(name){
    this.name = name //函数里的this指向它的调用者,在new的时候会指向对应的对象实例
}
var person=new Person('Alex')
上述的两种构建方式 其实核心上都是一种 , 都是通过构造函数 ( 构建对象的函数 ) 来构建

通过构造函数构建 做了什么操作

  • 自动构建对象

  • 手动设置属性

  • 自动返回对象

通过工厂模式来构建 , 返回对应的对象 ( 不能区分类型 )
  • 手动创建对象

  • 手动创建属性

  • 手动返回对象

//工厂里面传入的属性 返回的是对象(不能区分类型)
function factory(name){
    //object是最大的对象,手动构建对象
    var obj = new Object()
    //手动给对象添加属性
    obj.name = name
    //手动返回对象
    return obj
}
//调用
var obj = factory('发财')
var obj1 = factory('发大财')
console.log(obj,obj1)
工厂模式的特性
  • 可以构建所有的对象

  • 在构建对象的时候会忽略细节

  • 构建出来的对象都是Object ( instanceof 全部指向object )

console.log(obj instanceof Object) //true
console.log(obj1 instanceof Object) //true

面对对象的三大特性

  • 封装 ( 将对应的行为抽取为方法 )

  • 继承 ( 子类继承父类的属性和方法 )

  • 多态 ( 继承关系的体现 , 重写 : 子类重写父类的方法 ) , 重载 ( 在一个类中同名不同参数 , js没有会覆盖 ))

封装示例

示例 : 有一只猫会喵喵叫 , 它很胖800斤 , 吃得很多 , 名字叫咪咪

属性 : 体重800斤 , 名字咪咪

方法 : 喵喵叫 , 吃很多

继承及对应的重写
class Person{
    constructor(){
        this.name='jack'
         this.say=()=>{
            console.log('hhhh')
        }
    }
}
class Son extends Person{
    constructor(){
        super()
        this.age=25
        this.say=()=>{
            console.log('oooo')
        }
    }
}
var son =new Son()
console.log(son) //name,age,say
son.say()

面对对象tab栏切换

属性 : 上面的tab栏 , 下面的显示框

行为 : tab栏的点击事件 , 显示栏的切换方法

//构建一个类
class Tab{
    constructor(nav,content){
        this.nav=nav //上边的点击栏
        this.content=content //下边的切换栏
    }
    //切换的方法
    toggele(selectedElement){
        //遍历上边的点击栏,选中的设置样式,其他的清空样式
        Array.from(this.nav).forEach((item)=>{
            item.className=''
        })
        selectedElement.className='selected'
        //遍历下边的切换栏
        Array.from(this.content).forEach((item)=>{
            item.className=''
        })
        //找到上边点击栏被选中的下标
        let i = Array.from(this.nav).findIndex((v)=>{
            return v==selectedElement
        })
        //改这个下标对应的样式
        this.content[i].className='show'
    }
    //点击的方法
    handlerClick(){
        let self=this
        //遍历上边点击栏,给每个成员添加点击事件并切换
        Array.from(this.nav).forEach((item,i)=>{
            item.onclick=()=>{
                self.toggle(item)
            }
        })
    }
}

面对对象实现盒子区间拖拽

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

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .box {
                width: 500px;
                height: 500px;
                border: 1px solid #000;
                position: relative;
            }

            .move {
                width: 100px;
                height: 100px;
                background-color: aqua;
                position: absolute;
            }
        </style>
    </head>

    <body>
        <div class="box">
            <div class="move"></div>
        </div>
        <script>
            // 面对对象实现盒子拖拽
            class Touch {
                constructor(box, move) {
                    this.box = box //大盒子
                    this.move = move //移动的盒子
                    this.point = { //坐标位置,初始位置是0,0
                        x: parseInt(this.getStyle(this.move).left || 0),
                        y: parseInt(this.getStyle(this.move).top || 0)
                    }
                    this.handlerDown()
                }
                // 获取样式的方法
                getStyle(element) {
                    if(window.getComputedStyle){
                        return window.getComputedStyle(element,'')
                    }else{
                        return element.currentStyle
                    }
                }
                // 按下事件
                handlerDown() {
                    this.move.onmousedown = (e) => {
                        e = e || window.event
                        // 获取移动盒子按下的位置
                        let currentX = e.offsetX
                        let currentY = e.offsetY
                        // 调用移动的方法
                        this.handlerMove(currentX, currentY)
                        // 调用弹起的方法
                        this.handlerUp()
                        console.log(currentX, currentY)
                    }
                }
                // 移动事件
                handlerMove(currentX,currentY) {
                    // 给大盒子添加移动事件
                    this.box.onmousemove = (e) => {
                        e = e || window.event
                        // 获取大盒子在页面上的位置
                        let { x, y } = this.getPagePoint(this.box)
                        // 获取可移动位置 = 页面上的位置-大盒子在页面上的位置-当前按下的位置
                        let { targetX, targetY } = {
                            targetX: e.pageX - currentX - x,
                            targetY: e.pageY - currentY - y
                        }
                        // 获取最大拖拽值
                        let maxX = this.box.offsetWidth - this.move.offsetWidth
                        let maxY = this.box.offsetHeight - this.move.offsetHeight
                        // 区间判断,为了让盒子不超出移动范围
                        if (targetX < 0) {
                            targetX = 0
                        }
                        if (targetX > maxX) {
                            targetX = maxX
                        }
                        if (targetY < 0) {
                            targetY = 0
                        }
                        if (targetY > maxY) {
                            targetY = maxY
                        }
                        // 设置位置(调用方法)
                        this.point = { x: targetX, y: targetY }
                        this.setStyle()
                    }
                }
                // 鼠标弹起事件
                handlerUp() {
                    document.onmouseup = () => {
                        this.box.onmousemove = null
                    }
                }
                // 设置位置的方法
                setStyle() {
                    this.move.style.left = this.point.x + 'px'
                    this.move.style.top = this.point.y + 'px'
                }
                // 获取到父元素的距离,一直到body循环就结束
                getPagePoint(element) {
                    let x = 0
                    let y = 0
                    while (element.offsetParent) {
                        x += element.offsetLeft
                        y += element.offsetTop
                        element = element.offsetParent
                    }
                    return { x, y }
                }
            }
            var box = document.querySelector('.box')
            var move = document.querySelector('.move')
            // 调用实现拖拽
            new Touch(box,move)
        </script>
    </body>

</html>

基于拖拽实现放大镜

// 放大镜功能和盒子区间拖拽的实现有类似
class Magnifier extends Touch{
    constructor(box,move,bigBox,bigImg){
        // 传给父类
        super(box,move)
        this.bigBox=bigBox
        this.bigImg=bigImg
        this.handlerEnter()
        this.handlerLeave()
    }
    handlerEnter(){
        this.bos.onmouseenter = ()=>{
            this.move.style.display = 'block'
            this.bigBox.style.display = 'block'
            this.init()
            //调用移动的方法
            this.handlerMove(this.move.offsetWidth/2,this.move.offsetHeight/2)
        }
    }
    handlerLeave(){
        this.box.onmouseleave = ()=>{
            this.move.style.display='none'
            this.bigBox.style.display='none'
        }
    }
    init(){
        // 将移动的move的大小初始化
this.move.style.width = this.box.offsetWidth / (this.bigImg.offsetWidth / this.bigBox.offsetWidth)+'px'
        this.move.style.height = this.box.offsetHeight/(this.bigImg.offsetHeight/this.bigBox.offsetHeight)+'px'
    }
    setStyle(){
        //根据对应的坐标来设置位置
        this.move.style.left = this.point.x+'px'
        this.move.style.top = this.point.y+'px'
        //获取大图片的定位
        //公式为 : 大盒子/移动的盒子 = 大图片/图片盒子
        //故图片定位应是 = 大盒子/移动的盒子*图片盒子
        let x = this.point.x/this.box.offsetWidth*this.bigImg.offsetWidth*-1
        let y = this.point.y/this.box.offsetHeight*this.bigImg.offsetWidth*-1
        //根据定位设置大图片的位置
        this.bigImg.style.left = x+'px'
        this.bigImg.style.top = y+'px'
    }
}

 

posted @ 2022-10-26 21:25  邱你咋滴  阅读(25)  评论(0)    收藏  举报