JQuery .click() event, very odd behavior in IE 8&9 - javascript

I've created a video gallery which loads a Youtube video via swfobject, based on the element's data attributes. It functions quite well in all browsers, except IE. The strange behavior I am seeing doesn't make sense.
The markup for each thumbnail is as follows:
<li>
<div class="movie-image">
<a class="" data-videotitle="Title" data-videoid="$node.contribution('video')" href="http://www.youtube.com/watch?v=41ZskpgQqZ4">
<img class="video-link" data-videotitle="Title" data-videoid="41ZskpgQqZ4" src="http://img.youtube.com/vi/41ZskpgQqZ4/default.jpg" alt="Title">
<h5>Title</h5>
</a>
</div>
</li>
With this javascript binding the event:
$('.video-link').click(function(){
player.setVideo(this.getAttribute("data-videoid"), true);
player.setTitle(this.getAttribute("data-videotitle"));
window.event.returnValue = false; //IESUX
if(window.event.stopPropagation) window.event.stopPropagation();
window.event.cancelBubble = true;
//Yes, there's a lot of redundancy here. None has worked.
return false;
})
Now, here's the weird part: When I click a link in any browser except IE, the event works fine.
However, in IE, if I click on the h5 element, everything works fine. If I click on the image, however, the browser navigates to the thumbnail. Which is really odd, since that's not even the target of the link.
EDIT: I forgot to mention, I am stuck using JQuery 1.4.2 on this particular webpage.
Edit 2: Well... crap. I just tried putting together a fiddle to show the problem, but the fiddle is working fine, even with the old version of JQuery.

jQuery wraps the event object and gives it methods that do what you're trying to do only better:
$(".video-link").click(function (e) {
player.setVideo(this.getAttribute("data-videoid"), true);
player.setTitle(this.getAttribute("data-videotitle"));
e.stopPropagation();
e.preventDefault();
});
Note that return false is explicitly left out -- you don't need it.
My guess is that IE is either throwing some sort of error that stops the JS execution and ends up following the link, or the default action is not properly being stopped.

Related

jQuery .on() not binding/refreshing correctly

