This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 9 years ago.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Button - Icons</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<style>
#s
{
width:200px;
}
#div1
{
min-width:100px;
width:auto;
float:left;
border:2px solid black;
min-height:100px;
height:auto;
background-color:red;
}
</style>
<script>
$(document).ready(function(){
$("div").click(function(){
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
});
$("#s").click(function(){
alert("sljsdf");
});
});
</script>
</head>
<body>
<div id="div1">
VOLVO B9R
</div>
</body>
</html>
Here when i click on the first div, the program creates another div. the newly created div is not responding to on click event. in the current code i have specified that the newly created div should give an alert on click but its not working.
Thanks!
You need event degation for dynamically added elements. The time the binding code for element with id s is executed the element does not exists in DOM
$(document).on("click", "#s", function(){
alert("sljsdf");
});
Delegated events
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers, jQuery doc.
When your dom ready handler is executed the #s div does not exists in the dom, so the click handler will not get added to the element. You can use event delegation to fix this problem
$(document).on('click', "#s", function () {
alert("sljsdf");
});
Demo: Fiddle
try something like this
$("body").on('click','#s',function(){
alert("sljsdf");
});
REFERENCE
http://api.jquery.com/on/
Since the #s element are created dynamically you need to use event delegation to register event handlers to these elements.
When you use $('#s').click(....); to register an event handler it will register the handle to only those elements which are already present in the dom at the time of the code execution, in you case since these elements are created after that the handlers will not get attached to the newly created elements
Try this
$(document).ready(function(){
$(document).on('click',"div",function(){
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
});
$(document).on("click", "#s", function(){
alert("sljsdf");
});
});
DEMO
Please see this LINK
OR
Try below code...
Your HTML ....
<div id="div1"> VOLVO B9R </div>
Your JQuery Code....
$(document).ready(function () {
$("div").click(function () {
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
$("#s").bind('click', function () {
alert("sljsdf");
});
});
});
Your CSS....
#s
{
width:200px;
float:right;
}
#div1
{
min-width:100px;
width:auto;
float:left;
border:2px solid black;
min-height:100px;
height:auto;
background-color:red;
}
Use below code..
$(document).ready(function () {
$("div").click(function () {
$(this).after($('<div id="s" style="background-color:blue; clear:both">NLC TRANSPORT</div>'));
$("#s").bind("click", function () {
alert("sljsdf");
});
});
});
Good luck.
The following jQuery lines of code will help you..
$(document).ready(function(){
$('body').on('click','#div1',function(){
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
$('#s').click(function(){
alert('a');
})
})
});
You can't add an event handler to an element that doesn't exist yet:
$(document).ready(function () {
$("div").click(function () {
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
$("#s").click(function () {
alert("sljsdf");
});
});
});
Try This Code :
$(document).ready(function(){
$("#div1").click(function(e){
$(this).after($('<div id="s" style="background-color:blue;">NLC TRANSPORT</div>'));
$("#s").click(function(){
alert("sljsdf");
});
});
});
Related
I need a custom context menu, so I use addEventListener for it, but I wish to have it on the div1, but not on div2, how I can do it without to add the same listener with stopPropagation()
<html>
<head>
</head>
<body>
<div id="div1" style="background-color:green;border:3px solid black;width:300px;height:300px;margin:auto;">
<div id="div2" style="background-color:yellow;border:3px solid black;width:100px;height:100px;margin:auto;margin-top:-50px;">
some text
</div>
</div>
<script>
document.getElementById('div1').addEventListener('contextmenu', function(e)
{
console.log('contextmenu');
});
</script>
</body>
</html>
Just check the event target in the handler, and abort if the target was <div2>.
Add false as a third parameter of addEventListener
document.getElementById('div1').addEventListener('contextmenu', function(e)
{
console.log('contextmenu');
}, false);
Or
if(e.currentTarget.getAttribute("id") != "div1") e.preventDefault();
This question already has answers here:
Event handler not working on dynamic content [duplicate]
(2 answers)
Closed 9 years ago.
I am writing an application using jQuery, where when a button is clicked, a select box is generated and appended to a row. Whenever the select changes, it should trigger the change event, but using .on("change", function() {}); isn't working:
Code:
<!DOCTYPE html>
<html>
<head>
<title>HTML5-Template</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style type="text/css">
html, body
{
}
input,select {
border: 1px solid #404048;
padding: 4px;
}
</style>
<script type="text/javascript" src="../JavaScript/JQuery/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#cmdCreateRow").click(function() {
var row = $("<div />")
.css("font", "normal 12px Verdana")
.css("padding", "8px")
.css("display", "inline-block")
.css("background", "#F0F0F8")
.css("border", "1px solid #A0A0A8")
.css("margin", "2px");
var types = [
"Local",
"Remote",
"(Custom)"
];
var type = $("<select />").attr("class", "member-type");
for(var i in types) {
type.append($("<option />").val(types[i]).text(types[i]));
};
row.append(type);
$("#Container").append(row).append($("<br />"));
});
$(".member-type").on("change", function() {
alert("changed");
});
});
</script>
</head>
<body>
<input type="button" id="cmdCreateRow" value="Create Row" />
<div id="Container">
</div>
</body>
</html>
Any idea's what I'm doing wrong?
As $(".member-type") is empty when you do the binding, you're not doing anything.
Change
$(".member-type").on("change", function() {
alert("changed");
});
to
$(document).on("change", ".member-type", function() {
alert("changed");
});
or this because the #Container element is static:
$("#Container").on("change", ".member-type", function() {
alert("changed");
});
Try this:
$(document).on("change", ".member-type", function() {
//Code
});
This is the replacement for: "live" in jQuery, see: http://api.jquery.com/live/
--
The regular "on" method will only work for elements which are already available in the DOM.
I want to add a click event to an iframe. I used this example and got this:
$(document).ready(function () {
$('#left').bind('click', function(event) { alert('test'); });
});
<iframe src="left.html" id="left">
</iframe>
But unfortunately nothing happens.
When I test it with another element (e.g. a button), it works:
<input type="button" id="left" value="test">
You could attach the click to the iframe content:
$('iframe').load(function(){
$(this).contents().find("body").on('click', function(event) { alert('test'); });
});
Note: this will only work if both pages are in the same domain.
Live demo: http://jsfiddle.net/4HQc4/
Two solutions:
Using :after on a .iframeWrapper element
Using pointer-events:none; one the iframe
1. Using :after
use a transparent overlay ::after pseudo element with higher z-index on the iframe's wrapper DIV element. Such will help the wrapper to register the click:
jQuery(function ($) { // DOM ready
$('.iframeWrapper').on('click', function(e) {
e.preventDefault();
alert('test');
});
});
.iframeWrapper{
display:inline-block;
position:relative;
}
.iframeWrapper::after{ /* I have higher Z-index so I can catch the click! Yey */
content:"";
position:absolute;
z-index:1;
width:100%;
height:100%;
left:0;
top:0;
}
.iframeWrapper iframe{
vertical-align:top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="iframeWrapper">
<iframe src="http://www.reuters.tv/" frameBorder="0"></iframe>
</div>
2. Using pointer-events:none;
Clicks are not handleable from outside the iframe from an external resource (if the iframe is not in your domain).
You can only create that function inside your 'called into iframe' page, not from within the iframe-hosting page.
How to do it:
You can wrap your iframe into a div
make the click "go through" your iframe using CSS pointer-events:none;
target clicks with jQuery on your wrapping DIV (the iframe parent element)
jQuery(function ($) { // DOM ready
$('.iframeWrapper').on('click', function(e) {
e.preventDefault();
alert('test');
});
});
.iframeWrapper{
display:inline-block;
position:relative;
}
.iframeWrapper iframe{
vertical-align:top;
pointer-events: none; /* let any clicks go trough me */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="iframeWrapper">
<iframe src="http://www.reuters.tv/" frameBorder="0"></iframe>
</div>
NOTA BENE:
No clicks will be registered by the iframe element, so a use-case would be i.e: if by clicking the iframe you want to enlarge it full screen.... Etc...
I got it to work but only after uploading it to a host. I imagine localhost would work fine too.
outer
<html>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function() {
var myFrame = document.getElementById("myFrame");
$(myFrame.contentWindow.document).find("div").on("click", function () { alert("clicked"); });
});
</script>
<body>
<iframe id="myFrame" src="inner.htm"></iframe>
</body>
</html>
inner
<html>
<head>
<style>
div {
padding:2px;
border:1px solid black;
display:inline-block;
}
</style>
</head>
<body>
<div>Click Me</div>
</body>
</html>
Pure Javascript
Not my solution but only this works well.
let myConfObj = {
iframeMouseOver : false
}
window.addEventListener('blur',function(){
if(myConfObj.iframeMouseOver){
console.log('Wow! Iframe Click!');
}
});
document.getElementById('YOUR_CONTAINER_ID').addEventListener('mouseover',function(){
myConfObj.iframeMouseOver = true;
});
document.getElementById('YOUR_CONTAINER_ID').addEventListener('mouseout',function(){
myConfObj.iframeMouseOver = false;
});
$(document).ready(function () {
$('#left').click(function(event) { alert('test'); });
});
<iframe src="left.html" id="left">Your Browser Does Not Support iframes</iframe>
The script would have to be ran entirely from the iframe. I would recommend a different method of calling content, such as php.
iframes aren't really worth the hassle.
The actual problem is that, the click event does not bind to the DOM of the iframe and bind() is deprecated, use .on() to bind the event. Try with the following codes and you will find the borders of the iframe clickable getting that alert.
$('#left').on('click', function(event) { alert('test'); });
Demo of that Issue
So how to get it done?
How you should do is, create a function on iframe page, and call that function from that iframe page.
I have a div and a simple jQuery code that calls the div on an 'onlclick' event and properly hides on 'onmouseout' event. The problem is when I put a text or a link inside this div and move a cursor over the text / link in this div - it triggers out() function effect and dissappears - even if the cursor is still inside the div. Why is that so ? Thanks for comments.
<script src="js/jquery.js"></script>
<style type="text/css">
#sample {
position:relative;
width:500px;
height:200px;
background-image:url(images/img.png);
background-repeat:repeat-x;
}
</style>
</head>
<body>
<a href="javascript:show();" >link</a>
<div id="sample" onmouseout="out()">THIS IS TEXT</div>
<script type="text/javascript">
$(document).ready(function() {
$("#sample").hide();
});
function show() {
$("#sample").fadeIn('slow');
}
function out() {
$("#sample").fadeOut('slow');
}
</script>
</body>
</html>
Use mouseenter and mouseleave.
In the document ready function add this
jQuery("#sample").mouseleave(out);
and remove the onmouseout code from the HTML markup.
remove JavaScript code from HTML
and try this.
$(function(){
$("#sample").hide();
$("a").click(function() {
$("#sample").fadeIn('slow');
return false;
});
$("#sample").mouseout(function() {
$("#sample").fadeOut('slow');
});
})();
Demo
Your <a> element is inside the #sample element, so running fadeOut on #sample will hide it, and everything inside it.
To keep the <a> you need to place it outside #sample in the html.
Oooh, no I get it, try this instead of the inline stuff:
$("#sample").hide();
$("a").mouseenter(function() {
$("#sample").fadeIn('slow');
});
$("#sample").mouseleave(function() {
$("#sample").fadeOut('slow');
});
Here's a Fiddle, not the way I would do it, but the closest I could get to your example: http://jsfiddle.net/GkSGz/
I have a jQuery UI Sortable list. The sortable items also have a click event attached. Is there a way to prevent the click event from firing after I drag an item?
$().ready( function () {
$('#my_sortable').sortable({
update: function() { console.log('update') },
delay: 30
});
$('#my_sortable li').click(function () {
console.log('click');
});
});
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
I had the same problem and since my sortable items contained three or four clickable items (and the number was variable) binding/unbinding them on the fly didn't really seem an option. However, by incident I specified the
helper : 'clone'
option, which behaved identically to the original sortable in terms of interface but apparently does not fire click events on the dragged item and thus solves the problem. It's as much a hack as anything else, but at least it's short and easy..
If you have a reference to the click event for your li, you can unbind it in the sortable update method then use Event/one to rebind it. The event propagation can be stopped before you rebind, preventing your original click handler from firing.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
var myClick = function () {
console.log('click');
};
$().ready( function () {
$('#my_sortable').sortable({
update: function(event, ui) {
ui.item.unbind("click");
ui.item.one("click", function (event) {
console.log("one-time-click");
event.stopImmediatePropagation();
$(this).click(myClick);
});
console.log('update') },
delay: 30
});
$('#my_sortable li').click(myClick);
});
</script>
<style type="text/css" media="screen">
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
If you for some reason don't want to use the helper:'clone' trick, this worked for me. It cancels the click event on an item that is dragged. jQuery adds the class ui-sortable-helper to the dragged element.
$('.draggable').click(clickCancelonDrop);
function clickCancelonDrop(event) {
var cls = $(this).attr('class');
if (cls.match('ui-sortable-helper'))
return event.stopImmediatePropagation() || false;
}
$('.selector').draggable({
stop: function(event, ui) {
// event.toElement is the element that was responsible
// for triggering this event. The handle, in case of a draggable.
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
}
});
This works because "one-listeners" are fired before "normal" listeners. So if a one-listener stops propagation, it will never reach your previously set listeners.
We can also use a flag on the stop event that and check that flag on the click event.
var isSortableCalled = false;
$('#my_sortable').sortable({
stop: function(event, ui){
isSortableCalled = true;
},
update: function() { console.log('update') },
delay: 30
});
$('#my_sortable li').click(function () {
if(!isSortableCalled){
console.log('click');
}
isSortableCalled = false;
});
The answer by mercilor worked for me a couple of caveats. The click event was actually on the handle element rather than the sorted item itself. Unfortunately the ui object, doesn't give you a reference to the handle in the update event (feature request to jquery ui?). So I had to get the handle myself. Also, I had to call preventDefault as well to stop the click action.
update: function(ev, ui) {
var handle = $(ui.item).find('h3');
handle.unbind("click");
handle.one("click", function (event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).click(clickHandler);
});
// other update code ...
Easier, use a var to know when the element is being sorted...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" charset="utf-8">
$().ready( function () {
$('#my_sortable').sortable({
start: function() {
sorting = true;
},
update: function() {
console.log('update');
sorting = false;
},
delay: 30
});
$('#my_sortable li').click(function () {
if (typeof(sorting) == "undefined" || !sorting) {
console.log('click');
}
});
});
</script>
<style type="text/css" media="screen">
#my_sortable li {
border: 1px solid black;
display: block;
width: 100px;
height: 100px;
background-color: gray;
}
</style>
</head>
<body>
<ul id="my_sortable">
<li id="item_1">A</li>
<li id="item_2">B</li>
<li id="item_3">C</li>
</ul>
</body>
</html>
Thanks to Elte Hupkus;
helper: 'clone'
I have implemented the same and a sample is shown below.
$(document).ready(function() {
$("#MenuListStyle").sortable({
helper:'clone',
revert:true
}).disableSelection();
});
One solution is to use live() instead of normal binding, but Elte Hupkes solution rocks!!!!
$('.menu_group tbody a').click(function(){
link = $(this).attr('href');
window.location.href = link;
});
This solution seems to be working for me. Now i can click on clickables inside sortable elements.
Note: ".menu_group tbody" is .sortable();