day12-事件下

事件流的传播阶段(顺序)

  • 捕获阶段
  • 目标阶段
  • 冒泡阶段

事件流的两种模式 

  • 冒泡模式:从里到外逐层执行,常用的一种模式,也是默认模式
  • 捕获模式:从外到内逐层执行,火狐提出来的,ie6,7,8不支持,很少使用

阻止事件冒泡的方法

  • stopPropagation   阻止冒泡,有兼容问题

e.stopPropagation() //阻止事件冒泡 常用的方法 兼容问题

  • cancelBubble    取消冒泡,兼容低版本

// 兼容写法 兼容ie8及以下
e.cancelBubble = true

  •  兼容写法

//兼容写法
e . stopPropagation ? e stopPropagation():e cancelBubble  =  true

 阻止默认行为

  • preventDefault(event对象的方法),有兼容问题

preventDefault()

  • returnValue(event对象的方法)。ie的兼容写法

e returnValue =false

  •  兼容写法

preventDefault?e preventDefault():e returnValue =false

  •  return false

//对应的右键点击
window.oncontextmenu = function(e){
        console.log('右键点击了')
        return false //一定要放在最后
}

示例:右键自定义菜单栏,具有前进、后退、刷新、换肤功能

css代码

 <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        ul {
            display: none;
            width: 80px;
            height: 120px;
            border: 1px solid #000;
            position: absolute;
        }
        
        li {
            list-style: none;
            height: 24px;
            background-color: #ccc;
        }
    </style>

html代码 

    <ul>
        <li onclick="history.forward()">前进</li>
        <li onclick="history.back()">后退</li>
        <li onclick="location.reload()">刷新</li>
        <li onclick="document.body.style.backgroundColor=randomColor()">换肤</li>
        <li onclick="print()">打印</li>
    </ul>

js代码 

    <script>
        // 右键自定义菜单栏,具有前进、后退、刷新、换肤功能
        var ul = document.querySelector('ul')

        document.oncontextmenu = function(e) {
            e = e || window.event
                // 取消右击默认属性
            e.preventDefault ? e.preventDefault() : e.returnValue
                // 右击ul隐藏
            ul.style.display = 'block'
                // 鼠标右击时,ul随页面点击位置改变
            ul.style.left = e.pageX + 'px'
            ul.style.top = e.pageY + 'px'
        }

        ul.onmouseover = function(e) {
                e = e || window.event
                if (e.target.tagName == 'LI') {
                    for (var item of this.children) {
                        item.style.backgroundColor = '#ccc'
                        item.style.color = '#000'
                    }
                    e.target.style.backgroundColor = '#666'
                    e.target.style.color = '#fff'
                }
            }
            // 当点击完毕后ul要隐藏
        ul.onclick = function(e) {
                e = e || window.event
                if (e.target.tagName == 'LI') {
                    this.style.display = 'none'
                }
            }
            // 随机颜色
        function randomColor() {
            var r = Math.random() * 256
            var g = Math.random() * 256
            var b = Math.random() * 256
            return `rgb(${r},${g},${b})`
        }
    </script>

事件监听器

eventListener 他是一个标准的观察者模式,他是通过对应的监听器来监听事件的触发和执行。

两个方法

  • addEventListener(事件名,函数名(函数),模式): 添加事件监听器
  • 事件冒泡和事件捕获的监听同时进行,那么会优先监听到事件捕获
  • 该方法可以监听多个处理函数,而onclick这种属性赋值的方法只可以进行一次,后写的会覆盖先写的
  • 事件名可以自定义
  • removeEventListener(要移除的事件名,要移除的函数名,模式): 移除事件监听器
  • 移除监听事件,里面的三个参数必须全部一致
  • 如果添加事件监听器的时候传入处理函数为匿名处理函数 那么不能被移除(对象比对的是地址)
    <div onclick="console.log('我被电击了');">
        <button onclick="console.log('别点我');">按钮
            <p onclick="console.log('点div去');"></p>
        </button>
    </div>
    <script>
        var div = document.querySelector('div')
        var btn = document.querySelector('button')

        btn.addEventListener('click', function() {
                console.log('1');
            }, false) //冒泡事件

        btn.addEventListener('click', function() {
                console.log('3');
            }, true) //捕获事件,会先执行
        btn.addEventListener('click', function() {
                console.log('2');
            }) //冒泡事件


        // 移除监听事件,里面的三个参数必须全部一致
        btn.addEventListener('click', headle, false) //冒泡事件
        btn.removeEventListener('click', headle, true)

        function headle() {
            console.log('5');
        } //冒泡事件


        // 内置属性的移除事件,
        document.querySelector('div').onclick = null
    </script>

拖拽

拖拽原理

  • 给对应的需要拖拽的元素添加鼠标按下事件
  • 在按下事件内添加给区间的元素对应的鼠标移动事件
  • 在按下事件内给document添加对应的鼠标弹起事件 在弹起事件中释放移动事件及释放弹起事件

基础拖拽

