jQuery plugin: add eventlistener to element - javascript

I'm creating a small jQuery plugin for personal use which adds some content to the document when you hover over an element.
Currently this is the (simplified) code:
(function($){
$.fn.tempFnName = function(options){
var element = $('<div />');
return this
.each(function(){
$(this)
.on('mouseenter',
function(){
$('body')
.append(element);
})
.on('mouseleave',
function(){
element.remove();
});
});
};
})(jQuery);
For some reason this doesn't work. Looking around on google and stackoverflow didn't provide an answer. What am I doing wrong?
edit: As pointed out by WTK, there's nothing wrong with this code. The following code shows how the plugin should be implemented.
function appendAddAnchor(){
return $('<a />').tempFnName();
}
//even if I try the following, the click event will not work!
function appendAddAnchor(){
return $('<a />')
.click(function(){console.log('test')});
.tempFnName();
}
This is really strange to me, because I used to have Bootstrap' .tooltip() chained to the same $('<a />') and this worked without any issues...

I tried this in this fiddle: http://jsfiddle.net/Gm4jk/2/
(function ($) {
$.fn.tempFnName = function(options){
var element = $('<div/>');
element.html('aTest');
return this.each( function(){
$(this).mouseenter(function(){
$('body').append(element);
});
$(this).mouseleave(function(){
element.remove();
});
});
};
})(jQuery);
$('#start').tempFnName();
and it is working just fine. It may be that you are running into compatibility issues.
from the jQuery documentation:
"The mouseenter JavaScript event is proprietary to Internet Explorer. Because of the event's general utility, jQuery simulates this event so that it can be used regardless of browser. This event is sent to an element when the mouse pointer enters the element. Any HTML element can receive this event."
I read that to mean if you are not using the shorthand bind method, you may not be getting the 'emulated' event instead jQuery may be looking for the actual event which, in all but IE, does not exist.
To be clear, I also got it to work with your code in jsFiddle. http://jsfiddle.net/zFKXx/2/

Related

Triggered click don't work propertly [duplicate]

