【问题标题】:Correct way to target button elements inside jquery element?在jquery元素中定位按钮元素的正确方法?
【发布时间】:2016-08-17 20:51:32
【问题描述】:

我有 jQuery 元素 popupbuttonsbuttonspopup 的子元素。


buttons 包含<button> 元素,我想将点击事件附加到这些元素。

所以我编写了以下代码:

buttons.children("button").on("click", function() {
    //I'm magic
}

但遗憾的是buttons的内容可以动态更改,按钮可以添加和删除:/

所以我通过写作解决了这个问题:

buttons.on("click", "button", function() {
    //I'm magic
}

buttons 本身可以从popup 中添加和删除。在buttons 被删除并添加回popup 之后,上面的代码不再起作用:/

下面的代码似乎可以解决它:

popup.on("click", "button", function() {
    //I'm magic
}

但这也会在点击 <button> 内的 popup 但不在 buttons 内时触发。

如何仅当<button>buttons 内被点击时触发?

感谢您的帮助!

【问题讨论】:

  • 无法阅读。请发布一个简单的 MCVE。
  • 张贴您的 html 以便我们检查
  • 请提供您目前拥有的html/js。谢谢
  • 不需要任何html、js。这是一个关于 jquery 中事件委托的明确问题。如果它很复杂,请继续前进。
  • 但是最好有 html 以便我们在定义事件委托时可以使用适当的选择器

标签: javascript jquery html event-delegation


【解决方案1】:

为所有buttons 元素指定一个类,并在委托中引用该类。

popup.on("click", ".buttons button", function() {
    ...
});

好的,以下是您可以在不添加类的情况下执行此操作的方法:

popup.on("click", "button", function() {
    var clickedButton = this;
    buttons.each(function(i, aButton) {
        if ($.contains(aButton, clickedButton)) {
            // I'm magic
            return false; // stop looping
        }
    });
});

这使用委托来触发popup 中的任何按钮。然后当代码被触发时,它会搜索所有buttons 以查看此按钮是否在其中一个内。如果是这样,它会执行你想要的代码,并跳出循环。

【讨论】:

  • 另一种解决方案是每次更新buttons时重做委托,这似乎更难。
  • 为什么这不是一个真正的解决方案?我们正在告诉您如何使用 jQuery 委托。这取决于以特定方式构建的 HTML。
  • 我不是在问事件委托是如何工作的……而且我们不是在谈论 html 元素,而是在谈论 jquery 对象……
  • jQuery 对象代表 DOM 元素。
  • O.o jQuery 对象表示 dom 元素和唯一的 jquery 属性,例如唯一的 jquery id 等。无论如何,您的代码在buttons 方面似乎更好,因为它记住buttons 可以也是元素的集合,而不是一个。
【解决方案2】:

在执行 onclick 处理程序之前尝试检查父类:

popup.on("click", "button", function() {  
    if ( $(this).parent().hasClass('buttons') ) {
        //I'm magic
    }
}

【讨论】:

  • 它仍然将 onclick 事件附加到 popup 内的所有 <button> 元素。此外,您的代码需要添加一个不必要的类,这绝不是一个好主意......
【解决方案3】:

我后来想出了一个部分解决方案,但看起来有点混乱,因为它仍然将点击事件附加到 popup 内的所有 <button> 元素。

popup.on("click", "button", function() {  
    if($.contains(buttons[0], $(this)[0])) {
        //I'm magic
    }
}

完全符合我要求但不起作用的代码是:

popup.on("click", buttons.find("button"), function() {  
    //I'm magic
}

【讨论】:

  • buttons 是什么?
  • @NikolayErmakov 这是 OP 脚本中的一个变量。
  • 此解决方案仅适用于buttons 中的第一个按钮。
  • 完全正确!!! this code requires adding a unnecessary "buttons" which is never a good idea 我们不知道那个按钮是什么.. 我知道它是一个 OP 的变量.. 但是什么?哈哈哈:)
  • @Barmar Right )) 谢谢!
【解决方案4】:

据我了解。这是一个解决方案。将buttons ("#buttons button") 内的button 的点击事件委托给弹出窗口。我在小提琴中使用了 id 。你可能在那里上课。

$('#popup').on("click","#buttons button", function(){
  alert('click');
})

fiddle

【讨论】:

  • 此代码需要将 id 添加到我的元素中,这不是问题的真正解决方案。
  • @seahorsepip 你在开玩笑吧!!!!这就是我们要求您提供 HTML 的原因...:).. 所以我们确切地知道您那里有什么。
  • html可以是任何东西,这不是html问题而是jquery元素问题。当附加点击事件时,jquery 元素甚至可能不在 dom 中。
  • @seahorsepip 关键是委托要求您将事件附加到静态元素,然后提供与您要触发的元素匹配的选择器。这意味着你需要设计你的类来匹配你想做的事情。
  • @seahorsepip 如果它不是一个 html 问题,那么为什么在你的 html 中添加一个 ids 或类(来自其他答案)对你很重要。您知道解决方案是点击委托 + 最好的部分,您将问题标记为 HTML... ;) :)