【思路】

  • 获取拖拽的元素
  • 给拖拽元素添加鼠标按下事件 并记录按下的坐标(在对应的盒子里的坐标)
  • 在按下事件内给区间元素添加鼠标移动事件 并记录每次移动的坐标
  • 在区间元素的鼠标移动事件中 设置对应的拖拽元素的坐标(移动的坐标 = 当前的坐标 - 鼠标点击位置的坐标 + 'px')
  • 在按下事件内在document中添加鼠标弹起事件 并释放之前的移动事件及自身的弹起事件
    <style>
            div {
                width: 100px;
                height: 100px;
                background-color: aquamarine;
                position: absolute;
            }
        </style>
    </head>
    <div></div>
    <script>
        var div = document.querySelector('div')
        div.onmousedown = function(e) {
            e = e || window.event
                // 先获取在div内的点击坐标
            var x = e.offsetX
            var y = e.offsetY
                // 带获取点击在页面的坐标
            document.onmousemove = function(e) {
                e = e || window.event
                var currentX = e.pageX
                var currentY = e.pageY

                div.style.left = currentX - x + 'px'
                div.style.top = currentY - y + 'px'
            }
            div.onmouseup = function(e) {
                document.onmousemove = null
            }
        }
    </script>

区间拖拽 

offset家族(属于元素对象)

  • offsetParent 偏移的父元素 (从里到外找有定位的父元素 没有的话就是body)
  • offsetLeft 左偏移量 (不包含偏移的父元素本身的margin 包含偏移的父元素本身padding、border)
  • offsetTop 上偏移量
  • offsetHeight 偏移元素的高度 (包含padding及border 不包含margin)
  • offsetWidth 偏移元素的宽度

【思路 】

  • 获取拖拽的元素
  • 给拖拽元素添加鼠标按下事件 并记录按下的坐标(在对应的盒子里的坐标)
  • 在按下事件内给区间元素添加鼠标移动事件 并记录每次移动的坐标
  • 在区间元素的鼠标移动事件中 获取对应的区间元素的位置 及 能够移动的距离 (区间元素的宽/高度 - 自身的宽/高度)
  • 设置移动元素处在区间元素的位置
  • 移动位置在父元素的坐标 = 页面的位置 - 父元素离页面的位置- 鼠标点击的位置
  • 对应坐标位置进行区间判断 小于0的时候值应该设置为0 大于能够移动的距离设为最大的距离
  • 在按下事件内在document中添加鼠标弹起事件 并释放之前的移动事件及自身的弹起事件
    <style>
        .box1 {
            width: 300px;
            height: 300px;
            /* position: relative; */
            background-color: palevioletred;
        }
        
        .box2 {
            width: 50px;
            height: 50px;
            position: absolute;
            background-color: peachpuff;
        }
    </style>
    <div class="box1">
        <div class="box2">
        </div>
    </div>
    <script>
        var box1 = document.querySelector('.box1')
        var box2 = document.querySelector('.box2')
        box2.onmousedown = function(e) {
            e = e || window.event
            var x = e.offsetX
            var y = e.offsetY
            box1.onmousemove = function(e) {
                e = e || window.event
                var box1X = this.offsetLeft
                var box1Y = this.offsetTop
                var maxW = this.offsetWidth - box2.offsetWidth
                var maxH = this.offsetHeight - box2.offsetHeight
                var targetX = e.pageX - x - box1X
                var targetY = e.pageY - y - box1Y
                if (targetX > maxW) {
                    targetX = maxW
                }
                if (targetX < 0) {
                    targetX = 0
                }
                if (targetY > maxH) {
                    targetY = maxH
                }
                if (targetY < 0) {
                    targetY = 0
                }
                box2.style.left = e.pageX - x - box1X + 'px'
                box2.style.top = e.pageY - y - box1Y + 'px'
            }
            document.onmouseup = function() {
                box1.onmousemove = document.onmouseup = null
            }
        }
    </script>

 封装一个方法找盒子到页面的距离

function getBoxToPageDistance(element){
    var distance = {
        x:0,
        y:0
    } //距离对象
    while(element.offsetParent){ //找到body就停止
        distance.x += element.offsetLeft
        distance.y += element.offsetTop
        element = element.offsetParent
    }
    return distance
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
明日问题的输入事件与输出事件为: | Input Events | Node Output Event description Node . e0: start program event 1 e7: Welcome message 2 e1: center a valid month 6e8: print today's date 4 e2: enter an invalid month 67| e9: print tomorrow's date 6 e3: enter a valid day 69 e10: "month OK" 39 e4: enter an invalid day 69 e11: "month out of range" 41 e5: enter a valid year 71 e12: "day OK" 4 e6: enter an invalid year 71 e13: "day out of range" 4S e14: "year OK" 54 e15: "year out of range" 5( e16: "Date OK" 6C e17: "please enter a valid date" 62 e18: "enter a month" 6( e19: "enter a day" 68 e20: "enter a year" 70 c21: "Day is month, day, year" 8S 在下表中,ASF-6对应的输入事件为: 输出事件 ASF-7对应的输入事件为: 输出事件 为:_ ASF-8对应的输入事件为:_, 输出事件 为:_ ASF-9对应的输入事件为:_,输 出事件 为:_ Atomic System Function Inputs Outputs L ASF-1 start program e0 e7 | ASF-2 enter a date with an invalid month, valid day and valid year e2, e3,e5 e11,e12,e14,e17 | ASF-3 enter a date with an invalid day, valid month and validyear| e1, c4,e5 e10,e13,e14,e17 | ASE-4 enter a date wih an ivalid year, valid day and valid monh| el,e3, c6 e10,e12, el5,e17| ASF-5 enter a date with valid month, day, and year e1,e3,e5 . e10, e12, e14, e16, c21 | ASIF-6 enter a date with valid month, day and year invalid ASF-7 enter a date with valid day, month and year invalid ASF-8 enter a date with valid year, day and month invalid ASF-9 enter a date with invalid month, day, year
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值