Some part of Javascript code stopped working in latest Chrome update - javascript

I bought some files through codecanyon.net and they've been working fine on all browsers. Just recently I noticed they weren't working in Chrome.
The code is really big and I've tried to change some things through trial and error on the js file but was unsuccessful. You can see the slider at http://miguelsart.com/scroller-test.
As you can see, the captions are supposed to be hidden and once you hover they have slide up. But with Chrome, the captions appear automatically and nothing happens when you hover.
I think something is wrong in this part of the code:
//init captions
Scroller.prototype.initCaptions = function() {
var $captions = this._$slides.find(">p:first");
if (this._displayCaption) {
var padding = $captions.outerWidth() - $captions.width();
$captions.css({width:this._slideWidth - padding, display:"inline-block"}).click(preventDefault);
if (this._captionPos == OUTSIDE) {
var heights = $captions.map(function() { return $(this).height(); }).get();
var maxHeight = Math.max.apply(Math, heights);
$captions.css({top:this._captionAlign == TOP ? 0 : this._slideHeight, height:maxHeight});
this._extHeight = $captions.outerHeight();
if (this._captionAlign == TOP) {
this._extOffset = this._extHeight;
}
$captions.addClass("outside");
}
else {
if (jQuery.browser.msie && parseInt(jQuery.browser.version) > 6 && parseInt(jQuery.browser.version) < 9) {
$captions.addClass("ie-inside");
}
else {
$captions.addClass("inside");
}
}
}
else {
$captions.hide();
}
}
I've tried messing around replacing display for opacity or for visibility but nothing worked. Does anyone have any clue what might be wrong?
Thanks in advance!