【解决方案5】:

我根据您的描述重建了应用程序,在我看来它可以工作。

我使用 div 作为元素,但你明白了。

快速简介:按下任意按钮,将触发点击事件(隐藏/显示消息)。当你按下“Remove”时,“buttons” div 将被移除并附加到“popup”中,因此它上面不会留下任何事件,因此我们需要再次添加事件。这不是最佳做法,但可以完成工作。

我希望这会有所帮助并且我回答了你的问题。

// When Buttons Div is clicked, the message is hidden / shown
$("#buttons").on("click", function() {
    if($("#txt").is(":visible")){
			$("#txt").hide();
		}
		else{
			$("#txt").show();
		}
});

// When the Remove Button is pressed, "Buttons" will be deleted and appended to Popup
$("#modify").on("click", function(){
		$("#buttons").remove();
		
		// Ignore this... this is the code which can be placed in a function
		$("#popup" ).append('<div id="buttons"><FORM><SELECT name="element"><OPTION value="button">Button</OPTION></SELECT><INPUT type="button" value="Add" onclick="add(document.forms[0].element.value)"/><span id="fooBar">&nbsp;</span></FORM><button type="button">Switch Magic 1</button><button type="button">Switch Magic 2</button><button type="button">Switch Magic 3</button><button type="button">Switch Magic 4</button></div>' );
		
		
		$("#buttons").on("click", function() {
    if($("#txt").is(":visible")){
			$("#txt").hide();
		}
		else{
			$("#txt").show();
			$("#buttons").remove();
		}
	});
});

function add(type) {

	//Create an input type dynamically.
	var element = document.createElement("input");

	//Assign different attributes to the element.
	element.setAttribute("type", type);
	element.setAttribute("value", type);
	element.setAttribute("name", type);


	var foo = document.getElementById("fooBar");

	//Append the element in page (in span).
	foo.appendChild(element);

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<SCRIPT language="javascript">
function add(type) {

	//Create an input type dynamically.
	var element = document.createElement("input");

	//Assign different attributes to the element.
	element.setAttribute("type", type);
	element.setAttribute("value", type);
	element.setAttribute("name", type);


	var foo = document.getElementById("fooBar");

	//Append the element in page (in span).
	foo.appendChild(element);

}
</SCRIPT>
<div id="popup">
<button id="modify" type="button">
Remove
</button>
<div id="buttons">
<FORM>
<SELECT name="element">
	<OPTION value="button">Button</OPTION>
</SELECT>
<INPUT type="button" value="Add" onclick="add(document.forms[0].element.value)"/>
<span id="fooBar">&nbsp;</span>
</FORM>
<button type="button">
Switch Magic 1
</button>
<button type="button">
Switch Magic 2
</button>
<button type="button">
Switch Magic 3
</button>
<button type="button">
Switch Magic 4
</button>
</div>
</div>
<label id="txt">I'm magic!</label>

【讨论】:

  • 我经常从其他人的演示中理解得更好。我解释了解决方案,因此我相信它已经足够好了。不需要仇恨。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-10
相关资源
最近更新 更多