Is hover from jquery to backbone code - javascript

I want to translate this into backbone event model, avoiding using directly jquery.
$(".class").is(":hover")
What I have tried in my view is register an event (mouseenter, mouseleave), but seems that the events are being intercepted before by another component probably because it have stopPropagation or for an uncertain reason I don't receive it. I need to have something like this.
if($(".class").is(":hover")){
//execute this code.
}
What I tried to do is using event handlers to intercept the hover on a specific element change a flag, and change the condition to use that flag.
if(flag){
//execute this code.
}

You're looking for the mouseover javascript event.
If the event bubbling is stopped by stopPropagation, rethink using stopPropagation as it causes all sort of problems.
Here's a simple backbone view using the event.
var View = Backbone.View.extend({
events: {
"mouseover .specific-element": "onMouseOver"
},
onMouseOver: function(e) {
// do stuff
}
});

Related

Angular not listening to jQuery triggered events and vice versa

Angular5#latest here, I have several components that are using several javascript with jQuery plugins and I need them, but when the dom is modified by such plugins angular bindings does not update their values and also vice versa. The same thing happens when the dom is modified by a change in angular variables.
I came up with this rough solution:
$('*').each(function()
{
$(this).on("change",
(event)=>
{
event.preventDefault();
event.stopPropagation();
if(event.detail!=="ng")
{setTimeout(()=>{this.dispatchEvent(new CustomEvent("change", {detail: "ng"}));},0);}
});
});
for some reasons events fired using trigger() are only listened in jQuery but events fired using dispatchEvent() are listened by both.
And to do it in reverse I found nothing better than manually trigger specific events like:
jq_update()
{
$('.select-chosen').each(function(){setTimeout(()=>{$(this).trigger("chosen:updated", true, true);}, 0)});
$('.datepicker').each(function(){setTimeout(()=>{$(this).trigger("oninput", true, true);}, 0)});
}
Is there a better solution to these issues? using ChangeDetectorRef and Zone does absolutly nothing and I wonder why...

Binding a click event to content loaded via AJAX without making it delegated?