I'm having a hard time understand how to simulate a mouse click using JQuery. Can someone please inform me as to what i'm doing wrong.
HTML:
<a id="bar" href="http://stackoverflow.com" target="_blank">Don't click me!</a>
<span id="foo">Click me!</span>
jQuery:
jQuery('#foo').on('click', function(){
jQuery('#bar').trigger('click');
});
Demo: FIDDLE
when I click on button #foo I want to simulate a click on #bar however when I attempt this, nothing happens. I also tried jQuery(document).ready(function(){...}) but without success.
You need to use jQuery('#bar')[0].click(); to simulate a mouse click on the actual DOM element (not the jQuery object), instead of using the .trigger() jQuery method.
Note: DOM Level 2 .click() doesn't work on some elements in Safari. You will need to use a workaround.
http://api.jquery.com/click/
You just need to put a small timeout event before doing .click()
like this :
setTimeout(function(){ $('#btn').click()}, 100);
This is JQuery behavior. I'm not sure why it works this way, it only triggers the onClick function on the link.
Try:
jQuery(document).ready(function() {
jQuery('#foo').on('click', function() {
jQuery('#bar')[0].click();
});
});
See my demo: http://jsfiddle.net/8AVau/1/
jQuery(document).ready(function(){
jQuery('#foo').on('click', function(){
jQuery('#bar').simulateClick('click');
});
});
jQuery.fn.simulateClick = function() {
return this.each(function() {
if('createEvent' in document) {
var doc = this.ownerDocument,
evt = doc.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, doc.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
this.dispatchEvent(evt);
} else {
this.click(); // IE Boss!
}
});
}
May be useful:
The code that calls the Trigger should go after the event is called.
For example, I have some code that I want to be executed when #expense_tickets value is changed, and also, when page is reload
$(function() {
$("#expense_tickets").change(function() {
// code that I want to be executed when #expense_tickets value is changed, and also, when page is reload
});
// now we trigger the change event
$("#expense_tickets").trigger("change");
})
jQuery's .trigger('click'); will only cause an event to trigger on this event, it will not trigger the default browser action as well.
You can simulate the same functionality with the following JavaScript:
jQuery('#foo').on('click', function(){
var bar = jQuery('#bar');
var href = bar.attr('href');
if(bar.attr("target") === "_blank")
{
window.open(href);
}else{
window.location = href;
}
});
Try this that works for me:
$('#bar').mousedown();
Technically not an answer to this, but a good use of the accepted answer (https://stackoverflow.com/a/20928975/82028) to create next and prev buttons for the tabs on jQuery ACF fields:
$('.next').click(function () {
$('#primary li.active').next().find('.acf-tab-button')[0].click();
});
$('.prev').click(function () {
$('#primary li.active').prev().find('.acf-tab-button')[0].click();
});
I have tried top two answers, it doesn't worked for me until I removed "display:none" from my file input elements.
Then I reverted back to .trigger() it also worked at safari for windows.
So conclusion, Don't use display:none; to hide your file input , you may use opacity:0 instead.
Just use this:
$(function() {
$('#watchButton').trigger('click');
});
You can't simulate a click event with javascript.
jQuery .trigger() function only fires an event named "click" on the element, which you can capture with .on() jQuery method.

Capturing and bubbling events

I created the next jsfiddle:
http://jsfiddle.net/AHyN5/6/
This is my code:
var mainDiv = document.getElementsByClassName('mainDiv');
var div = mainDiv[0].getElementsByClassName('data');
mainDiv[0].addEventListener("click", function(e) {
alert('1');
});
$(mainDiv[0]).children('img').click(function (e) {
e.stopImmediatePropagation()
return false;
})
I want that click on the pink background will popup a message with value of 1(an alert message).
When clicking the yellow, I want nothing to happen.
I read this blog but with no success..
Any help appreciated!
I agree with the others stating to use jQuery or straight DOM calls.
Here is another shot at the jQuery solution - very similar to the one above. I went ahead and presented it because it targets the images directly - in case that's what you're really trying to accomplish.
$(function()
{ var mainDiv = $('div.pink:first'),
imgs = $('img');
mainDiv.click(function()
{ alert('1');
});
imgs.click(function(e)
{ e.stopImmediatePropagation();
});
});
You could add pointer-events: none; to the yellow class. That will cause those elements to not fire click events.
See here for more info https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
You have a mix of jQuery and DOM methods calls. Note also that for attaching event listeners, you should wait for all HTML document to be ready.
I'd recommend using either DOM methods ot jquery methods. Following is an example of jquery:
$(function(){
$('.pink:first').on("click", function(e) {
alert('1');
});
$('.yellow').on('click', function (e) {
e.stopPropagation();
});
})
See also this JSfiddle

Cant select ids that I loaded with jQuery

I understand that you need to use ".on" to use code that you loaded with jquery after the page has loaded. (At least I think it works that way)
So I tried that but it somehow just doesn't do a thing at all. No errors in the console either.
$("#forgot_password").click(function(){
var forgot_password = '<div id="toLogin" style="cursor:pointer;">Prijava</div>'
$("#loginPopupForm").html(forgot_password);
});
$("#toLogin").on("click", function(){
alert("Hello");
});
So when I click on #forgot_password it does execute the first click function. But when I click on #toLogin it doesn't do anything and I think its because its loaded with jquery when I click on #forgot_password
Try this
$("#loginPopupForm").on("click", "#toLogin", function(){
alert("Hello");
});
You need to bind to an element that is present when the page loads, like body for example. Just change your code to what is shown below
$("body").on("click", "#forgot_password", function(){
var forgot_password = '<div id="toLogin" style="cursor:pointer;">Prijava</div>'
$("#loginPopupForm").html(forgot_password);
});
$("body").on("click", "#toLogin", function(){
alert("Hello");
});
You are setting the on to the wrong thing. You want it to be:
$(document).on('click', '#toLogin', function() {alert('hello') });
The id isn't there until you do the other click event, so jQuery is not finding any element to set the click event on. You need to have an element that has been rendered in the DOM to set the event on.
You are totally right about the problem : on() targets only elements that are already existing as it runs.
What you need in jQuery is called Delegated event and is well explained on the Jquery doc page.
The difference in the code is thin, but it's how you're supposed to do.
You have to specify the parent element
$("#toLogin").on("click","#loginPopupForm", function(){
alert("Hello");
});
in the 2nd argument of the on

jQuery .on('change', function() {} not triggering for dynamically created inputs

The problem is that I have some dynamically created sets of input tags and I also have a function that is meant to trigger any time an input value is changed.
$('input').on('change', function() {
// Does some stuff and logs the event to the console
});
However the .on('change') is not triggering for any dynamically created inputs, only for items that were present when the page was loaded. Unfortunately this leaves me in a bit of a bind as .on is meant to be the replacement for .live() and .delegate() all of which are wrappers for .bind() :/
Has anyone else had this problem or know of a solution?
You should provide a selector to the on function:
$(document).on('change', 'input', function() {
// Does some stuff and logs the event to the console
});
In that case, it will work as you expected. Also, it is better to specify some element instead of document.
Read this article for better understanding: http://elijahmanor.com/differences-between-jquery-bind-vs-live-vs-delegate-vs-on/
You can use any one of several approaches:
$("#Input_Id").change(function(){ // 1st way
// do your code here
// Use this when your element is already rendered
});
$("#Input_Id").on('change', function(){ // 2nd way
// do your code here
// This will specifically call onChange of your element
});
$("body").on('change', '#Input_Id', function(){ // 3rd way
// do your code here
// It will filter the element "Input_Id" from the "body" and apply "onChange effect" on it
});
Use this
$('body').on('change', '#id', function() {
// Action goes here.
});
Just to clarify some potential confusion.
This only works when an element is present on DOM load:
$("#target").change(function(){
//does some stuff;
});
When an element is dynamically loaded in later you can use:
$(".parent-element").on('change', '#target', function(){
//does some stuff;
});
$("#id").change(function(){
//does some stuff;
});
you can use:
$('body').ready(function(){
$(document).on('change', '#elemID', function(){
// do something
});
});
It works with me.
You can use 'input' event, that occurs when an element gets user input.
$(document).on('input', '#input_id', function() {
// this will fire all possible change actions
});
documentation from w3
$(document).on('change', '#id', aFunc);
function aFunc() {
// code here...
}

Attach an event immediately after setting up the HTML content

This is an example of my jQuery code that I use in a function to do pagination:
// new_content is a variable that holds the html I want to add to a div
$('div#my_div').html(new_content);
$("div#my_div a.details").hover(function(){
$(this).fadeIn(); //code to execute when the mouse get in
}, function(){
$(this).fadeOut(); //code to execute when the mouse get out
});
BUT the hover event does not work at all, and I believe that this is caused because the DOM is not ready yet!
To get around this I used set up a timer like this:
$('div#my_div').html(new_content);
window.setTimeout(
$("div#my_div a.details").hover(function(){
$(this).fadeIn(); //code to execute when the mouse get in
}, function(){
$(this).fadeOut(); //code to execute when the mouse get out
});
,100);
I asked this question because I'm sure that this is not the right way to attach an event immediately after the html method (maybe it didn't it's work!).
si I hope someone show me the right way to do it.
You would want to use the live mouseover mouseleave events
$("div#my_div").live({
mouseenter: function()
{
},
mouseleave: function()
{
}
}
);
Alternately you could do:
$('div#my_div').live('mouseover mouseout', function(event) {
if (event.type == 'mouseover') {
// do something on mouseover
} else {
// do something on mouseout
}
});
UPDATE
In newer versions of jQuery you can do it like this
$('body').on('mouseover','#my_div', function(){});
$('body').on('mouseout', '#my_div', function(){});
Maybe you need to use the live() method. As you can read here, it seems that you will need to separate the two events:
.live("mouseenter", function() {...})
.live("mouseleave", function() {...});
UPDATE: Someone voted me up, so if someone gets here, I recommend to read the on() documentation (here) as live was deprecated long ago. Also, it may be interesting to see mouseenter()(link) and mouseleave() (link). The idea is the same as with live.
It is better to use a delegate rather than live, as live is essentially a delegate on the document.body causing it to have to bubble much longer.
Here is an example using a delegate: http://jsfiddle.net/Akkuma/wLDpT/
you can check out .live function of jquery. Here is the link
http://api.jquery.com/live/

Categories

Resources