I believe I've figured out what's wrong with the author's implementation, and you are correct, it has to do with the latest version of Chrome.
On line 43 of jquery.wt.scroller.js
this._mouseoverCaption = window.Touch ? false : opts.mouseover_caption;
The author of the plugin is testing for native touch capabilities (by determining if window.Touch is defined). Chrome must've recently added native touch API capabilities in a recent version.
So what the author was going for, was saying that 'you can't hover on a touch device, so we can't show the captions on hover on a touch device so we'll just always show them' - which is logically.
However, just because touch capabilities exist, however, doesn't mean that touch input is the default (as in this case). Modernizr solves this issue (for now) by performing the following conditional:
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
Something tells me this will also soon be broken. (https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js#L42)
So, long story short (too late, I know) add this to the plugin code:
Add this to line 7 (push all lines down one):
var TOUCH = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
Find and replace all occurrences of window.Touch with TOUCH in the plugin code.
Tell the author of the plugin I'll send him a bill. :)

Related

Multiple javascript functions on an index page

I am trying to update some existing javascript code in place that navigates the user to a desktop depending on whether their device has Flash or not. However, I now want the option to navigate the user to a Mobile site if the screen width is smaller that 800px.
I have included the code below which is not working and I think I have the characters wrong between the two function requirements. Any guidance would be appreciated.
<script type="text/javascript">
if (screen.width <= 800) {
window.location = "mobile.htm";
}
if ((navigator.appName == "Microsoft Internet Explorer" &&
navigator.appVersion.indexOf("Mac") == -1 &&
navigator.appVersion.indexOf("3.1") == -1) ||
(navigator.plugins && navigator.plugins["Shockwave Flash"])
|| navigator.plugins["Shockwave Flash 2.0"]){
window.location='home_f.htm';
}
else {
window.location='home_n.htm';
}
</script>
I think what is happening is that the code above (with the screen.width and all) is executing properly, but then, while mobile.htm is still loading, the code continues. Because you have Flash, the code below it still executes and before mobile.htm can fully load the browser instead decides to obey the later if statement and go to home_f.htm .
Try creating a function that returns after the first bit, like so:
function redirect() {
if (screen.width <= 800) {
window.location = "mobile.htm";
return;
}
if ((navigator.appName == "Microsoft Internet Explorer" &&
navigator.appVersion.indexOf("Mac") == -1 &&
navigator.appVersion.indexOf("3.1") == -1) ||
(navigator.plugins && navigator.plugins["Shockwave Flash"])
|| navigator.plugins["Shockwave Flash 2.0"]){
window.location='home_f.htm';
}
else {
window.location='home_n.htm';
}
}
redirect();
I'd also like to note that screen.width measures the screen resolution, but if the browser is resized, it will not take into account the browser's new size. It'll take the size of the entire monitor regardless of the size of the browser. If that isn't what you want, read up on measuring the browser width and height here: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
Finally, for what you're doing, that is, detecting mobile devices, you may prefer browser detection to basing it off the screen size. There is a simple way to detect if your user is using Android via a user agent. In your case scenario feature detection is probably not applicable. But do remember to provide a link to the mobile version of the site from your non-mobile version just in case of false positives! You never know.
if(navigator.userAgent.toLowerCase().indexOf("android")!=-1||navigator.userAgent.toLowerCase().indexOf("googletv")!=-1||navigator.userAgent.toLowerCase().indexOf("htc_flyer")!=-1) {
// this person is using Android. Redirect the the mobile site!
window.location = "mobile.htm";
return;
}

event.preventDefault() not working in the keypress event on Android

Most web developers know that to restrict only numbers to a form input, you can do something like this:
$(function() {
$("#foobar").keypress(function(e) {
if($.inArray(e.which, range(48, 57)) == -1) {
e.preventDefault();
return false;
}
});
});
function range(start, end) {
var range = [];
for(var i = start; i <= end; i++) {
range.push(i);
}
return range;
}
Unfortunately, this does not quite get the job done on an Android with the default browser. (iPhone and Other Android browsers have not been tested, so they could suffer from the same issue. Tested on an iPhone 4S, which did not have this issue.)
On an Android, let's say you first type "f". Nothing happens. Awesome. Wait just a minute. You then type "a". What happens? The "f" is put into the input field! You type "c", the "a" is put into the field. And so on. Whatever the previously-entered character is, that's what's put into the field.
Here's a jsFiddle that demonstrates the issue.
The fiddle works fine on a desktop, but try it on Android (phone or emulator). I've tested with Android 2.3.6 and 2.2.
Anyone run into this before? Any direction would be greatly appreciated! For now, the workaround is to remove non-numeric characters immediately afterwards (in the keyup event).
Update: Here is a fiddle that shows that preventDefault() is being reached. The problem seems to be that rather than preventing, it's simply delaying (until the next event).
A completely different approach would be using <input type="number"> and relying on the browser to provide the appropriate interface/filtering (which mobile browsers are prone to). It does not fix the code, but should circumvent the problem, which looks like a bug, to be honest.
A wild guess: Maybe Androids register the input at the keydown stage. You could try both events.
Ok I played with this a bit and this is running fine on my andriod:
var reserved = [0,8]
$(function()
{
$("#foobar").keypress(function(e)
{
if($.inArray(e.which, reserved) < 0 && ((e.which < 48) || (e.which > 57)))
{
e.preventDefault();
return false;
}
});
});
http://jsfiddle.net/HW794/1/embedded/result/
Possible that droid does not like the call to the fn? (range)

IE stop script warning

Only in IE I get a warning when loading my site containing javascript saying that its causing the page to run slowly (and asking if I want to stop it).
I've seen other posts about this and I've looked for any long running code or infinite loops etc. The weird thing is, when I select 'No' (to not terminate the script) the page immediately loads properly. Its almost like this warning comes up right before the page is done loading. Has anybody experienced this, or know why this might be happening?
IE has its own way of making your life impossible.
Just deactivate the warning, you can further research in the future if that's necessary.
This article might help you determine why IE is giving such a warning.
Regards,
Adapted from http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers
// Magic IE<9 workaround for irritating "Stop running this script?" dialog.
RepeatOperation = function(anonymousOperation, whenToYield){
var count = 0
return function(){
if (++count >= whenToYield){
count = 0
setTimeout(function(){anonymousOperation()}, 100)
}
else anonymousOperation()
}
}
// How to implement the workaround:
//for (var i in retailers){ // Too big for IE<9! Use magic workaround:
var i = 0; var noInArray = retailers.length
var ro = new RepeatOperation(function(){
// <<Your loop body here, using return instead of continue.>>
if (++i < noInArray) ro()
else alert("Loop finished.")
}, 200) // Run this in batches of n. 500 is too much for IE<9.
ro()

Get scrollheight cross-browser through Selenium

I'm working on a project which is using Selenium and I'd like to try to get the full web page height cross-browser and cross-platform. IE8 is being stubborn as always, is there anybody who has an idea of how to solve this?
The problem: When you scroll down a page for e.g. 500px and you keep doing this until the bottom of the page, the last scroll will be less than 500px. I need to know how much this last scroll was.
Two ways of solving:
1) Find the offset that has been scrolled each time (works everywhere except IE8)
2) Find the total height of the webpage
I know JQuery's height() function does this but I can't use this function from Selenium RC.
If you know a way of calling JQuery functions through Selenium or any other solution, please tell!
Cheers,
Henry
I've found a solution to my own problem.
When you run tests with Selenium, it starts two windows:
1) The Selenium window executing all the commands
2) The Browser window in which the website is tested.
When you try to get info about window 2 via JavaScript functions, you need to do the following:
selenium.browserbot.getCurrentWindow()
To get the full height of a browser window cross browser via selenium, you'll need following script:
function getPageHeight(){
$scrOfY = 0;
$test = $this->getEval("typeof(selenium.browserbot.getCurrentWindow().pageYOffset)");
if(strcmp($test,"number") == 0) {
//Netscape compliant
$scrOfY = (int)$this->getEval("selenium.browserbot.getCurrentWindow().pageYOffset;");
//scrOfX = window.pageXOffset;
} else if( (bool)$this->getEval("selenium.browserbot.getCurrentWindow().document.body != null") && (bool)$this->getEval("selenium.browserbot.getCurrentWindow().document.body.scrollTop != null")) {
//DOM compliant
$scrOfY = (int)$this->getEval("selenium.browserbot.getCurrentWindow().document.body.scrollTop;");
//scrOfX = document.body.scrollLeft;
} else if( (bool)$this->getEval("selenium.browserbot.getCurrentWindow().document.documentElement != null") && (bool)$this->getEval("selenium.browserbot.getCurrentWindow().document.documentElement.scrollTop != null")) {
//IE6 standards compliant mode
$scrOfY = (int)$this->getEval("selenium.browserbot.getCurrentWindow().document.documentElement.scrollTop;");
//scrOfX = document.documentElement.scrollLeft;
}
if(!$scrOfY || $scrOfY <= 0)
$scrOfY = $this->getEval("selenium.browserbot.getCurrentWindow().document.body.offsetHeight");
return $scrOfY;
}

