Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 事件捕获与冒泡 #4

Open
meahu opened this issue Apr 27, 2019 · 6 comments
Open

JS 事件捕获与冒泡 #4

meahu opened this issue Apr 27, 2019 · 6 comments

Comments

@meahu
Copy link
Owner

meahu commented Apr 27, 2019

No description provided.

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

事件传播先后顺序:先捕获再冒泡

<body>
    <div>
        <p>我是p</p>
    </div>
</body>

var body = document.body;
var div  = body.querySelector('div');
var p = body.querySelector('p');

// 捕获事件
p.addEventListener('click', capture, true);
div.addEventListener('click', capture, true);
body.addEventListener('click', capture, true);

// 冒泡事件
p.addEventListener('click', bubble, false);
div.addEventListener('click', bubble, false);
body.addEventListener('click', bubble, false);

function bubble(event){
    var target = event.currentTarget;
    console.log('bubble: ' + target.tagName);
}

function capture(event){
    var target = event.currentTarget;
    console.log('capture: ' + target.tagName);
}

// 结果:
capture: BODY
capture: DIV
capture: P
bubble: P
bubble: DIV
bubble: BODY

结果表明是:事件传播先后顺序:先捕获再冒泡。
完整过程是:先捕获:document -> body -> div -> p,再冒泡:p -> div -> body -> document
说人话:石头扔进湖泊,是石头先进湖里还是现有涟漪?当然是石头先进湖里,湖泊先捕获到石头进来了,引起了涟漪(冒泡)。

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

stopPropagation 阻止事件传播

<body>
    <div>
        <p>我是p</p>
    </div>
</body>

var body = document.body;
var div  = body.querySelector('div');
var p = body.querySelector('p');

// 捕获事件
p.addEventListener('click', capture, true);
div.addEventListener('click', captureDiv, true); // stopPropagation
body.addEventListener('click', capture, true);
html.addEventListener('click', capture, true);

// 冒泡事件
p.addEventListener('click', bubble, false);
div.addEventListener('click', bubble, false);
body.addEventListener('click', bubble, false);
html.addEventListener('click', bubble, false);



function bubble(event){
    var target = event.currentTarget;
    console.log('bubble: ' + target.tagName);
}

function capture(event){
    var target = event.currentTarget;
    console.log('capture: ' + target.tagName);
}

function captureDiv(event){
    var target = event.currentTarget;
    event.stopPropagation();
    console.log('capture - div: ' + target.tagName);
}

// 结果:
capture: HTML
capture: BODY
capture - div: DIV

结果表明:stopPropagation 会阻止接下去的捕获和冒泡

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

目标元素的事件,谁先定义谁先执行

<body>
    <div>
        <p>我是p</p>
    </div>
</body>

// 冒泡事件
p.addEventListener('click', bubble, false);
// 捕获事件
p.addEventListener('click', capture, true);

或:
// 捕获事件
// p.addEventListener('click', capture, true);
// 冒泡事件
// p.addEventListener('click', bubble, false);

function bubble(event){
    var target = event.currentTarget;
    console.log('bubble: ' + target.tagName);
}

function capture(event){
    var target = event.currentTarget;
    console.log('capture: ' + target.tagName);
}

// 结果:
bubble: P
capture: P
或:
capture: P
bubble: P

结果表明:目标元素的事件,谁先定义谁先执行

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

但是目标元素有子元素的时候,点击子元素仍然是先触发捕获事件,再触发冒泡事件

<body>
    <div>
        <p>
            我是p
            <span>,span</span>
        </p>
    </div>
</body>

// 冒泡事件
p.addEventListener('click', bubble, false);
// 捕获事件
p.addEventListener('click', capture, true);

function bubble(event){
    var target = event.currentTarget;
    console.log('bubble: ' + target.tagName);
}

function capture(event){
    var target = event.currentTarget;
    console.log('capture: ' + target.tagName);
}

// 结果:
// 点击 span 元素:
capture: P
bubble: P
// 点击『我是p』:
bubble: P
capture: P

结果表明:目标元素有子元素的时候,点击子元素是先触发捕获事件,再触发冒泡事件

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

@meahu
Copy link
Owner Author

meahu commented Apr 27, 2019

补充:IE 的阻止捕获和冒泡事件是window.event.cancelBubble,封装一下:

function stopPropagation (e) {
    if (e.stopPropagation) {
        e.stopPropagation()
    } else {
        window.event.cancelBubble = true
    }
}

@meahu meahu changed the title JS 事件总结 JS 事件捕获与冒泡 Apr 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant