Jui Slider removing key events - javascript

I have a issue not sure how complicated it is but I have been unsuccessful in finding a solution and I have spent some considerable time troubleshooting and Googling resolutions.
Here is my issue, I have a jQuery UI Slider on my page.
I insert a new value using Ajax and it basically rebuilds the Slider.
All that works perfect. The problem is any key bindings I had are removed. (I know the solution for this).
The problem comes where I remove a mouse event prior by changing it at the root of the widget.
I cannot just recall this after the Slider is rebuilt, I don't understand why but it just doesn't work as it did on the first page load.
Here is my code to disable the Slider click tracker.
// Disable the mouse tracking for ui-slider-handle(s)
$.widget('ui.slider', $.ui.slider, {
_mouseCapture: function(e) {
return (!$(e.target).is(this.element)) ? this._super(e) : false;
}
});
Nothing in there is specific to the slider itself since this changes the slider widget itself.
Just to be clear I am only looking at removing a certain binding mouse event to the Jui Slider.
The above code works at doing that, but it won't work once I rebuild the slider with a new value via Ajax.
$('#slider').unbind();
The above unbind() function removes all bindings and makes the slider not functional, just visual.

I solved it by adding 2 lines in my framework as framework specific code for Yii.
Yii::app()->clientScript->scriptMap['*.js'] = false;
Yii::app()->clientScript->scriptMap['*.css'] = false;
It doesn't allow for the scripts to get reinitialized on the page.

Related

JS/Jquery: Initiate window resize without actually resizing

So I have a very specific problem that presented itself recently (right before our planned launch day tomorrow) and I am not completely sure how to solve it. I have built our website of an HTML-template with my modest front-end skills and we are very pleased with it. However, I can't seem to solve this.
The problem:
I have a filter system that allows a user to filter articles that are presented on a page. A user can even fill in this filter on the home page, direct to the page with the articles and have the filter applied. However, if then the filter is broadened (less strict) and new articles present itself, the pictures do not show up. Found out this is the case because the flexslider behind it has to be initialized again which happens on a window load (e.g. when the window is resized). The function that controls the initialization of the flexslider is in an external js file and I am not sure whether I can call on it from my own custom.js file, so I am thinking of just calling a resize/reload window function to active it.
The question:
Can I run a resize window function (or something that activates the flexslider) without hindering user experience (more specifically, without ACTUALLY resizing/reloading the window)? I will run this on a change in the filter.
I know this is a very specific question but hopefully somebody can help me out.
Take care!
p.s. it would be ideal if I could run the actual function that loads the flexslider but this is located in an external js file.
EDIT:
Briefly some additional info. If I go straight to the article page, it has no filter active and thus shows all articles, if I then start flipping through the filter, all is good. It is however only if I arrive from the homepage with a set filter that the problems arise. You then arrive on the article page which shows only the articles that are within the boundaries, and when the filter is taken away it has problems loading the images of the new articles showing up. As if it had not loaded these because they were not open on window load the first time.
You can trigger a resize event by creating a new event and passing it into the dispatchEvent command on window. There's a nice guide here. You'll want the type of event to be resize, since that's what it's listening for.
window.dispatchEvent(new Event('resize'))
This will work for events that were added via jQuery as well as events added via addEventListener.
I managed to solve it after all by delaying the function that drops the filter values into my inputs so it loads in all images initially before applying the filter. It happens at such speed it's hardly noticeable.
Also, I did try to initiate a window resize function, it did work without actually resizing anything, but unfortunately the images did not load in properly (overlap and such).
Anyway, it has been solved. Thanks for all the input!

Function returning info to console log, but doesn't actually do what it's supposed to