I have a situation where I am using the data attribute named data-command in many instances throughout a specific section of a site and instead of binding tons of separate click events I decided to just use the one and use a switch such as:
$('[data-command]').on('click', function(event) {
// Prevent default click action
event.preventDefault();
// Get command
var command = $(event.target).data('command');
switch (command) {
// Do stuff...
}
// Prevent default click action (IE 8)
return false;
});
However it has just become an issue when trying to get it to work on data loaded via AJAX.
This obviously works..
$('#existing_element').on('click', '[data-command]', function(event) {
...but since it is supposed to work on many different pages in that section of the site the above wouldn't work on all pages.
I could just make sure to give a specific id to the parent wrapper where I load all my ajax data, but that would mean making two separate binding events with a bunch of the same code.
I also could do this to cover all bases..
$(document).on('click', '[data-command]', function(event) {
...but that's probably not such a wise idea binding an element to the document.
Edit: Html data is being loaded into the DOM via jQuery's html method.
Any clean way I can handle this or should I just create two different binding events to handle each situation?
Event delegation is the best approach to bind events on dynamically created elements. Since you don't want to use event delegation, use following approach to bind events.
$('[data-command]').off('click').on('click', clickHandler);
// Somewhere in the same scope
function clickHandler(e) {
// Handle click event here
}
Add this after the dynamically created elements are added using html().
off('click') will first unbind the click event handlers that are applied previously and then on('click', will bind the click handler on all the elements matching selector.
Edit
This seems to be repeating the same code again and again. Can't I keep it DRY?
Yes, you can keep the code DRY and clean by creating a function to bind events and call the same function when you want to bind event.
function clickHandler(e) {
// Handle click event here
}
function bindEvent() {
$('[data-command]').off('click').on('click', clickHandler);
}
$(document).ready(bindEvent);
...
$.ajax({
...
success: bindEvent
....

Famo.us attaching click and touchstart events

I'm wondering how to bind both events "click" and "touchstart" within a single line:
Engine.on("click"), function(){ aCode() }
Engine.on("touchstart", function(){ aCode() }
I expected something like this (as it is implemented in some other frameworks):
Engine.on("click touchstart", function(e){ aCode() });
My current workaround is chaining them:
Engine.on("click", function(){Engine.emit("touchstart")});
Engine.on("touchstart", function() { aCode() }
Is there a better practice for this ? The problem is that click is not caught on iOS nor the touchstart with a mouse on desktop… obviously I would like to handle the event the same way whatever the device.
[EDIT] For handling the click and touchstart->touchend in the same way, just use the FastClick override shim.
just add:
FastClick = require('famous/inputs/FastClick');
then this will also work on tablet:
anElement.on("click", function(){alert("Click caught")})
Another alternative is using this helper:
function onEvent(source, events, callback)
{
for (var event in events)
{
source.on(events[event], function(e) {
callback(e);
});
}
}
Then:
onEvent(Famous.Engine, ["click","touchstart"],function(){});
The on() method in Famo.us only accepts one event type. It doesn't do any jQuery style string processing to determine separate events. In theory you could have an event named get to the chopper
What I do when creating my custom views however is create a bindEvents() function which groups all the event listeners together. The only code in these handlers are other functions. If I wanted to react to two different events in the same way, I'd just use the same function for both of them.
// An example Class demonstrating events - some off-topic parts omitted
function myLovelyHorseButton() {
// Recomended Reading: https://famo.us/guides/dev/events.html
this._eventInput = new EventHandler();
this._eventOutput = new EventHandler();
this._eventInput.pipe(this.sync);
this.sync.pipe(this._eventInput);
EventHandler.setInputHandler(this, this._eventInput);
EventHandler.setOutputHandler(this, this._eventOutput);
/** Set options & variables
/* ...
*/
// create event listeners for this specific instance
_bindEvents.call(this);
};
// bind all the events for the button
function _bindEvents() {
//Call event handlers with this set to owner.
this._eventInput.bindThis(this);
// listen for events
this._eventInput.on('click', _handleClick);
this._eventInput.on('touchstart', _handleClick); //Same as 'click'
};
// Nay to the console on click/touch
function _handleClick(event) {
console.log('Nayyyyy!!!');
};
// create an instance of myLovelyHorseButton
var button = new myLovelyHorseButton;
// We would then add the button to the Render Tree
mainContext.add(button);
There is a big reason why you don't want to do the chaining pattern you're currently using. And that's because by emitting a touchstart event on a click, you're inferring that there's going to be some code there to act upon it. One day you might get drunk and decide "Nobody on touch devices is using this!" and delete the ontouchstart handler. And in an instant, your code doesn't work for anybody, touch or mouse.
TL;DR There is nothing wrong with using multiple on() calls.
I hope this helps.

Meteor JS: How should I bind events to the window in Meteor?

I am trying to detect a mouseup outside of a window in Meteor. I tried this, but window doesn't seem to work:
Template.layout.events({
'mouseup window' : function(e) {
console.log("mouseup");
}
});
How should I bind events to the window in Meteor?
The code snippet below will bind the event handler when your template is created and unbind when your template is destroyed. Should give you the behavior you're looking for.
var layoutMouseUpHandler = function(e) {
console.log('window.mouseup');
};
Template.layout.onCreated(function() {
$(window).on('mouseup', layoutMouseUpHandler);
});
Template.layout.onDestroyed(function() {
$(window).off('mouseup', layoutMouseUpHandler);
});
Note that the event is bound in the onCreated handler, so there's a chance the template will not have been rendered yet when the event fires. If your handler interacts with the DOM, you will need to check for that. It is not bound in the onRendered handler because that would cause your mouseup handler to be bound multiple times if the template were re-rendered.
Edit: As Serkan mentions below, the new UI engine only calls onRendered once when the template is inserted into the DOM. This makes it a better choice than onCreated if your event handler will interact with the DOM.
This is not the typical Meteor use case, and Meteor doesn't provide any special helpers for such behavior (at least at this moment). So use typical jQuery solution for that. Just make sure that it's wrapped in Meteor.startup().
Meteor.startup(function() {
$(window).mouseup(function() {...});
});
Meteor is almost 1.0 and will be shipping a new ui engine. According to the meteor wiki, the new engine already exposes document body for events.
UI.body.events({
'mouseup': function () {
console.log("mouseup");
}
});
These threads in the google group will help you pinpoint any current problem areas and suggestions on how to solve them.
You can use the onRendered and onDestroyed callbacks to register the helper.
var mouseEvent = function (e) {
console.log(e.clientX, e.clientY);
}
Templates.myTemplate.onRendered(function () {
$(window).on('mousemove', mouseEvent);
});
Template.myTemplate.onDestroyed(function () {
$(window).off('mousemove', mouseEvent);
});

How to change all onClick events to TouchStart on iOS?

OnClick event has a timeout ~400ms before executing on iOS-browser (demo). And I want to change it to TouchStart event for all DOM-elements who have onClick. How can i make it?
I use jQuery and i tried check all elements for click function:
$('*').each(function() {
if($(this).click != null) {
// BUT all elements in DOM has click
}
})
I don't have an exact answer, but I think you should be able to make this do what you want.
For every element on your page that has an OnClick, add a class - say TouchTarget. Then use this in your startup function.
$('.TouchTarget').bind('touchstart', function (e) {
e.preventDefault();
touchStart(e, this);
});
Create a handler function that looks like this:
function touchStart(pEvent, pElement) {
//Do something with the touch.
}
If you only want to register if touch is available, then you can protect the bind call with
if (Modernizr.touch) {
}
I believe the reason for the delay in OnClick is because Safari is waiting to see if the touch is really a click or a drag, or some other gesture. This will recognize a simple touch quickly. I normally bind both touchstart and touchend when I need quick touches so that touchstart provides visual feedback and then touchend does something with the "click". This method does not have a delay built in.
Use a product like http://www.jqtouch.com/ or the code snipped provided here: http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone.

Categories

Resources