In my HTML, I have a div:
<div id='layerList'>
</div>
In my JavaScript, I dynamically append several items to this div, for example:
$('#layerList').append("<a class='lays dropdown-item' href='#'> This is an example </a>");
So far, everything works fine. My menu is built dynamically.
When I click on the different menu items, I want to change the active state and do other things, but it's not working — the menu items don't change state. Below is the click event handler:
$("#layerList").on("click", '.lays', function () {
console.log("test") // this works, I can see it
$(".lays").removeClass("active"); // this does not work
$(this).addClass("active"); // this does not work
// other stuff, doesn't work
});
Note that this code works just fine if I add the menu items in my HTML (i.e., if I do not create them dynamically).
What am I doing wrong?
There are two ways of achieving the same effect.jQuery:You can achieve the same effect using the shorthand .click method on the jQuery prototype. Attaching the event listener to the document and filtering through children is slow and will keep getting slower as your page size increases. Let me show you the code I have used.
$(".lays").click(function(e) {
$(".lays")
.removeClass("active");
$(this)
.addClass("active");
// other stuff
return false;
});
.lays.active {
color: red;
}
<div id='layerList'>
<a class='lays dropdown-item' href='#'> This is an example </a><br><a class='lays dropdown-item' href='#'> This is an example </a>
</div>
Using the buit-in javascript DOM API:
If you want a faster solution that does not need external libs, then accessing the DOM API might be better for you. The syntax is longer than jQuery's and doesn't have method chaining
so you'll end up with a bit more code than jQuery.
[].slice.call(document.getElementsByClassName("lays")).forEach(function(element) {
element.addEventListener("click", function(event) {
[].slice.call(document.getElementsByClassName("lays")).forEach(function(element) {
element.classList.remove("active");
});
element.classList.add("active");
//other stuff
return false;
});
});
.lays.active {
color: red;
}
<div id='layerList'>
<a class='lays dropdown-item' href='#'> This is an example </a><br><a class='lays dropdown-item' href='#'> This is an example </a>
</div>
Using [].slice.call turns an iterable object into an Array.
If you wanted to add support for older browsers, then I recommend adding a polyfill for the Array.from method.
Anyway, the code does work, so I'm not sure what's happening on your computer. Have you tried using Incognito Mode or the Guest account on Chrome, or Safe Mode on Firefox? Check all your extensions, as it is working fine in my browser (Google Chrome) right now. Good luck to you! :)
try a this way $("#layerList").on("click", 'a.lays', function () {
$("#layerList").on("click", 'a.lays', function () {
$(".lays").removeClass("active");
$(this).addClass("active");
// other stuff
});

jquery html update working on computer but not on smartphone

I'm using following-like code on my website
<span class="box">
<noscript>
<img src="images/imagebox.png">
</noscript>
</span>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
$(document).ready(function() {
$('span.box').html('<img src="images/imagebox.png">');
$(document).on('click','span.box', function(){
// rest of code
});
});
as you can see, i built it the way if the client has javascript, the content of is replaced by without link so it's more interactiv for the client and if the client has no javascript, he still has with the link the way he can still make the necessary action...
While this works perfectly without any trouble on the computer, on smartphone (at least mine), it doesn't work but i don't know why... actually, on my smartphone, i can't see the and can't do any action as if it wouldn't have javascript while it has... I have android 2.1 on my smartphone...
Do you know any solution or workaround for this, the way i can have this and necessary action ability even on smartphone?
Thanks in advance for your help!
EDIT: I finally opted for a solution like in JavaScript function in href vs. onclick
All mobile devices don't handle click events.. should be:
$('<img />').attr('src', 'images/imagebox.png').appendTo('span.box').bind('click touchstart', function() {
// handle click / touch
});
also see this post about double trgiggering issue in some touch enabled devices:
How to bind 'touchstart' and 'click' events but not respond to both?
try to use
$(document).on('pageinit', function(){}); or $(document).on('mobileinit', function(){}); instead of
$(document).ready(function(){});

Javascript hide/show toggle works both ways in Opera, but only one way in other browsers

I have a customized show/hide toggle script that I'm using along with CSS3 transitions for the effects.
The script shows the content when clicked, and hides it when the 'HideLink' link is clicked, complete with CSS3 transistions - but only in Opera.
In other browsers the script only works for showing the content, clicking the hide link doesn't work.
See this JSfiddle: http://jsfiddle.net/xte63/
These days with show / hide javascript, I prefer to use HTML5's data-* attributes.
This can already be used in non-HTML5 browsers via the getAttribute and setAttribute function.
I've quickly tried it against IE7, Chrome and Opera and it seems to work.
http://jsfiddle.net/ThJcb/
function showHide(shID) {
var exDiv = document.getElementById(shID);
if(exDiv.getAttribute("data-visible") != 'false'){
document.getElementById(shID+'-show').style.cssText = ';height:auto;opacity:1;visibility:visible;';
document.getElementById(shID).style.cssText = ';height:0;opacity:0;visibility:hidden;';
exDiv.setAttribute("data-visible" , 'false');
} else {
document.getElementById(shID+'-show').style.cssText = ';height:;opacity:0;visibility:hidden;';
document.getElementById(shID).style.cssText = ';height:auto;opacity:1;visibility: visible ;';
exDiv.setAttribute("data-visible" , 'true');
}
}
This allows you to determine the state of the div without having to check for CSS values.
EDIT: As pointed out in the comments, a typo was on the hide link (onlick instead of onclick) which made it appear the above jsfiddle worked whereas it didn't. At least not exactly as I made an error in the logic, setting the "data-visible" to false instead of true.
Here's an updated jsfiddle: http://jsfiddle.net/ThJcb/4/
(javascript snippet above updated also)

How does one disable Caching in jQuery Mobile UI

Tried...
<div data-role="page" data-cache="30">
<div data-role="page" data-cache="never">
<div data-role="page" data-cache="false">
<div data-role="page" cache="false">
Nothing seemes to work... so at the moment I'm fixing the problem on the server-side via...
.'?x='.rand()
.'&x='.rand()
I don't want to disable the AJAX just the caching. There has to be a better way though... am I missing something?
Thanks,
Serhiy
Thank you for the answers guys, and even though they didn't quite work for me they did point me in the direction to find the code I was looking for.
This is the code that I found on this gentleman's Github Gist.
https://gist.github.com/921920
jQuery('div').live('pagehide', function(event, ui){
var page = jQuery(event.target);
if(page.attr('data-cache') == 'never'){
page.remove();
};
});
There is also a back button code in that Gist, but I don't seem to need it really as my back button seems to work just fine...
Page caching is now off by default in jQM RC1. See the extract below from the jQM website about page caching: http://jquerymobile.com/demos/1.0rc1/docs/pages/page-cache.html
If you prefer, you can tell jQuery Mobile to keep previously-visited pages in the DOM instead of removing them. This lets you cache pages so that they're available instantly if the user returns to them.
To keep all previously-visited pages in the DOM, set the domCache option on the page plugin to true, like this:
$.mobile.page.prototype.options.domCache = true;
Alternatively, to cache just a particular page, you can add the data-dom-cache="true" attribute to the page's container:
<div data-role="page" id="cacheMe" data-dom-cache="true">
You can also cache a page programmatically like this:
pageContainerElement.page({ domCache: true });
The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.
Have you tried to overwrite the default value ?
$(document).bind("mobileinit", function(){
$.mobile.page.prototype.options.domCache = false;
});
This works for me
Method 1
This disables AJAX
Read
http://jquerymobile.com/demos/1.0a2/#docs/api/globalconfig.html
Set ajaxLinksEnabled to false and it will not load and cache those pages, just work as normal links.
Method 2
Second idea is to remove cached elements. You can bind to pagehide event and make it remove the page instead. If not present in DOM, the page will be loaded again.
It can be done with this code as a proof of concept:
$('.ui-page').live('pagehide',function(){ $(this).remove(); });
But it needs a little work. The above code breaks the history. It prooves that you will only be able to use it with pages you intend to be leaves in your sitemap tree. Therefore you have to create a special selector for them or bind it to only certain pages.
Also you can bind to a button's click or mousedown event, get its href, generate page id out of it and find the div by id to remove it before jqm tries to look for it.
I have found no advised way of disabling the cache or forcing loading.
Martin's answer should be the right one in my opinion but jQuery Mobile cache the first page no matter what. https://github.com/jquery/jquery-mobile/issues/3249
I've opted to "patch" the behaviour of $.mobile.page.prototype.options.domCache = false and data-dom-cache="true"
$(document).on('pagehide', function (e) {
var page = $(e.target);
if (!$.mobile.page.prototype.options.domCache
&& (!page.attr('data-dom-cache')
|| page.attr('data-dom-cache') == "false")
) {
page.remove();
}
});
Here's my working solution:
$('.selector').live( 'pagebeforecreate', function () {
$.mobile.urlHistory.stack = [];
$.mobile.urlstack = [];
$( '.ui-page' ).not( '.ui-page-active' ).remove();
});
I wrote an (original in German) article about that topic, maybe that helps.
Link to google translated article

Image resize handles in IE's contenteditable mode

How can I selectively turn off image resize handles in IE 7+'s contenteditable mode? I've tried setting the image's contentEditable to false and its onresizestart to "return false" to no avail.
I'm using tinyMCE.
Set unselectable="on" for your images. Works for older IEs, but is lately deprecated.
I was using the advimagescale plugin in tinyMCE to stop all images from being resized.
However, I found it stopped images from being dragged and dropped into an editor instance.
I found I could strip the size attributes on mouseup using:
setup : function(ed) {
ed.onMouseUp.add(function(ed, e) {
if (e.target.nodeName == "IMG") {
e.target.removeAttribute("width");
e.target.removeAttribute("height");
}
});
}
I would dearly love to get rid of those damn handles though.
This took pain, time and luck to find: You want the 'controlselect' event to remove the resize handles in IE.
element.oncontrolselect = function () { return false; };
The above line of code worked for me (caveat: Not using TinyMCE, but then, this seems to be a contentEditable headache, not a specific TinyMCE one). You need to set this handler on any element you want to not have these drag handles (in my case, images).
You can disable the function of the handles by defining a behaviour file. I couldn't find anything which would let you hide the handles. The result of the code below is that dragging the handles has no effect.
noresize.htc:
<public:component lightweight="true">
<script language="javascript">
function CancelEvent()
{
return false ;
}
this.onresizestart = CancelEvent ;
this.onbeforeeditfocus = CancelEvent ;
</script>
</public:component>
Then in css:
img.noresize {
behaviour:url(/css/noresize.htc);
}
Note that you'll need to get that url() path right. Add the css class to the images you want to selectively disable.
This article has an alternative .htc file which didn't work for me:
http://nickw101.wordpress.com/2011/02/25/disabling-image-resizing-in-ie-contenteditable-elements/
Just the best fix ever:
<div contenteditable="true">
<label contenteditable="false"><input/></label>
</div>
or any html element that wraps your input/img
Works like a charm on IE11 with img too.
Often you will not want the resize functionnality for any element to be accessible. You can set the onresizestart handler of the contenteditable container so it cancels any resize.
That is:
<div id="editor" contenteditable="true" onresizestart="return false;">
<img src="..." />
</div>
Or with JS:
var editor = document.getElementById('editor');
editor.onresizestart=function(){return false;}
That will not hide the handles but the users will not be able to resize the element, whatever type it is.
Hope this helps!

Categories

Resources