为什么我的 jQuery 单击处理程序就像我单击 parent 元素一样?
Why is my jQuery click handler acting as though I clicked on the parent element?
我在 parent div 中创建了很多 child div。所有div定位,parentdiv是绝对的,childdiv是相对的。 Parentdivz-index是400,childdiv是500。
当我点击任何 child div 然后 jQuery 检测 parent div 与点击功能。我不明白为什么这些代码不起作用。
所以我希望任何人都可以帮助我这种情况。
Parent div ID: "#cardslayer"
Child divs class: ".cardinlayer"
-HTML:
<body>
<div id="cardslayer"></div>
</body>
-CSS:
#cardslayer {
position: absolute;
width: 960px;
height: auto;
top: 0;
left: 0;
z-index: 400;
display: none;
}
.cardinlayer {
width: 100px;
height: 125px;
margin: 10px;
position: relative;
z-index: 500;
display: none;
}
-JQUERY:(css 中的某些样式具有 jquery 功能。)
var hazakstr = "";
var i = 0;
$("#button").click(function(){
hazakstr = "<center>";
for(i=0; i<22; i++) {
if(level_owner[i] == -1) {
hazakstr = hazakstr + "<div class='cardinlayer' id='house" + i + "' style='background: url(../houses/" + i + ".png); background-size: 100px 125px; background-repeat: no-repeat;'></div>";
}
}
hazakstr = hazakstr + "</center>";
$("#cardslayer").css("display", "block");
$("#cardslayer").html(hazakstr);
$(".cardinlayer").css("display", "inline-block");
i=((567 - $("#cardslayer").height()) / 2);
$("#cardslayer").css("height", 567 - i + "px");
$("#cardslayer").css("padding-top", i + "px");
});
在循环结束时将 html 添加到 #cardslayer。代码如下:
HTML:
<div id="cardslayer" style="display: block; height: 507px; padding-top: 60px;">
<center>
<div class="cardinlayer" id="house0" style="background: url("../houses/0.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
<div class="cardinlayer" id="house1" style="background: url("../houses/1.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
.
.
.
.
<div class="cardinlayer" id="house21" style="background: url("../houses/21.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
</center>
</div>
所以毕竟我为.cardinlayer创建了点击功能。而且它不起作用。
$(".cardinlayer").click(function(){
alert("Cardinlayer");
});
我为 .cardinlayer 尝试了这个点击功能
$("div").click(function(){
alert($(this).attr("id"));
});
当我点击一个 .cardinlayer return 值是#cardslayer,而不是#house1 或任何#house。
#cardslayer 是 parent 和 .cardinlayer(s) 是 childs.
问题图片: https://i.imgur.com/DjWcIKK.jpg
红色是 parent,蓝色是 child。
所以当我点击任何卡片时 jquery 都没有被检测到。 Jquery 想我点击了褪色的黑色背景。 (parent).
我希望有人能帮助我。
祝你有愉快的一天,谢谢。
click
事件有修饰符,例如 stopPropagation
或 preventDefault
。 (更多信息:Event on MDN)
查看实际效果:
let hazakstr = "";
const cardHtml = ({ i }) => {
return `
<div
id="house${i}"
class="cardinlayer"
data-idx="${i}"
>
HOUSE ${i}
</div>
`
}
jQuery("#button").on('click', function() {
for (let i = 0; i < 22; i++) {
hazakstr += cardHtml({ i })
}
$("#cardslayer").html(hazakstr);
});
jQuery("#cardslayer").on('click', '.cardinlayer', function(e) {
e.stopPropagation() // this stops the event from propagation
const { idx } = $(this).data()
alert(`Clicked house card: ${idx}`)
})
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button">CLICK</button>
<div class="container">
<div id="cardslayer"></div>
</div>
编辑/建议:
我建议您尽可能不要乱用 jQuery
。 Vue
:
中有一些更新
Vue.component('HouseCard', {
props: ['idx'],
methods: {
onClick({ idx }) {
alert(`Clicked house: ${ idx }`)
},
},
template: `
<div
class="cardinlayer"
@click.stop="() => onClick({ idx })"
>
HOUSE {{ idx }}
</div>
`
})
new Vue({
el: "#app",
data() {
return {
houses: [],
}
},
methods: {
addHouse(houses) {
return [...houses, houses.length]
},
add1House() {
this.houses = this.addHouse(this.houses)
},
add22Houses() {
let ret = this.houses
for (let i = 0; i < 22; i++) {
ret = this.addHouse(ret)
}
this.houses = ret
}
},
template: `
<div>
<button @click="add1House">ADD 1 HOUSE</button>
<button @click="add22Houses">ADD 22 HOUSES</button>
<br />
<div
class="container"
>
<div
id="cardslayer"
>
<house-card
v-for="(house, idx) in houses"
:key="idx"
:idx="idx"
></house-card>
</div>
</div>
</div>
`
})
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
或React
解决方案:
const { useState } = React
const HouseCard = ({ idx }) => {
const handleClick = () => {
alert(`House clicked: ${idx}`)
}
return (
<div class="cardinlayer" onClick={handleClick}>
HOUSE { idx }
</div>
)
}
const App = () => {
const [houses, setHouses] = useState([])
const addHouse = (houses) => [...houses, houses.length]
const add1House = () => setHouses((prev) => addHouse(prev))
const add22Houses = () => {
for(let i = 0; i < 22; i++) {
setHouses((prev) => addHouse(prev))
}
}
return (
<div>
<button onClick={add1House}>ADD 1 HOUSE</button>
<button onClick={add22Houses}>ADD 22 HOUSES</button>
<div class="container">
<div id="cardslayer">
{
houses.map((_, idx) => <HouseCard idx={idx} />)
}
</div>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>
我在 parent div 中创建了很多 child div。所有div定位,parentdiv是绝对的,childdiv是相对的。 Parentdivz-index是400,childdiv是500。
当我点击任何 child div 然后 jQuery 检测 parent div 与点击功能。我不明白为什么这些代码不起作用。
所以我希望任何人都可以帮助我这种情况。
Parent div ID: "#cardslayer"
Child divs class: ".cardinlayer"
-HTML:
<body>
<div id="cardslayer"></div>
</body>
-CSS:
#cardslayer {
position: absolute;
width: 960px;
height: auto;
top: 0;
left: 0;
z-index: 400;
display: none;
}
.cardinlayer {
width: 100px;
height: 125px;
margin: 10px;
position: relative;
z-index: 500;
display: none;
}
-JQUERY:(css 中的某些样式具有 jquery 功能。)
var hazakstr = "";
var i = 0;
$("#button").click(function(){
hazakstr = "<center>";
for(i=0; i<22; i++) {
if(level_owner[i] == -1) {
hazakstr = hazakstr + "<div class='cardinlayer' id='house" + i + "' style='background: url(../houses/" + i + ".png); background-size: 100px 125px; background-repeat: no-repeat;'></div>";
}
}
hazakstr = hazakstr + "</center>";
$("#cardslayer").css("display", "block");
$("#cardslayer").html(hazakstr);
$(".cardinlayer").css("display", "inline-block");
i=((567 - $("#cardslayer").height()) / 2);
$("#cardslayer").css("height", 567 - i + "px");
$("#cardslayer").css("padding-top", i + "px");
});
在循环结束时将 html 添加到 #cardslayer。代码如下:
HTML:
<div id="cardslayer" style="display: block; height: 507px; padding-top: 60px;">
<center>
<div class="cardinlayer" id="house0" style="background: url("../houses/0.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
<div class="cardinlayer" id="house1" style="background: url("../houses/1.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
.
.
.
.
<div class="cardinlayer" id="house21" style="background: url("../houses/21.png") 0% 0% / 100px 125px no-repeat; display: inline-block;"></div>
</center>
</div>
所以毕竟我为.cardinlayer创建了点击功能。而且它不起作用。
$(".cardinlayer").click(function(){
alert("Cardinlayer");
});
我为 .cardinlayer 尝试了这个点击功能
$("div").click(function(){
alert($(this).attr("id"));
});
当我点击一个 .cardinlayer return 值是#cardslayer,而不是#house1 或任何#house。
#cardslayer 是 parent 和 .cardinlayer(s) 是 childs.
问题图片: https://i.imgur.com/DjWcIKK.jpg
红色是 parent,蓝色是 child。 所以当我点击任何卡片时 jquery 都没有被检测到。 Jquery 想我点击了褪色的黑色背景。 (parent).
我希望有人能帮助我。 祝你有愉快的一天,谢谢。
click
事件有修饰符,例如 stopPropagation
或 preventDefault
。 (更多信息:Event on MDN)
查看实际效果:
let hazakstr = "";
const cardHtml = ({ i }) => {
return `
<div
id="house${i}"
class="cardinlayer"
data-idx="${i}"
>
HOUSE ${i}
</div>
`
}
jQuery("#button").on('click', function() {
for (let i = 0; i < 22; i++) {
hazakstr += cardHtml({ i })
}
$("#cardslayer").html(hazakstr);
});
jQuery("#cardslayer").on('click', '.cardinlayer', function(e) {
e.stopPropagation() // this stops the event from propagation
const { idx } = $(this).data()
alert(`Clicked house card: ${idx}`)
})
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button">CLICK</button>
<div class="container">
<div id="cardslayer"></div>
</div>
编辑/建议:
我建议您尽可能不要乱用 jQuery
。 Vue
:
Vue.component('HouseCard', {
props: ['idx'],
methods: {
onClick({ idx }) {
alert(`Clicked house: ${ idx }`)
},
},
template: `
<div
class="cardinlayer"
@click.stop="() => onClick({ idx })"
>
HOUSE {{ idx }}
</div>
`
})
new Vue({
el: "#app",
data() {
return {
houses: [],
}
},
methods: {
addHouse(houses) {
return [...houses, houses.length]
},
add1House() {
this.houses = this.addHouse(this.houses)
},
add22Houses() {
let ret = this.houses
for (let i = 0; i < 22; i++) {
ret = this.addHouse(ret)
}
this.houses = ret
}
},
template: `
<div>
<button @click="add1House">ADD 1 HOUSE</button>
<button @click="add22Houses">ADD 22 HOUSES</button>
<br />
<div
class="container"
>
<div
id="cardslayer"
>
<house-card
v-for="(house, idx) in houses"
:key="idx"
:idx="idx"
></house-card>
</div>
</div>
</div>
`
})
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
或React
解决方案:
const { useState } = React
const HouseCard = ({ idx }) => {
const handleClick = () => {
alert(`House clicked: ${idx}`)
}
return (
<div class="cardinlayer" onClick={handleClick}>
HOUSE { idx }
</div>
)
}
const App = () => {
const [houses, setHouses] = useState([])
const addHouse = (houses) => [...houses, houses.length]
const add1House = () => setHouses((prev) => addHouse(prev))
const add22Houses = () => {
for(let i = 0; i < 22; i++) {
setHouses((prev) => addHouse(prev))
}
}
return (
<div>
<button onClick={add1House}>ADD 1 HOUSE</button>
<button onClick={add22Houses}>ADD 22 HOUSES</button>
<div class="container">
<div id="cardslayer">
{
houses.map((_, idx) => <HouseCard idx={idx} />)
}
</div>
</div>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.container {
position: relative;
}
#cardslayer {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.cardinlayer {
display: flex;
justify-content: center;
align-items: center;
height: 125px;
padding: 8px 16px;
background-color: rgba(255, 0, 0, 0.3);
-webkit-transition: background-color 0.25s ease-out;
-moz-transition: background-color 0.25s ease-out;
-o-transition: background-color 0.25s ease-out;
transition: background-color 0.25s ease-out;
cursor: pointer;
}
.cardinlayer:hover {
background-color: rgba(255, 0, 0, 0.9)
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>