I have the below content that loads on through AJAX.
<div class="grid">
<div class="thumb">
<img alt="AlbumIcon" src="some-image.jpg">
<div style="bottom:-75px;" class="meta">
<p class="title">Title</p>
<p class="genre"> <i class="icon-film icon-white"></i>
Genre
</p>
</div>
</div>
</div>
Additionally, I have writen the following script in jquery that applies to the above 'div.grid'.
jQuery(function ($) {
$(document).ready(function () {
$(".grid").on({
mouseenter : function () {
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},
mouseleave : function () {
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
});
});
});
The script works fine when the page loads the first time. However, the hover effect doesn't work once the above div is generated via AJAX after clicking on an 'a' tag. I can't seem to figure out what's wrong here? New to all this. Can anyone help?
To append these event handlers to dynamically generated elements, you need to bind to the document or another static parent element and then specify .grid as the second argument passed to .on.
The second argument is used as a filter to determine the selected elements that trigger the event. So when the event is fired it will propagate to the document or parent element selected by jquery. The event target will then be scrutinized using the selector provided as the second argument. If the target matches the second argument, (.grid in our case), the event is fired.
You can read more in the jQuery documentation.
Also, since your using document.ready there is no need for the short hand ready statement, jquery(function($).
$(document).ready(function () {
$(document).on({
mouseenter : function () {
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},
mouseleave : function () {
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
}, ".grid");
});
you lost your binding because of ajax that overwrite your div with class=".grid"
use parent element for binding
$('.ParentElementClass').on("mouseleave", ".grid", function(){...})
more from jquery api
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. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
Not sure what you're shooting for here but a little malformed HTML may have done it...
jsFiddle Demo
<div class="grid">
<div class="thumb">
<img alt="AlbumIcon" src="some-image.jpg" />
<div style="bottom:-75px;" class="meta">
<p class="title">Title</p>
<p class="genre"><i class="icon-film icon-white"></i>Genre</p>
</div>
</div>
</div>
$(function () {
$(".grid").on({
mouseenter: function () {
alert('entered');
$(this).find('.meta').stop().animate({
bottom: '0px'
}, 200);
},
mouseleave: function () {
alert('left');
$(this).find('.meta').stop().animate({
bottom: '-75px'
}, 200);
}
}, ".thumb");
});
});
Be sure to close img tags. They're notorious for causing intermittent glitches.
You can just use the hover function:
jQuery(function ($) {
$(document).ready(function () {
$(".grid").hover(function () { /*mouseenter*/
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},function(){ /*mouseleave*/
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
});
});
Explanation:
The first parameter function does the work of mouseenter and the second does the work of mouseleave.
I'd recommend using those both, mouseenter and mouseleave in situation when you don't want an effect back when the user gets off his mouse from the element.
Related
Polymer 1.*
I had to write my own dropdown menu. I need to close the menu when the user clicks outside of the element. However, I am not able to catch the event when a user clicks outside of the element so I can close the menu.
Any ideas what I am doing wrong?
EDIT: I've studying paper-menu-button which closes paper-listbox when I click outside the element.... but I don't see anywhere where it catches that event https://github.com/PolymerElements/paper-menu-button/blob/master/paper-menu-button.js#L311
<dom-module id="sp-referrals-reservations-dropdown">
<template>
<style include="grid-dropdown-styles">
</style>
<div id="dropdown" class="grid-dropdown">
<paper-listbox>
<div class="grid-dropdown-item">Convert to stay</div>
<div class="grid-dropdown-item">Cancel reservation</div>
<div class="grid-dropdown-item">Delete reservation</div>
</paper-listbox>
</div>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'sp-referrals-reservations-dropdown',
behaviors: [Polymer.IronControlState],
properties: {
},
listeners: {
'tap': '_close',
'click': '_close',
'blur': '_close',
'focusout': '_close',
'focusChanged': '_close',
'focus-changed': '_close',
'active-changed': '_close',
'activeChanged': '_close',
'iron-activate': '_close',
'ironActivate': '_close',
},
open: function(e) {
},
_close: function() {
console.log('aaa');
this.$.dropdown.style.display = "none";
},
});
})();
</script>
</dom-module>
I am not sure, will it be enough, but if you wrap the sp-referrals-reservations-dropdown element with a parent-element then you can listen to parent-element events same as its child.
<parent-element></parent-element>
<dom-module id="parent-element">
<template>
<style>
:host {
display:block;
background:green;
width:100%;
height:100vh; }
</style>
<sp-referrals-reservations-dropdown id="spref"></sp-referrals-reservations-dropdown>
At parent's script:
Polymer({is:'parent-element', properties:{},
listeners:{ 'tap': '_taped'},
_taped:function(t){
this.$.spref._close();
}
});
this _taped functions will call child's _close function. Hope its help.
Incase of needed more. We can develop this.
Demo
EDIT
Wrap your element into paper-dialog. And at ready:function() call
this.$.dialog.open()
Then when you click outside of the element. paper-dialog will close automatically.
Just FYI, you weren't able to get this to work because custom elements don't listen for events outside of their own encapsulation unless you explicitly wire them up to do so... and if you do so, you can't use Polymer's built-in event handling.
So something like this would work:
// Insert this somewhere it'll get run once attached to the DOM
// This line keeps clicks within your element from closing the dropdown
this.shadowroot.addEventListener('click', (event) => { event.stopPropagation(); });
// And this listens for any click events that made it up to body, and closes the element
document.querySelector('body').addEventListener('click', this._close);
Or, at least, that's what I think was going on. The polymer elements either did it by binding to a different event (blur?) or by having the parent element trigger an event on click that told the child element to close.
I have problem with Edge browser. In my web site I have buttons with span tags inside them. In this span tags I bind text and icons. So far I had no problem but on Edge browser it is possible to click on disabled buttons. After investigating problem I found out that, when button contains span tags inside, it is possible to click on button. Here is how it looks on my web site:
<button id="btnRefresh" type="button" class="btn btn-primary" ng-click="refresh()" ng-disabled="performingAction">
<span ng-class="performingAction && action == 'refresh' ? 'fa fa-cog fa-spin' :'fa fa-refresh'"></span>
<span>{{ refresh }}</span>
</button>
Here is example to testing:
<button type="button" disabled="disabled" onclick='alert("test");'>
<span>Click me!</span>
</button>
One option would be to hide buttons instead of disabling, but I prefer to disable them. Please suggest solution to over come this issue.
Just set
pointer-events: none;
for disabled buttons.
Here's CSS to disable all disabled elements everywhere:
*[disabled] {
pointer-events: none !important;
}
pointer-events documentation
This is a bug in Microsoft Edge. Disabled buttons accept clicks if they contain any HTML elements (i.e. if they contain anything else than just text).
Reported multiple times via Microsoft Connect:
Event bubbles from child element into element (by SO user Ryan Joy)
Bootstrap/Jquery disabled buttons generate click events and show tooltips even disabled
The bug was still present in Build 10565 (16 October 2015).
It was fixed in the November update, Build 10586.
A possible (but ugly) workaround is to call some Javascript in onclick for every button, which then checks if the button is disabled and returns false (thus suppressing the click event).
One work around I've come up with using angularjs is inspired by Ben Nadel's blog here
So for example:
angular.module('myModule').directive(
"span",
function spanDirective() {
return ({
link: function (scope, element, attributes) {
element.bind('click', function (e) {
if (e.target.parentNode.parentNode.disabled || e.target.parentNode.disabled) {
e.stopPropagation();
}
})
},
restrict: "E",
});
}
);
Since you're not always going to be using a span element and probably don't want to create a new directive for every element type, a more general workaround would be to decorate the ngClick directive to prevent the event from reaching the real ngClick's internal event handler when the event is fired on a disabled element.
var yourAppModule = angular.module('myApp');
// ...
yourAppModule.config(['$provide', function($provide) {
$provide.decorator('ngClickDirective', ['$delegate', '$window', function($delegate, $window) {
var isEdge = /windows.+edge\//i.test($window.navigator.userAgent);
if (isEdge) {
var directiveConfig = $delegate[0];
var originalCompileFn = directiveConfig.compile;
directiveConfig.compile = function() {
var origLinkFn = originalCompileFn.apply(directiveConfig, arguments);
// Register a click event handler that will execute before the one the original link
// function registers so we can stop the event.
return function linkFn(scope, element) {
element.on('click', function(event) {
if (event.currentTarget && event.currentTarget.disabled) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
}
});
return origLinkFn.apply(null, arguments);
};
};
}
return $delegate;
}]);
}]);
How do I get a DOM element and attach an event onClick?. I tried this code but it does not work:
<div>
<h1 id="some_id">
click here
</h1>
</div>
JavaScript:
Ext.onReady(function() {
if(Ext.getDom('some_id'))
{
var elDom = Ext.getDom('some_id');
elDom.on('click', function(){
Ext.Msg.alert('Status', 'Already get the element from the dom');
});
}
});
Fiddle: https://fiddle.sencha.com/#fiddle/2fl
Another way to do this is to get the Ext.dom.Element instead of the actual DOM node. This will allow you to use .on(). This is done by using Ext.get() instead of Ext.getDom().
var elDom = Ext.get('some_id');
if(elDom) {
elDom.on('click', function() {
Ext.Msg.alert('Status', 'Already get the element from the dom');
});
}
Since I don't know much about jQuery I have am not being able to produce a dialog box on hover over a checkbox. Any suggestion would be helpful. Below is my code:
<input type="checkbox" id="employee-id" name="employeeId" onmouseover="produceDialog()">
<div id="employee-info-div"></div>
Similarly my jQuery is:
produceDialog(){
$("employee-info-div").dialog({
open : function ( event, ui ) {
$(".ui-dialog-titlebar-close").hide();
},
dialogClass : 'fixed-dialog',
resizable : false,
height : 150,
width : 250,
modal : false,
create : function ( event ) {
$(event.target).parent().css('position', 'fixed');
},
});
}
This may be the example you are looking for:
Working jsFiddle here
Below is a stand-alone example, which should just be copy/play.
Notes:
The element $('#employee-info-div'); was assigned to a variable to make code more efficient and faster to type. (More efficient b/c only check DOM once for the element, retrieve from variable after that.)
Used jQuery hover() method to open the dialog, but initialized the dialog separately (upon document ready). Note that the hover method must have two functions associated with it; the second function need not do anything but it must be there.
The hover-IN method assigned to the class $('.employee-id') runs the code $('#employee-info-div').dialog('open');, which opens the dialog. Note that the 2nd element is accessed via variable name.
Copy/Paste the following code into a separate document in your webroot and run, OR just use the above jsFiddle link to see it all in action.
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<style>
#employee-info-div{
width:40%;
float:right;
padding:5px;
background:wheat;
color:blue;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
var eid = $('#employee-info-div');
var blurb = '<h2>Employee Information:</h2>Here is some example information about this employee. It can be text inserted like this, or it can be information retrieved from a database via AJAX. For simple AJAX examples, <a target="_blank" href="http://stackoverflow.com/questions/17973386/ajax-request-callback-using-jquery/17974843#17974843"> see this StackOverflow post </a> (remember to upvote any posts that are helpful to you, please.)';
function hovIn() {
$(this).css({'font-weight':'bold','color':'blue'});
eid.html(blurb);
eid.dialog('open');
}
function hovOut() {
//eid.html(''); //<-- Causes dlg text to appear/disappear as you move mouse on/off checkbox and label
$(this).css({'font-weight':'normal','color':'black'});
}
$('.employee-id').hover(hovIn, hovOut);
eid.dialog({
autoOpen:false,
title:"Your jQueryUI Dialog",
show: "fade",
hide: "fade",
width:500, //orig defaults: width: 300, height: auto
buttons: {
Ok: function() {
$(this).dialog('close');
}
}
}); //END eid.dialog
}); //END $(document).ready()
</script>
</head>
<body>
Hover over below checkbox to see hidden DIV:<br><br>
<input type="checkbox" id="employee-id" class="employee-id" name="employeeId" ><span class="employee-id">Hover over this checkbox</span>
<div id="employee-info-div"></div>
</body>
</html>
You can bind the hover event to your checkbox:
$("#employee-id").hover(function(){
// call your produceDialog function here
});
I am unable to get the click event for this HTML:
<ul id="frd_overlay_list">
<li><div class="divLink"><div id="1"><img src="path"><div class="frdName">Name</div></div></div></li>
<li><div class="divLink"><div id="2"><img src="path"><div class="frdName">Name</div></div></div></li>
</ul>
and JQuery script:
$('li').click(function(){
console.log('Not working');
});
I am able to get click event for the ul element i.e.
$('ul#frd_overlay_list').click(function(){
console.log('This works');
});
I have tried this, but this also doesnt work:
$('ul#frd_overlay_list li').click(function(){
console.log('Doesn't work either');
});
Please give me pointers what am I doing wrong?
All your example works except for the last one:
You need to escape the ' or use double quotes for the string
$('ul#frd_overlay_list li').click(function(){
console.log("Doesn't work either");
});
Since you want to apply the click events for dynamically added elements, you could use on function of jQuery.
on would bind event handlers for dynamically added elements
bind would only bind event handlers for currently existing elements.
Usage of on:
$("ul#frd_overlay_list li").on("click", function(){
console.log("Doesn't work either");
});
Fiddle