删除后重新添加事件侦听器--Javascript
Re-add event listeners after removing--Javascript
<style type="text/css">
.hilite {
color:green;
font-size: 1.5em;
font-weight:bold;
}
.autosize {width: auto; height: auto;}
ul {background-color: lightblue; height: 24px;}
li {background-color: pink; width: 300px; height: 24px; font-weight: bold; font-size: 1.5em;}
</style>
该网页突出显示了文本,用户将鼠标悬停在该文本上可获得定义某些术语的工具提示。那部分有效,我学会了如何使用事件委托来实现它,它重新使用事件监听器,所以我只需要每种监听器中的一个。
我正在尝试使用无线电输入让用户选择是使用鼠标悬停还是单击。我已经用按钮试过了,但收音机似乎更适合。当用户单击悬停时,他会通过将鼠标悬停在上方来获得工具提示。当用户点击 Click 时,他通过点击获得工具提示。我一直在寻找控制这种选择的方法,但无法理解如何使用自定义数据属性 https://toddmotto.com/stop-toggling-classes-with-js-use-behaviour-driven-dom-manipulation-with-data-states/'>(我没有第一条线索)的解释,所以我决定我应该首先学习如何通过删除事件侦听器来实现它,这应该很容易,对吧?
当我不得不将其全部拆除以使用 removeEventListeners 时,我将我的添加事件侦听器作为方法很好地搁置在对象中,因为方法值是匿名函数。这只是为了组织,但它有一个额外的好处,那就是让它自然地远离全球范围。这将一切都置于全球范围内,但我真正的问题比这更糟。
真正的问题:代码可以在使用鼠标悬停时删除点击,或在使用单击时删除鼠标悬停,但是一旦我删除了一种事件类型,单选按钮就不会重新打开它。显然我需要一种不同的方式来重新添加事件侦听器,但我不知道为什么或如何。我不知道为什么这行不通,这看起来很简单,而且我还没有找到任何其他人发生这种情况的例子。这很重要,因为我计划将其调整为适用于触摸屏用户的媒体查询,因为他们不能使用悬停,但如果用户有鼠标,我更喜欢默认的鼠标悬停。
<div id='tooltipAncestorOff'>
<div id='tooltipAncestorClick'>
<div id='tooltipAncestorHover'>
<p class='autosize'>Just <span class='hilite' id="onez">FIRST hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="twoz">SECOND hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="threez">THIRD hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fourz">FOURTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fivez">FIFTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="sixz">SIXTH hilite</span></p>
</div> </div> </div>
<ul>
<li id='toolTip'>placeholder... solve: why do I need text here?</li>
</ul>
<form name="chooseTooltips">
<input type="radio" name="tooltips" value="hover" onclick = 'onHoverButton()' checked> HOVER TOOLTIPS</br>
<input type="radio" name="tooltips" value="click" onclick = 'onClickButton()'> CLICK TOOLTIPS</br>
<input type="radio" name="tooltips" value="none" onclick = 'offBothButtons()'> NO TOOLTIPS</br>
</form>
<script>
var what = {
onez: 'FIRST definition',
twoz: 'SECOND definition',
threez: 'THIRD definition',
fourz: 'FOURTH definition',
fivez: 'FIFTH definition',
sixz: 'SIXTH definition'
};
var how = {
showHide: function (stile){
var displ = document.getElementById('toolTip');
displ.style.display = stile;
}
};
//most of the script below was in an object but I had to move it to global scope when using removeEventListener
var clickFunx = function(evt) {
var clicked = evt.target.id;
toolTip.firstChild.textContent = (what[clicked]);
how.showHide('block');
console.log('clicked');
};
var findClickParent = document.getElementById('tooltipAncestorClick');
findClickParent.addEventListener('click', clickFunx, false);
function removeHoverFunx() {
findHoverParent.removeEventListener('mouseover', hoverFunx, false);
}
var hoverFunx = function(evt) {
var mousedOver = evt.target.id;
toolTip.firstChild.textContent = (what[mousedOver]);
how.showHide('block');
console.log('moused over');
};
var findHoverParent = document.getElementById('tooltipAncestorHover');
findHoverParent.addEventListener('mouseover', hoverFunx, false);
function removeClickFunx() {
findClickParent.removeEventListener('click', clickFunx, false);
};
function hiliteOut() {
var findOutParent = document.getElementById('tooltipAncestorHover');
findOutParent.addEventListener('mouseout', function() {
how.showHide('none');
console.log('moused out');
}, false);
};
/********radio controls**********/
function onHoverButton() {
hoverFunx;
hiliteOut();
removeClickFunx();
};
function onClickButton() {
clickFunx;
hiliteOut();
removeHoverFunx();
};
function offBothButtons() {
removeHoverFunx();
removeClickFunx();
}
</script>
而不是每次 adding/removing 事件 - 我注册了两个事件 (hover/click) 并且我只 运行 基于单选框当前值的相关功能:
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'click') {
return;
}
这是对您的代码的修复:
var what = {
onez: 'FIRST definition',
twoz: 'SECOND definition',
threez: 'THIRD definition',
fourz: 'FOURTH definition',
fivez: 'FIFTH definition',
sixz: 'SIXTH definition'
};
var how = {
showHide: function (stile){
var displ = document.getElementById('toolTip');
displ.style.display = stile;
}
};
//most of the script below was in an object but I had to move it to global scope when using removeEventListener
var clickFunx = function(evt) {
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'click') {
return;
}
var clicked = evt.target.id;
toolTip.firstChild.textContent = (what[clicked]);
how.showHide('block');
//console.log('clicked');
};
var findClickParent = document.getElementById('tooltipAncestorClick');
findClickParent.addEventListener('click', clickFunx, false);
function removeHoverFunx() {
findHoverParent.removeEventListener('mouseover', hoverFunx, false);
}
var hoverFunx = function(evt) {
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'hover') {
return;
}
var mousedOver = evt.target.id;
toolTip.firstChild.textContent = (what[mousedOver]);
how.showHide('block');
//console.log('moused over');
};
var findHoverParent = document.getElementById('tooltipAncestorHover');
findHoverParent.addEventListener('mouseover', hoverFunx, false);
function removeClickFunx() {
findClickParent.removeEventListener('click', clickFunx, false);
};
function hiliteOut() {
var findOutParent = document.getElementById('tooltipAncestorHover');
findOutParent.addEventListener('mouseout', function() {
how.showHide('none');
//console.log('moused out');
}, false);
};
.hilite {
color:green;
font-size: 1.5em;
font-weight:bold;
}
.autosize {width: auto; height: auto;}
ul {background-color: lightblue; height: 24px;}
li {background-color: pink; width: 300px; height: 24px; font-weight: bold; font-size: 1.5em;}
<div id='tooltipAncestorOff'>
<div id='tooltipAncestorClick'>
<div id='tooltipAncestorHover'>
<p class='autosize'>Just <span class='hilite' id="onez">FIRST hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="twoz">SECOND hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="threez">THIRD hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fourz">FOURTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fivez">FIFTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="sixz">SIXTH hilite</span></p>
</div> </div> </div>
<ul>
<li id='toolTip'>placeholder... solve: why do I need text here?</li>
</ul>
<form name="chooseTooltips">
<input type="radio" name="tooltips" value="hover" checked> HOVER TOOLTIPS<br />
<input type="radio" name="tooltips" value="click"> CLICK TOOLTIPS<br />
<input type="radio" name="tooltips" value="none"> NO TOOLTIPS<br />
</form>
<style type="text/css">
.hilite {
color:green;
font-size: 1.5em;
font-weight:bold;
}
.autosize {width: auto; height: auto;}
ul {background-color: lightblue; height: 24px;}
li {background-color: pink; width: 300px; height: 24px; font-weight: bold; font-size: 1.5em;}
</style>
该网页突出显示了文本,用户将鼠标悬停在该文本上可获得定义某些术语的工具提示。那部分有效,我学会了如何使用事件委托来实现它,它重新使用事件监听器,所以我只需要每种监听器中的一个。
我正在尝试使用无线电输入让用户选择是使用鼠标悬停还是单击。我已经用按钮试过了,但收音机似乎更适合。当用户单击悬停时,他会通过将鼠标悬停在上方来获得工具提示。当用户点击 Click 时,他通过点击获得工具提示。我一直在寻找控制这种选择的方法,但无法理解如何使用自定义数据属性 https://toddmotto.com/stop-toggling-classes-with-js-use-behaviour-driven-dom-manipulation-with-data-states/'>(我没有第一条线索)的解释,所以我决定我应该首先学习如何通过删除事件侦听器来实现它,这应该很容易,对吧?
当我不得不将其全部拆除以使用 removeEventListeners 时,我将我的添加事件侦听器作为方法很好地搁置在对象中,因为方法值是匿名函数。这只是为了组织,但它有一个额外的好处,那就是让它自然地远离全球范围。这将一切都置于全球范围内,但我真正的问题比这更糟。
真正的问题:代码可以在使用鼠标悬停时删除点击,或在使用单击时删除鼠标悬停,但是一旦我删除了一种事件类型,单选按钮就不会重新打开它。显然我需要一种不同的方式来重新添加事件侦听器,但我不知道为什么或如何。我不知道为什么这行不通,这看起来很简单,而且我还没有找到任何其他人发生这种情况的例子。这很重要,因为我计划将其调整为适用于触摸屏用户的媒体查询,因为他们不能使用悬停,但如果用户有鼠标,我更喜欢默认的鼠标悬停。
<div id='tooltipAncestorOff'>
<div id='tooltipAncestorClick'>
<div id='tooltipAncestorHover'>
<p class='autosize'>Just <span class='hilite' id="onez">FIRST hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="twoz">SECOND hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="threez">THIRD hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fourz">FOURTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fivez">FIFTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="sixz">SIXTH hilite</span></p>
</div> </div> </div>
<ul>
<li id='toolTip'>placeholder... solve: why do I need text here?</li>
</ul>
<form name="chooseTooltips">
<input type="radio" name="tooltips" value="hover" onclick = 'onHoverButton()' checked> HOVER TOOLTIPS</br>
<input type="radio" name="tooltips" value="click" onclick = 'onClickButton()'> CLICK TOOLTIPS</br>
<input type="radio" name="tooltips" value="none" onclick = 'offBothButtons()'> NO TOOLTIPS</br>
</form>
<script>
var what = {
onez: 'FIRST definition',
twoz: 'SECOND definition',
threez: 'THIRD definition',
fourz: 'FOURTH definition',
fivez: 'FIFTH definition',
sixz: 'SIXTH definition'
};
var how = {
showHide: function (stile){
var displ = document.getElementById('toolTip');
displ.style.display = stile;
}
};
//most of the script below was in an object but I had to move it to global scope when using removeEventListener
var clickFunx = function(evt) {
var clicked = evt.target.id;
toolTip.firstChild.textContent = (what[clicked]);
how.showHide('block');
console.log('clicked');
};
var findClickParent = document.getElementById('tooltipAncestorClick');
findClickParent.addEventListener('click', clickFunx, false);
function removeHoverFunx() {
findHoverParent.removeEventListener('mouseover', hoverFunx, false);
}
var hoverFunx = function(evt) {
var mousedOver = evt.target.id;
toolTip.firstChild.textContent = (what[mousedOver]);
how.showHide('block');
console.log('moused over');
};
var findHoverParent = document.getElementById('tooltipAncestorHover');
findHoverParent.addEventListener('mouseover', hoverFunx, false);
function removeClickFunx() {
findClickParent.removeEventListener('click', clickFunx, false);
};
function hiliteOut() {
var findOutParent = document.getElementById('tooltipAncestorHover');
findOutParent.addEventListener('mouseout', function() {
how.showHide('none');
console.log('moused out');
}, false);
};
/********radio controls**********/
function onHoverButton() {
hoverFunx;
hiliteOut();
removeClickFunx();
};
function onClickButton() {
clickFunx;
hiliteOut();
removeHoverFunx();
};
function offBothButtons() {
removeHoverFunx();
removeClickFunx();
}
</script>
而不是每次 adding/removing 事件 - 我注册了两个事件 (hover/click) 并且我只 运行 基于单选框当前值的相关功能:
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'click') {
return;
}
这是对您的代码的修复:
var what = {
onez: 'FIRST definition',
twoz: 'SECOND definition',
threez: 'THIRD definition',
fourz: 'FOURTH definition',
fivez: 'FIFTH definition',
sixz: 'SIXTH definition'
};
var how = {
showHide: function (stile){
var displ = document.getElementById('toolTip');
displ.style.display = stile;
}
};
//most of the script below was in an object but I had to move it to global scope when using removeEventListener
var clickFunx = function(evt) {
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'click') {
return;
}
var clicked = evt.target.id;
toolTip.firstChild.textContent = (what[clicked]);
how.showHide('block');
//console.log('clicked');
};
var findClickParent = document.getElementById('tooltipAncestorClick');
findClickParent.addEventListener('click', clickFunx, false);
function removeHoverFunx() {
findHoverParent.removeEventListener('mouseover', hoverFunx, false);
}
var hoverFunx = function(evt) {
if (document.querySelector('[name="tooltips"]:checked').getAttribute('value') != 'hover') {
return;
}
var mousedOver = evt.target.id;
toolTip.firstChild.textContent = (what[mousedOver]);
how.showHide('block');
//console.log('moused over');
};
var findHoverParent = document.getElementById('tooltipAncestorHover');
findHoverParent.addEventListener('mouseover', hoverFunx, false);
function removeClickFunx() {
findClickParent.removeEventListener('click', clickFunx, false);
};
function hiliteOut() {
var findOutParent = document.getElementById('tooltipAncestorHover');
findOutParent.addEventListener('mouseout', function() {
how.showHide('none');
//console.log('moused out');
}, false);
};
.hilite {
color:green;
font-size: 1.5em;
font-weight:bold;
}
.autosize {width: auto; height: auto;}
ul {background-color: lightblue; height: 24px;}
li {background-color: pink; width: 300px; height: 24px; font-weight: bold; font-size: 1.5em;}
<div id='tooltipAncestorOff'>
<div id='tooltipAncestorClick'>
<div id='tooltipAncestorHover'>
<p class='autosize'>Just <span class='hilite' id="onez">FIRST hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="twoz">SECOND hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="threez">THIRD hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fourz">FOURTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="fivez">FIFTH hilite</span></p>
<p class='autosize'>Only <span class='hilite' id="sixz">SIXTH hilite</span></p>
</div> </div> </div>
<ul>
<li id='toolTip'>placeholder... solve: why do I need text here?</li>
</ul>
<form name="chooseTooltips">
<input type="radio" name="tooltips" value="hover" checked> HOVER TOOLTIPS<br />
<input type="radio" name="tooltips" value="click"> CLICK TOOLTIPS<br />
<input type="radio" name="tooltips" value="none"> NO TOOLTIPS<br />
</form>