Is there a way to handle separated events by one condition, without checking it in every event handler function? I.e. in the code listed below. Or maybe there is a way to do it more convinient? Any thoughts/suggestions?
var Obj = function(){
var self = this;
this.initialized = true;
$(document).on('click', function(){
if(self.initialized){
alert('hax!');
self.initialized = false;
}
})
$('input').on('mouseenter mouseleave', function(e){
if(self.initialized){
$(this).attr('class', e.type == 'mouseenter' ? 'hovered' : '');
}
})
/*$('...').on(...) etc etc*/
}
var obj = new Obj()
.hovered{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='button' value='Click me!'/>
i've played a bit around and maybe this is a working solution for you:
eventHandlerWrapper = function(state, callback) {
return function(e) {
if(state.initialized) {
return callback.bind(this, e)();
}
}
}
var Obj = function() {
this.initialized = true;
}
var obj = new Obj()
$(document).on('click', eventHandlerWrapper(obj, function(e){
obj.initialized = false;
}))
$('input').on('mouseenter mouseleave', eventHandlerWrapper(obj, function(e){
$(e.currentTarget).attr('class', e.type == 'mouseenter' ? 'hovered' : '');
}))
I've also create a fiddle: https://jsfiddle.net/jz17L7h6/
Can you add another class for your button?
var Obj = function(){
var self = this;
self.initialized = true;
self.dom = $('<input>').attr('type', 'button').val('Click me!')
.data('obj', this)
.appendTo($('.container'));
/*$('...').on(...) etc etc*/
}
$(document)
.on('click', 'input:not(.uninitialized)', function(){
alert('hax!');
$(this).addClass('uninitialized')
.data('obj').initialized = false;
})
.on('mouseenter mouseleave', 'input:not(.uninitialized)', function(e){
$(this).attr('class', e.type == 'mouseenter' ? 'hovered' : '');
});
for (var i = 0; i < 5; i++) {
new Obj();
}
https://jsfiddle.net/chukanov/fzez5th2/3/
If you can't add a class, you can turn off your listeners
var Obj = function(){
var self = this;
self.initialized = true;
self.dom = $('<input>').attr('type', 'button').val('Click me!')
.appendTo($('.container'));
var moveHandler = function(e){
$(this).attr('class', e.type == 'mouseenter' ? 'hovered' : '');
};
var clickHandler = function(){
alert('hax!');
self.initialized = false;
self.dom
.off('mouseenter mouseleave', moveHandler)
.off('click', clickHandler);
};
self.dom
.on('mouseenter mouseleave', moveHandler)
.on('click', clickHandler);
/*$('...').on(...) etc etc*/
}
for (var i = 0; i < 5; i++) {
new Obj();
}
https://jsfiddle.net/chukanov/fzez5th2/4/
Or you can override your handlers
var Obj = function(){
var self = this;
self.initialized = true;
self.dom = $('<input>').attr('type', 'button').val('Click me!')
.appendTo($('.container'));
self.moveHandler = function(e){
$(this).attr('class', e.type == 'mouseenter' ? 'hovered' : '');
};
self.clickHandler = function(e){
alert('hax!');
self.initialized = false;
self.clickHandler = function (e) {};
self.moveHandler = function (e) {};
};
self.dom
.on('mouseenter mouseleave', function (e) { self.moveHandler.apply(this, arguments); })
.on('click', function (e) { self.clickHandler(e); });
/*$('...').on(...) etc etc*/
}
for (var i = 0; i < 5; i++) {
new Obj();
}
https://jsfiddle.net/chukanov/fzez5th2/5/
Update
I think you need to separate mouse events handlers.
var Obj = function(){
var self = this;
self.initialized = true;
self.dom = $('<input>').attr('type', 'button').val('Click me!')
.appendTo($('.container'));
var handlers = {
mouseenter: function (e) {
$(this).addClass('hovered');
},
mouseleave: function (e) {
$(this).removeClass('hovered');
}
}
var moveHandler = function(e){
handlers[e.type].apply(this, arguments);
};
var clickHandler = function(e){
alert('hax!');
self.initialized = false;
clickHandler = function (e) {};
moveHandler = function (e) {};
};
self.dom
.on('mouseenter mouseleave', function (e) {
moveHandler.apply(this, arguments);
})
.on('click', function (e) {
clickHandler(e);
});
/*$('...').on(...) etc etc*/
}
for (var i = 0; i < 5; i++) {
new Obj();
}
https://jsfiddle.net/chukanov/fzez5th2/7/
Related
With this tutorial i made simple drag and drop web app. But I cant do it with DOM. Here is my code jsfinddle . It is not working on jsfiddle but if u download it it will. The script should be placed behind the divs. When you uncoment <div class="column" draggable="true"><span>A</span></div> it will work (not in jsfiddle). So how can i made it with DOM ?
Going off the assumption you meant doing the draggable with dynamically created elements, I've updated your jsfiddle. http://jsfiddle.net/7c3v0s1s/6/ I wrapped the code in a namespace while doing the changes.
HTML
<div class="containter">
<div id="columns"></div>
</div>
Javascript
var localNameSpace = {
dragSrcEl: null
, bindDraggables: function() {
var cols = document.querySelectorAll('#columns .column');
[].forEach.call(cols, function(col) {
col.addEventListener('dragstart', localNameSpace.handleDragStart, false);
col.addEventListener('dragenter', localNameSpace.handleDragEnter, false);
col.addEventListener('dragover', localNameSpace.handleDragOver, false);
col.addEventListener('dragleave', localNameSpace.handleDragLeave, false);
col.addEventListener('drop', localNameSpace.handleDrop, false);
col.addEventListener('dragend', localNameSpace.handleDragEnd, false);
});
}
, createDraggables: function() {
var colDiv = document.getElementById('columns');
var divC = document.createElement('div');
var spanC = document.createElement('span');
divC.className = 'column';
divC.draggable = 'true';
spanC.innerHTML = 'A';
divC.appendChild(spanC);
colDiv.appendChild(divC);
}
, handleDrop: function(e) {
if(e.stopPropagation){
e.stopPropagation();
}
if(dragSrcEl != this){
localNameSpace.dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
, handleDragEnd: function(e) {
var cols = document.querySelectorAll('#columns .column');
this.style.opacity = 1;
[].forEach.call(cols, function(col){
col.classList.remove('over');
});
}
, handleDragEnter: function(e) {
this.classList.add('over');
}
, handleDragLeave: function(e) {
this.classList.remove('over');
}
, handleDragOver: function(e) {
if(e.preventDefault){
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
, handleDragStart: function(e) {
this.style.opacity = 0.4;
localNameSpace.dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
, init: function() {
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
localNameSpace.createDraggables();
localNameSpace.bindDraggables();
}
}, 10);
}
};
localNameSpace.init();
sorry if this is a simple one, I'm very new to jQuery.
I'm using a custom dropdown in place of select boxes. Here is the script:
function DropDown(el) {
this.dd = el;
this.parentid = this.dd.attr('id');
this.placeholder = this.dd.children('span');
this.opts = this.dd.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
obj.dd.on('click', function(event){
$(this).toggleClass('active');
return false;
});
obj.opts.on('click',function(){
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
if(obj.parentid == "dd"){ //brand
$('#brand').val(obj.val);
$("#brand").trigger('change')
} else if (obj.parentid == "dd3") { //availibility
$('#availibility').val(obj.val);
$("#availibility").trigger('change')
}
obj.placeholder.text(obj.val);
});
},
getValue : function() {
return this.val;
},
getIndex : function() {
return this.index;
}
}
$(function() {
var dd = new DropDown( $('#dd') );
var dd2 = new DropDown( $('#dd2') );
var dd3 = new DropDown( $('#dd3') );
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-1').removeClass('active');
});
});
This works perfectly fine, but one of the dropdowns '#dd2' has different options added to it via .append()
The click event doesn't fire on these new options - any suggestions..?
I think "obj.opts.on('click',function(){...})" is the problem;
I prefer
obj.dd.on('click', '.ul.dropdown > li', function() {
//do your job here!
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
if(obj.parentid == "dd"){ //brand
$('#brand').val(obj.val);
$("#brand").trigger('change')
} else if (obj.parentid == "dd3") { //availibility
$('#availibility').val(obj.val);
$("#availibility").trigger('change')
}
obj.placeholder.text(obj.val);
});
because dynamic elment is not binding any event on it!
I have following javascript code to give me drop down menus. I don't want it to drop down the menu. I want it to show all the menu by default what should I remove. Please help.
function DropDown(el) {
this.dd = el;
this.placeholder = this.dd.children('span');
this.opts = this.dd.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents: function () {
var obj = this;
obj.dd.on('click', function (event) {
$(this).toggleClass('active');
return false;
});
obj.opts.on('click', function () {
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
obj.placeholder.text(obj.val);
});
},
getValue: function () {
return this.val;
},
getIndex: function () {
return this.index;
}
}
$(function () {
var dd = new DropDown($('#dd'));
$(document).click(function () {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});
remove
obj.dd.on('click', function(event){
$(this).toggleClass('active');
return false;
});
update
and add the class active by changing var dd = new DropDown( $('#dd') ); into var dd = new DropDown( $('#dd').addClass('active') );
also if you don't want it to get hidden onclick of the document, remove the following as well.
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
I've got Dropdown Menu 3 from here: http://tympanus.net/codrops/2012/10/04/custom-drop-down-list-styling/
Working well onclick, but I don't know how to make it work on hover.
My attempt at the JS:
<script type="text/javascript">
function DropDown(el) {
this.dd = el;
this.placeholder = this.dd.children('span');
this.opts = this.dd.find('ul.dropdown > a');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
obj.dd.on('hover', function(event){
$(this).toggleClass('active');
return false;
});
obj.opts.on('hover',function(){
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
obj.placeholder.text(obj.val);
});
},
getValue : function() {
return this.val;
},
getIndex : function() {
return this.index;
}
}
$(function() {
var dd = new DropDown( $('#dd') );
$(document).hover(function() {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});
</script>
I think this should work:
$(function() {
var dd = new DropDown( $('#dd') );
$('.wrapper-dropdown-3').hover(function() {
$(this).toggleClass('active');
});
});
If got any issues, say so.
Try:
obj.dd.on('mouseenter', function(event){
$(this).toggleClass('active');
return false;
});
obj.opts.on('mouseleave',function(){
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
obj.placeholder.text(obj.val);
});
If I am not mistaken, the hover() function looks for mouseover and mouseoff events. Why would you want the menu to only change when your mouse is over an item at the top? Once you mouseoff it will change. I recommend using just mouseover, and then a mouseleave instead of hover.
I am trying to be able to tab through these tooltip as a part of my tab order on my page but the tabbing stops at the first tooltip. Is the problem with the try catch statement in my Javascript code?
landingTooltip = {
locked :false,
initialize: function(){
if (dojo.byId('pickup-cycle')){
this.buttons = dojo.query('.button-link', dojo.byId('pickup- cycle'));
}
else{
return;
}
var _this = this;
dojo.forEach(
_this.buttons,
function(obj){
Hoverable.disconnect(obj)
domExtender.connect(obj,"onmouseenter",function(e){
_this.show(domExtender.closest(obj, '.step'), obj);
});
// dojo.connect(obj,"onmouseleave",function(e){
// _this.hide(domExtender.closest(obj, '.step'), obj, null);
// });
domExtender.connect(dojo.query('a', obj)[0],"onfocus",function(e){
_this.show(domExtender.closest(obj, '.step'), obj);
});
}
);
},
show: function(el, t){
if (this.locked == true){
return;
}
this.locked = true;
var t = t;
var _this = this;
dojo.addClass(dojo.query('span', t)[0], 'hover');
this.tt = dojo.query('.tool-tip', el)[0];
var placed = dojo.place(
_this.tt,
dojo.body(),
'first'
);
dojo.style(_this.tt, 'display', 'block');
_this.tt.focus();
var setFocus = dojo.query('h5', placed)[0];
setFocus.focus();
this.inst = dojo.connect(_this.tt,"onblur",function(e){
if (domExtender.closest(e.target, 'div.tool-tip') == null) {
_this.hide(domExtender.closest(t, '.step'), t, true);
}
});
this.inst1 = dojo.connect(dojo.body(), 'onclick',function(e){
//alert(domExtender.closest(e.target, 'div.tool-tip'));
if (domExtender.closest(e.target, 'div.tool-tip') == null){
_this.hide(domExtender.closest(t, '.step'), t, true);
}
});
},
hide: function(el, t, blur){
// if (this.locked == true){
// return;
// }
this.locked = true;
var _this = this;
if (this.inst){
dojo.disconnect(_this.inst);
}
if (this.inst1){
dojo.disconnect(_this.inst1);
}
dojo.removeClass(dojo.query('span', t)[0], 'hover');
var placed = dojo.place(
_this.tt,
el,
'first'
);
dojo.style(placed, 'display', 'none');
_this.locked = false;
try {
var setFocus = domExtender.next(el);
setFocus.focus();
} catch (e) {
}
}
}
Install firebug
Set a breakpoint
See what exactly is causing tab order to break.
Report a new specific question here.