I have a question regarding a image slider script I'm using called Slippry. I currently have it integrated into a site I’m working on and I've run into an issue. I’m using the following code to stop the slider when one of the images within the slider is clicked:
Javascript Code:
// Stop the slider and log click
$('.stop').click(function () {
slider.stopAuto();
console.log('stopped');
});
HTML Code:
<a class=“stop” href=“#123”>
<img src=“/img/slide.jpg”/>
</a>
If I let the slider play through to the slide and click the slide, it will add stopped to the JS console, but it won’t stop the slider. If I click the pagination, then click the slide, it adds stopped to the JS console and stops the slider.
Why is the function attached to .stop only working when I click the pagination first? Any thoughts?
Thanks to #J.Cheong I found a solution to this problem.
There is a timing issue with the slider.stopAuto function, and the function that transitions the slides. It appears both functions were being called at the same time or close enough that they were conflicting with one another. I added the following:
setTimeout(function(){
slider.stopAuto();
console.log('50ms - Paused');
}, 50);
I repeated calling the script every 50ms for an entire second, thus resulting in 21 calls for slider.stopAuto. This seems to have fixed the issue I was having. Hopefully this offers a solution for others using the Slippry script that might encounter this issue in the future.
NOTE: I just receive a email from one of the developers, and this 'bug' has been reported.

Why is telling jQuery to click my link button slowing my page down?

I don't know if this is the effects of an update panel or what, but I basically have a drop down list that allows a user to select an item as a filter. When the item is selected it should bring back only one item into a grid view. That is this specific filter will at most bring back the record you are looking for. This works fine if the user clicks an "apply" link to apply the filter. Behind the apply link is some server-side code (C# within an ASP.NET Web Forms application).
We had a request by a user with something to the effect of:
"Why do I have to click the apply button if I make a selection in this
one drop down filter...it should simply get that one record I am
searching for. This helps me because I don't have to click the
"Apply" button."
I agreed with him and thought what is the easiest way to do this...I thought: Simple, I will have an on change event handler of the drop down such that when a selection is made I'll trigger a click event. Something to this effect:
$("#MainContent_ddlCompany").on("change", function() {
var companyId = $("#MainContent_ddlCompany").val();
$("#MainContent_hdnCompanyValue").val(companyId);
$("#<%=ddlCompany.ClientID %>").trigger("chosen:updated");
if (companyId.length > 0) {
$(".apply").click();
$(".apply").removeClass("applyButton");
$(".apply").addClass("resetButton");
} else {
//cleared selection of a company
$(".apply").removeClass("resetButton");
$(".apply").addClass("applyButton");
}
});
At first this didn't work, and I couldn't tell why, but then after some serious googling I changed this line:
$(".apply").click();
To this:
$('.apply')[0].click();
That worked great...so I decided to test it some more. As I kept selecting one filter value after another I noticed the page started to slow down. In fact by the 6th or 7th time it was pretty unusable. I don't know why it's happening, but I suspect again it has to do with the fact that this linkbutton with the class name .apply is inside an update panel.
But still I thought to myself, it was inside of an update panel before I changed my jQuery code to simulate the click event. So why does the page slow down and drag with this little piece of code? Is calling the event from jQuery code rendering something else in the HTML that could be causing this?
If I change my code back and force the user to click the apply button then we are back to a good normal speed. Why is it if I tell jQuery to simulate clicking the button my page slow down? It's doing the same thing, the simulation of the click of this link button is calling its server-side code method whether the user clicks it or I have jQuery click it.
For now I'm at a loss as to why this is happening because this button is in an update panel in either case, yet when I have jQuery click it via $('.apply')[0].click(); the page slows down after several attempts. Yet when I have the user simply click this button (without the jQuery click event) then it works fine?
What am I missing here?
Ugh, well, I found my issue. Because I was using updatepanels I had to wrap my jQuery code to include an add_endRequest. That is, you have something to the effect of:
$(document).ready(function() {
//Some initial event/triggers
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
//Copy of some initial event/triggers
});
});
Why do I use the endRequest you ask? Well, because updatepanels basically throw away all your events after an asynchronous postback because the HTML at that point (after an update) is rendered again and at that point all events associated with any control inside an update panel are wiped away. At this point of course document.ready() does not run, so I have to resubscribe to these events inside of endRequest. Enter my issue...
I had a huge brain fart where I basically took everything, literally everything inside document ready and copied it into endRequest. In fact, if I remember correctly, I read articles which stated
Whatever you have in document ready simply copy paste into endRequest
That's fine, but you have to be careful here. I was throwing in events that were not wrapped around inside of an updatepanel into endRequest. The result is disastrous...at least for me.
These events would be attached then multiple times..or based on the number of asynchronous postbacks made. In my case, as I was testing I mentioned after the 6th or 7th time performance starts degrading. Well, by that time my controls were being attached that many times to events. For instance, my .apply button along with my dropdownlist were both outside of my updatepanel. But my jQuery code was attaching the change event of my dropdownlist in both document ready and endRequest.
The result is initially it's pretty fast, because it's only in document ready. But as I make asynchronous postbacks these events are being attached every time. For n tests I would have n attached events...in my case the test of 7 yields 7 on change event handlers!
Case in point, do not place any event handlers such as jQuery's on() event for any controls that are NOT inside an update panel. Otherwise you will run into what I ran into which was poor performance as events are happening.