How can I detect if Flash is installed and if not, display a hidden div that informs the user?

How can I use javascript/jQuery/etc to detect if Flash is installed and if it isn't, display a div that contains information informing the user that they need to install flash?
If swfobject won't suffice, or you need to create something a little more bespoke, try this:
var hasFlash = false;
try {
hasFlash = Boolean(new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));
} catch(exception) {
hasFlash = ('undefined' != typeof navigator.mimeTypes['application/x-shockwave-flash']);
}
It works with 7 and 8.
#Drewid's answer didn't work in my Firefox 25 if the flash plugin is just disabled but installed.
#invertedSpear's comment in that answer worked in firefox but not in any IE version.
So combined both their code and got this. Tested in Google Chrome 31, Firefox 25, IE 8-10. Thanks Drewid and invertedSpear :)
var hasFlash = false;
try {
var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if (fo) {
hasFlash = true;
}
} catch (e) {
if (navigator.mimeTypes
&& navigator.mimeTypes['application/x-shockwave-flash'] != undefined
&& navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
hasFlash = true;
}
}
Use swfobject. it replaces a div with the flash if it is installed.
see: http://code.google.com/p/swfobject/
You can use navigator.mimeTypes.
if (navigator.mimeTypes ["application/x-shockwave-flash"] == undefined)
$("#someDiv").show ();
jqplugin: http://code.google.com/p/jqplugin/
$.browser.flash == true
You should also be able to use..
swfobject.getFlashPlayerVersion().major === 0
with the swfobject-Plugin.
I used Adobe's detection kit, originally suggested by justpassinby. Their system is nice because it detects the version number and compares it for you against your 'required version'
One bad thing is it does an alert showing the detected version of flash, which isn't very user friendly. All of a sudden a box pops up with some seemingly random numbers.
Some modifications you might want to consider:
remove the alert
change it so it returns an object (or array)
--- first element is boolean true/false for "was the required version found on user's machine"
--- second element is the actual version number found on user's machine
Very very minified version of http://www.featureblend.com/javascript-flash-detection-library.html (only boolean flash detection)
var isFlashInstalled = (function(){
var b=new function(){var n=this;n.c=!1;var a="ShockwaveFlash.ShockwaveFlash",r=[{name:a+".7",version:function(n){return e(n)}},{name:a+".6",version:function(n){var a="6,0,21";try{n.AllowScriptAccess="always",a=e(n)}catch(r){}return a}},{name:a,version:function(n){return e(n)}}],e=function(n){var a=-1;try{a=n.GetVariable("$version")}catch(r){}return a},i=function(n){var a=-1;try{a=new ActiveXObject(n)}catch(r){a={activeXError:!0}}return a};n.b=function(){if(navigator.plugins&&navigator.plugins.length>0){var a="application/x-shockwave-flash",e=navigator.mimeTypes;e&&e[a]&&e[a].enabledPlugin&&e[a].enabledPlugin.description&&(n.c=!0)}else if(-1==navigator.appVersion.indexOf("Mac")&&window.execScript)for(var t=-1,c=0;c<r.length&&-1==t;c++){var o=i(r[c].name);o.activeXError||(n.c=!0)}}()};
return b.c;
})();
if(isFlashInstalled){
// Do something with flash
}else{
// Don't use flash
}

Categories

Resources