Handler & current time with video.js

I'm working on new skins for my video.js player. I already added un handler. Now, I want to add the current timer on it which has to follow the progress bar.
There are two prototypes: one for the handler and the other for the timer. How can I add the timer into the handler ?
If you're referring to just the currentTime, you can listen to the timeupdate event. Assuming you've got a reference to your player:
player.on('timeupdate', function() {
// do whatever you want with the time update
});
That being said, if all you're working on is building a new skin, you're throwing away a lot of work already done for you by not simply styling elements that are already in place. CurrentTimeDisplay will already handle keeping the vjs-current-time class updated.
My suggestion would be to try and get as far as possible using nothing but CSS, then when you find yourself limited move on to JS. If you get to the point you need extra listeners, the events documentation are going to be the first place you'll want to look.

jqm Stop tap events queuing when busy

I am creating an app using jQuery Mobile and PhoneGap.
I "delegate" a button on "tap" to perform some heavy processing and display a loading spinner. If users continue to tap on my app, the taps get queued up and fall through to be processed by the app after the heavy processing completes - and end up clicking on unwanted stuff.
How can I prevent this?
(From what I understand, stopImmediatePropagation doesn't help as these are new user events.)
Thanks
To inactive taps on the whole page you could overlay the whole page with a transparent div. Although it might be considered a borderline hack - this would actually use minimal js and css!
The caveat is that it would not give any visual indicator that the page is inactivated.
To do that one could, use a semitransparent gray for the overlay or, as I've done below, show a loading message.
First off, a small CSS discussion:
To make the div cover the whole page set width and height 100%. To position it correctly, use position:absolute and for the transparent background use an rgba background-color property (see below). You should also declare a z-index (can be increased if needed) to ensure that it goes on top of everything else and remove tap-callout using the -webkit-tap-highlight-color property. Set display to none and then show it during your heavy lifting.
I made a jsfiddle which hopefully clears things up.
Here I've made div with an id of "inactivator" which features the properties discussed above.
I've also made a button with an id of "inactivate" to which I've delegated jQuery's show function.
I also took the liberty to add jQuery Mobile's default loading message to show simultaneously just to give a visual indicator of the app thinking (so it's not mistaken for lag).
Here I've added a timeout function so that the loading message and "inactivator" hides after 5 second. Obviously in your case the same code should instead be fired upon completion of your "heavy processing" rather than after five seconds.
(New, additional answer since I didn't understand the question correctly but the old answer still might be helpful to other people.)
The easiest way I can think of is inactivating the button at the start of your javascript function and then reactivating it when it's suitable:
$('#YourButton').addClass('ui-disabled');
At the end of your function (or whenever you'd want it active again:
$('#YourButton').removeClass('ui-disabled');
So it took me a while to figure it out... you have to return FALSE from the delegate function for parent elements to ignore the event. The return false line below fixes my issue:
$(document).delegate("#finish", "tap", onFinish);
var onFinish = function() {
$.mobile.loadingMessage = "Finishing...";
$.mobile.showPageLoadingMsg();
setTimeout(function(){
HEAVYPROCESSING();
$.mobile.changePage($("#choosearticle"));
}, 50);
return false; // important - stops the two click fall through problem!
}

Categories

Resources