onnouseover not working in chrome, was working until update - javascript

I have the following function being called via onmouseover on an
function showTooltip(tip, el, evt) {
if (document.layers) {
if (!el.tip) {
el.tip = new Layer(200);
el.tip.document.open();
el.tip.document.write(tip);
el.tip.document.close();
el.onclick = function (evt) { this.tip.visibility = 'hide'; };
el.onmouseout = function (evt) { this.tip.visibility = 'hide'; };
}
el.tip.left = evt.pageX;
el.tip.top = evt.pageY;
el.tip.visibility = 'show';
}
else if (document.all) {
if (!el.tip) {
document.body.insertAdjacentHTML('beforeEnd', '<DIV ID="tip' + tc + '" CLASS="tooltip">' + tip + '<\/DIV>');
el.tip = document.all['tip' + tc++];
el.onclick = function (evt) { this.tip.style.visibility = 'hidden'; };
el.onmouseout = function (evt) { this.tip.style.visibility = 'hidden'; };
}
el.tip.style.pixelLeft = event.clientX + document.body.scrollLeft - 200
el.tip.style.pixelTop = event.clientY + document.body.scrollTop + 10
el.tip.style.visibility = 'visible';
}
}
the call looks like;
<img id="ContentPlaceHolder1_DocumentList1_dg_imgNotes_0" onmouseover="javascript:showTooltip('<b>Pages:</b> 1<br><b>Date:</b> 8/7/2014<br><b>Rep ID:</b> 789',this,event);" src="/applications/Images/icons/no-a.bmp" align="absmiddle" style="border-width:0px;">
with the event of;
onmouseover="javascript:showTooltip('<b>Pages:</b> 1<br><b>Date:</b> 8/7/2014<br><b>Rep ID:</b> 789',this,event);"
this code has been working without a hitch for upwards of a year and still functions correctly in Firefox and IE, but not is Chrome Version 38.0.2125.111 m. I am no expert, but I feel like the declarations are all fine and the information being passed it alright, but when it hits the function it just steps over the if(document.layers) and the else if(document.all) when debugging, however, when in IE and debugging it steps into the else if statement just find and renders the tooltip for the exact same site.
any help would be appreciated.

document.all and document.layers is obsolete. They are no longer supported by chrome.

Related

Is it possible to display the full URL in the tooltip of a Chrome tab (on hover)?

Is it possible to display the full URL of a webpage when hovering over a tab in Chrome, instead of just the domain? And is it possible to do so programatically, not by editing a local configuration in Chrome.
Below are two images comparing tab tooltips in Chrome and IE. I am wondering if it possible somehow to make the tooltip in Chrome display the entire url like IE does instead of just the domain.
Current Chrome tab tooltip:
IE Tab Tooltip:
First: You didn't clarify What are you trying to target and How your app/code written?.
If you want your users focus on your page full title or/and full page URL, Try the below as workaround.
Method #1: using custom tooltip (with mouseout and mouseover events to show & hide title)
var ttl = document.title,
loc = document.location,
fullTitle = ttl + "\n" + loc,
isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
var tooltip = document.createElement("div");
tooltip.style.width = "400px"
tooltip.style.borderRadius = "10px"
tooltip.style.position = "fixed"
tooltip.style.left = "40%"
tooltip.style.top = "3%"
tooltip.style.padding = "15px"
tooltip.style.marginTop = "8px"
tooltip.style.visibility = "hidden"
tooltip.style.backgroundColor = "white"
tooltip.style.zIndex = "9999"
tooltip.style.border = "solid 1px #ccc"
tooltip.innerHTML = "<b>" + document.title + "</b><br/><br/>" + document.location;
document.body.appendChild(tooltip);
if (isChrome) {
document.addEventListener("mouseout", function(e) {
tooltip.style.visibility = "visible"
});
document.addEventListener("mouseover", function(e) {
tooltip.style.visibility = "hidden";
});
}
Method #2: Something like rotational title:
var ttl = document.title,
loc = document.location,
fullTitle = ttl + " - " + loc,
document.title = fullTitle;
if(isChrome)rotaryTitle(50);
function rotaryTitle(speed, tempPause) {
speed = speed || 100;
setTimeout(function() {
var t = document.title;
if (t.length > 1) {
document.title = t.substr(1);
rotaryTitle(speed);
} else {
document.title = fullTitle;
rotaryTitle(speed, 2000);
}
}, tempPause || speed)
}

Extending Touch EventListener to Additional DOM Element

I used a Codrops article/experiment to create an interactive environment for a local group to use at their conferences. The problem with this is the default interaction is not very intuitive. The template used Flickity.js and what seems like classie.js to create this sliding interface I am having trouble with.
The page can be found here:
www.eyeconic.tv/ky-ffa/
Issue: The only way to activate the view-full is by clicking on the html element:
<h2 class=".stack-title">
// After the stack is active you should be able to activate the full view by clicking on the first .stack-item used to create the thumbnail below it. This entire div should be clickable. Users are touching everywhere all over the screen and not actually clicking the title for the desired action. I hope this makes sense.
In other words you should be able to click the stack-title and the image below the title of each stack to pull the stack into the full view mode on the screen. Then click the x or anywhere else on the screen to close the full view.
The following is located in main.js and the reference I found to create the events I am referring to.
//
function initEvents() {
stacks.forEach(function(stack) {
var titleEl = stack.querySelector('.stack-title');
// expand/close the stack
titleEl.addEventListener('click', function(ev) {
ev.preventDefault();
if( classie.has(stack, 'is-selected') ) { // current stack
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
var closeStack = function() {
classie.remove(bodyEl, 'move-items');
onEndTransition(slider, function() {
classie.remove(bodyEl, 'view-full');
bodyEl.style.height = '';
flkty.bindDrag();
flkty.options.accessibility = true;
canMoveHeroImage = true;
});
};
// if the user scrolled down, let's first scroll all up before closing the stack.
var scrolled = scrollY();
if( scrolled > 0 ) {
smooth_scroll_to(isFirefox ? docElem : bodyEl || docElem, 0, 500).then(function() {
closeStack();
});
}
else {
closeStack();
}
}
else if( canOpen ) { // stack is closed
canMoveHeroImage = false;
classie.add(bodyEl, 'view-full');
setTimeout(function() { classie.add(bodyEl, 'move-items'); }, 25);
bodyEl.style.height = stack.offsetHeight + 'px';
flkty.unbindDrag();
flkty.options.accessibility = false;
}
}
else if( classie.has(stack, 'stack-prev') ) {
flkty.previous(true);
}
else if( classie.has(stack, 'stack-next') ) {
flkty.next(true);
}
});
titleEl.addEventListener('mouseenter', function(ev) {
if( classie.has(stack, 'is-selected') ) {
canMoveHeroImage = false;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
imghero.style.transform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
}
});
titleEl.addEventListener('mouseleave', function(ev) {
// if current stack and it's not opened..
if( classie.has(stack, 'is-selected') && !classie.has(bodyEl, 'view-full') ) {
canMoveHeroImage = true;
}
});
});
window.addEventListener('mousemove', throttle(function(ev) {
if( !canMoveHeroImage ) return false;
var xVal = -1/(win.height/2)*ev.clientY + 1,
yVal = 1/(win.width/2)*ev.clientX - 1,
transX = 20/(win.width)*ev.clientX - 10,
transY = 20/(win.height)*ev.clientY - 10,
transZ = 100/(win.height)*ev.clientY - 50;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
imghero.style.transform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
}, 100));
// window resize
window.addEventListener( 'resize', throttle(function(ev) {
// recalculate window width/height
win = { width: window.innerWidth, height: window.innerHeight };
// reset body height if stack is opened
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
bodyEl.style.height = stacks[flkty.selectedIndex].offsetHeight + 'px';
}
}, 50));
// Flickity events:
flkty.on('cellSelect', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
var prevStack = stacksWrapper.querySelector('.stack-prev'),
nextStack = stacksWrapper.querySelector('.stack-next'),
selidx = flkty.selectedIndex,
cellsCount = flkty.cells.length,
previdx = selidx > 0 ? selidx - 1 : cellsCount - 1;
nextidx = selidx < cellsCount - 1 ? selidx + 1 : 0;
if( prevStack ) {
classie.remove(prevStack, 'stack-prev');
}
if( nextStack ) {
classie.remove(nextStack, 'stack-next');
}
classie.add(stacks[previdx], 'stack-prev');
classie.add(stacks[nextidx], 'stack-next');
});
flkty.on('dragStart', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
});
flkty.on('settle', function() {
classie.add(bodyEl, 'item-clickable');
canOpen = true;
});
}
init();
})();
I wrapped the title and the first stack item in a div class .touch-me and it worked fairly well. I had previously tried to do this and received an error. But I may have mistyped something because it only made sense.
ISSUE: It works on mouseclick, but it is not working with touch on windows. I have untested it in any other environment because it will be deployed on a windows touch screen.
Although I cannot tell the layer not to close on touch when you swipe or touch the header image for the stack.... I'm afraid I do not have the skillset to properly modify the logic in the javascript since I do not entirely understand the plugins being used.

Copying an element with all it’s attributes - Update

UPDATE 4
Hi #Paul. I think I know what's happening, I just don't know how to fix it.
The Alert I had in touchstart was causing the app to stop and when I clicked OK the touchend event had already passed. I removed the touchstart Alert and the touchend alert worked, the istouch value was "true".
I added a few more alerts to see where it is failing and found that math.abs(e.pageX) was not a number - the alert showed NaN. Also $snd.data('tx') showed as "Undefined". Because of this vx was also reported as NaN. The value for ds displayed a numeric value.
So, I think the problem is that $snd is defined in .on(touchstart...) and is not referencable from .on(touchend...). Could this be a scope issue for the variables? At least the original terms and the search results that are copied into the search results page are showing the same symptoms so the onclick handler is being triggered which is good progress. Below is the current version of the click handlers, could you let me know what I should change, I'm quite new at js and this has been really challenging for me. Thanks again.
$(".wrapper") //i'm attaching all event handlers to body, so everything with .spanish class will have them attached
.on("click", ".spanish", function(e) {
e.preventDefault();
})
.on("touchstart", ".spanish", function(e) {
if (istouch) {
var $snd = $(this);
$snd.data({
tstart: new Date().getTime(),
tx: e.pageX,
ty: e.pageY
});
}
})
.on("touchend", ".spanish", function(e) {
if (istouch) {
alert("touchend detected istouch val = " + istouch); // shows istouch = true
var $snd = $(this);
var snd = this;
var ds = $snd.data('tstart');
alert("ds = " + ds); // shows a numeric value
if (!ds) {
return;
}
alert("math.abs e.pagex = " + Math.abs(e.pageX)); // shows NaN
alert("$snd.data('tx') = " + $snd.data('tx')); // shows "undefined"
var vx = Math.abs(e.pageX - $snd.data('tx'));
alert("vx = " + vx); // shows NaN
var vy = Math.abs(e.pageY - $snd.data('ty'));
Math.abs(e.pageY - $snd.data('ty'));
alert("vx= "+ vx +" vy= " + vy + " ds = " + ds);
if (vx < 20 && vy < 20 && new Date().getTime() - ds < 400) {
alert("tap detected and about to call playstop");
playstop.apply(snd, [e]);
$snd.data({
tstart: null,
tx: null,
ty: null
});
}
}
});
});
UPDATE 3
Hi #Paul, I've made a minor change to your code, I applied the click handler to the .wrapper div instead of Body because there's a home page with links that stopped working when I applied your update, the home page links work OK now.
Each English phrase can be translated into 1,2 or 3 Spanish phrases, all of the Spanish phrases are contained within a single .wrapper div for any given English div.
Below is a sample showing 3 English divs with their Spanish translations. I have 800+ English phrases altogether. When the user searches these phrases the complete 'english' div, including the wrapper div, should be copied to the search results page and it looks like it is being copied correctly.
<div class="english">
How old are you?
<div class="wrapper">
<a class="formal spanish" data-ignore="true" href="ageHowOldF.mp3">F: Cuántos años tiene?</a>
<a class="informal spanish" data-ignore="true" href="ageHowOldI.mp3">I: Cuántos años tienes?</a>
</div> <!-- End .wrapper -->
</div> <!-- End English -->
<div class="english">
When were you born?
<div class="wrapper">
<a class="formal spanish" data-ignore="true" href="ageWhenBornF.mp3">F: Cuando nació?</a>
<a class="informal spanish" data-ignore="true" href="ageWhenBornI.mp3">I: Cuando naciste?</a>
</div> <!-- End .wrapper -->
</div> <!-- End English -->
<div class="english">
How old was he?
<div class="wrapper">
<a class="spanish" data-ignore="true" href="ageHowOldMale.mp3">Cuántos años tenía él?</a>
</div> <!-- End .wrapper -->
</div> <!-- End English -->
UPDATE 2
#Paul, as described in my comment below your reply, please see below the full document ready script with your changes and the searchApp script that matches/ copies the selected element to an empty div.
Here is the document ready script:
jQuery(function($){
var highlight = 'yellow', origcolor = 'transparent', curSnd = null,
istouch = !!('ontouchstart' in window) || !!('ontouchstart' in document.documentElement) || !!window.ontouchstart || (!!window.Touch && !!window.Touch.length) || !!window.onmsgesturechange || (window.DocumentTouch && window.document instanceof window.DocumentTouch);
function playstop(e){
alert("Start playstop");
e.preventDefault();
var $this = $(this);
if(curSnd && curSnd.sound){
if(this === curSnd.tag){
curSnd.sound.stop();
return;
}
curSnd.sound.stop();
}
$this.stop(true, true).css({backgroundColor: highlight});
var filename = this.href.substring(this.href.lastIndexOf('/')), myMedia = new Media(
this.href,
function() {
myMedia && myMedia.release();
curSnd = myMedia = null;
$this.stop(true, true).animate({backgroundColor: origcolor}, 500);
},
function(e) {
myMedia && myMedia.release();
curSnd = myMedia = null;
$this.stop(true, true).animate({backgroundColor: origcolor}, 500);
window.console && console.log ("Audio play error - " + filename + "\ncode: " + e.code + "\nmessage: " + e.message);
}
);
alert("Start playing sound")
curSnd = {tag: this, sound: myMedia};
curSnd.sound.play();
} // End playstop
$("body") //i'm attaching all event handlers to body, so everything with .spanish class will have them attached
.on("click", ".spanish", function(e) {
e.preventDefault();
})
.on("touchstart", ".spanish", function(e) {
if (istouch) {
var $snd = $(this);
$snd.data({
tstart: new Date().getTime(),
tx: e.pageX,
ty: e.pageY
});
}
})
.on("touchend", ".spanish", function(e) {
if (istouch) {
var $snd = $(this);
var snd = this;
var ds = $snd.data('tstart');
if (!ds) {
return;
}
var vx = Math.abs(e.pageX - $snd.data('tx'));
var vy = 'enter code here';
Math.abs(e.pageY - $snd.data('ty'));
if (vx < 20 && vy < 20 && new Date().getTime() - ds < 400) {
playstop.apply(snd, [e]);
$snd.data({
tstart: null,
tx: null,
ty: null
});
}
}
});
});
</script>
Here is the search/Copy script
function searchApp() {
var $searchTerm = $(".searchField").val().toLowerCase(); // Convert search term to all lower case
var $searchResults = "";
document.getElementById("searchResultsDiv").innerHTML = "";
$(".english").each(function () {
if ($(this).text().toLowerCase().match($searchTerm)) { // If this specific '.english' class
$(this).clone(true, true).appendTo("#searchResultsDiv");
}
});
}; // /searchApp
UPDATE
I think I've localized the area that is causing my problem - which is when I copy an element to an empty div in a search results page the event listener from the original element is not being triggered when I tap on the search results page.
Below is a sample English/ Spanish element that is being copied:
<div class="english">
How old are you?
<div class="wrapper">
<a class="formal spanish" data-ignore="true"
href="ageHowOldF.mp3">F: Cuántos años tiene?</a>
<a class="informal spanish" data-ignore="true"
href="ageHowOldI.mp3">I: Cuántos años tienes?</a>
</div> <!-- End .wrapper -->
</div> <!-- End English -->
and here's the code that copies the original element when it finds a match on the English text:
if ($(this).text().toLowerCase().match($searchTerm)) {
$(this).clone(true, true).appendTo("#searchResultsDiv");
}
The English/Spanish phrases correctly appear on the search results page but do not respond to a tap. I added an alert message to the event listener and this does not display when I tap on the search page but does display when i tap on the original page.
I would really appreciate any suggestions you may have. Thanks.
END UPDATE
I have a smartphone app that is a talking English/Spanish phrasebook, when the user taps a Spanish phrase a short mp3 file is played by jQuery and this is working correctly, the jQuery player is assigned at document ready. I have now created a Search function which copies all matching English/Spanish phrases to a search results page and this also works correctly.
The problem I’m having is when the user taps any of the Spanish phrases on the search results page the app invokes the system sound player (I think) and not the jQuery sound player and the system sound player displays an audio control bar, which I don’t want my users to see.
I have tried everything I can think of, basically following two approaches:
Copy all the attributes of the element
Assign an onclick event to a parent element in the search results page
Neither of these approaches fixes this – at least nothing I know of fixes this.
I’m pretty new to js/jQuery so please forgive me if I’ve missed something blindingly obvious.
Please find below:
A sample English/Spanish element, there are several hundred of
these altogether. These are copied to the search results page if the
search matches the English phrase/word
The document ready script that assigns the click handler to the
Spanish phrases
The search function that finds and copies matching elements to the
search results page
SAMPLE English/ Spanish element
<div class="english">
How old are you?
<div class="wrapper">
<a class="formal spanish" data-ignore="true"
href="ageHowOldF.mp3">F: Cuántos años tiene?</a>
<a class="informal spanish" data-ignore="true"
href="ageHowOldI.mp3">I: Cuántos años tienes?</a>
</div> <!-- End .wrapper -->
</div> <!-- End English -->
Document ready script
This also does things like changing the background color, checking for a tap vs. a swipe etc.
jQuery(function($) {
var highlight = 'yellow',
origcolor = 'transparent',
curSnd = null,
istouch = !!('ontouchstart' in window) || !!('ontouchstart' in document.documentElement) || !!window.ontouchstart || (!!window.Touch && !!window.Touch.length) || !!window.onmsgesturechange || (window.DocumentTouch && window.document instanceof window.DocumentTouch);
function playstop(e) {
e.preventDefault();
var $this = $(this);
if (curSnd && curSnd.sound) {
if (this === curSnd.tag) {
curSnd.sound.stop();
return;
}
curSnd.sound.stop();
}
$this.stop(true, true).css({
backgroundColor: highlight
});
var filename = this.href.substring(this.href.lastIndexOf('/')),
myMedia = new Media(
this.href,
function() {
myMedia && myMedia.release();
curSnd = myMedia = null;
$this.stop(true, true).animate({
backgroundColor: origcolor
}, 500);
},
function(e) {
myMedia && myMedia.release();
curSnd = myMedia = null;
$this.stop(true, true).animate({
backgroundColor: origcolor
}, 500);
window.console && console.log("Audio play error - " + filename + "\ncode: " + e.code + "\nmessage: " + e.message);
}
);
curSnd = {
tag: this,
sound: myMedia
};
curSnd.sound.play();
} // End playstop
$('.spanish').click(function(e) {
e.preventDefault();
}).each(function(i, snd) {
if (istouch) {
var $snd = $(snd);
snd.addEventListener('touchstart', function(e) {
$snd.data({
tstart: new Date().getTime(),
tx: e.pageX,
ty: e.pageY
});
}, false);
snd.addEventListener('touchend', function(e) {
var ds = $snd.data('tstart');
if (!ds) {
return;
}
var vx = Math.abs(e.pageX - $snd.data('tx')),
vy = `enter code here`
Math.abs(e.pageY - $snd.data('ty'));
if (vx < 20 && vy < 20 && new Date().getTime() - ds < 400) {
playstop.apply(snd, [e]);
$snd.data({
tstart: null,
tx: null,
ty: null
});
}
}, false);
}
});
});
Search function
function searchApp() {
// Convert search term to all lower case
var $searchTerm = $(".searchField").val().toLowerCase();
var $searchResults = "";
document.getElementById("searchResultsDiv").innerHTML = "";
$(".english").each(function() {
// If this specific '.english' class
if ($(this).text().toLowerCase().match($searchTerm)) {
// Append all HTML contents of '.english' div into $searchResults variable
$searchResults += $(this)[0].outerHTML;
}
});
// Within searchResultsDiv tag, write $searchResults variable to HTML
$("#searchResultsDiv").html($searchResults);
}; // /searchApp
UPDATE 5
I changed the alerts to console.log. First test was to tap a Spanish phrase that already existed on the search results page. Below is the console log
touchstart $snd = [object Object] index.html:67
touchend detected istouch val = true index.html:72
touchend ds = 1427885920974 index.html:76
pageX in touchend = undefined index.html:77
touchend math.abs e.pagex = NaN index.html:82
touchend $snd.data('tx') = undefined index.html:83
touchend vx = NaN index.html:85
touchend vx= NaN vy= NaN ds = 1427885920974
Second test is tapping one of the created Spanish elements. Here's the log
touchstart $snd = [object Object] index.html:67
touchend detected istouch val = true index.html:72
touchend ds = 1427885920974 index.html:76
pageX in touchend = undefined index.html:77
touchend math.abs e.pagex = NaN index.html:82
touchend $snd.data('tx') = undefined index.html:83
touchend vx = NaN index.html:85
touchend vx= NaN vy= NaN ds = 1427885920974
Neither of these played a sound. Below is the touchstart and touchend handler scripts showing where I added the console.log statements.
.on("touchstart", ".spanish", function(e) {
if (istouch) {
$snd = $(this);
$snd.data({
tstart: new Date().getTime(),
tx: e.pageX,
ty: e.pageY
});
console.log("touchstart $snd = " + $snd);
}
})
.on("touchend", ".spanish", function(e) {
if (istouch) {
console.log("touchend detected istouch val = " + istouch);
var $snd = $(this);
var snd = this;
var ds = $snd.data('tstart');
console.log("touchend ds = " + ds);
console.log("pageX in touchend = " + $snd.data('tx'));
if (!ds) {
return;
}
console.log("touchend math.abs e.pagex = " + Math.abs(e.pageX));
console.log("touchend $snd.data('tx') = " + $snd.data('tx'));
var vx = Math.abs(e.pageX - $snd.data('tx'));
console.log("touchend vx = " + vx);
var vy = Math.abs(e.pageY - $snd.data('ty'));
Math.abs(e.pageY - $snd.data('ty'));
console.log("touchend vx= "+ vx +" vy= " + vy + " ds = " + ds);
if (vx < 20 && vy < 20 && new Date().getTime() - ds < 400) {
console.log("touchend tap detected and about to call playstop");
playstop.apply(snd, [e]);
$snd.data({
tstart: null,
tx: null,
ty: null
});
}
}
});
});
Main problem in your code is that you're adding event handlers to one set of objects, and not re-adding them to cloned ones. Delegeation of events would be more suitable for you. Change your ${'.spanish') eventHandlers into:
$("body") //i'm attaching all event handlers to body, so everything with .spanish class will have them attached
.on("click", ".spanish", function(e) {
e.preventDefault();
})
.on("touchstart", ".spanish", function(e) {
if (istouch) {
var $snd = $(this);
$snd.data({
tstart: new Date().getTime(),
tx: e.pageX,
ty: e.pageY
});
}
})
.on("touchend", ".spanish", function(e) {
if (istouch) {
var $snd = $(this);
var snd = this;
var ds = $snd.data('tstart');
if (!ds) {
return;
}
var vx = Math.abs(e.pageX - $snd.data('tx'));
var vy = 'enter code here';
Math.abs(e.pageY - $snd.data('ty'));
if (vx < 20 && vy < 20 && new Date().getTime() - ds < 400) {
playstop.apply(snd, [e]);
$snd.data({
tstart: null,
tx: null,
ty: null
});
}
}
});
Basically, i just splitted your function into two separate jquery events delegation function. All those handlers will be attached to everything matching selector .spanish in body container. You can modify it for some optimization (if you have some div as a wrapper for all those elements).
jQuery $.on function can bind some events (touchstart, touchend and click int his case) to current existing elements, and those which will be created in future, for example in process of cloning elements - it will probably be the best solution for you.
Read more about it here: http://api.jquery.com/on/

Javascript works in Chrome but not IE or Firefox

I am using Javascript within an HTML file to expand and collapse elements of the file.
This is the script:
function toggleBlock(pstrID){
var myDiv = document.getElementById('d' + pstrID);
if (myDiv){
if (myDiv.style.display == 'none'){
showBlock(pstrID);
} else{
hideBlock(pstrID);
}
}
}
function showBlock(pstrID){
var myDiv = document.getElementById('d' + pstrID);
if (myDiv){
myDiv.style.display = 'block';
var myImage = document.getElementById('i' + pstrID);
if (myImage){
myImage.src = 'arrowdown.gif';
myImage.alt = 'Hide';
}
if (document.location.href.indexOf('mk:#') == 0)
myDiv.innerHTML = myDiv.innerHTML;
}
}
function hideBlock(pstrID){
var myDiv = document.getElementById('d' + pstrID);
if (myDiv){
myDiv.style.display = 'none';
var myImage = document.getElementById('i' + pstrID);
if (myImage){
myImage.src = 'arrowright.gif';
myImage.alt = 'Show';
}
if (document.location.href.indexOf('mk:#') == 0)
myDiv.innerHTML = myDiv.innerHTML;
}
}
When I call the script, I use the following:
<a id="h7217" class="expandingblocktemplate" title="" href="javascript:toggleBlock('7217')">
In Chrome everything works fine.
In IE, clicking the link leads to a different window (address shown is javascript:toggleBlock('7217') obviously, the number depends on the link that's clicked) and the error "Internet Explorer cannot display the webpage".
In Firefox, a new tab appears and the Error Console says:
Error: toggleBlock is not defined
Source File: javascript:toggleBlock('7217')
Line: 1
just add
return false ;
after the toggleBlock call.
Additionally to Furqan's solution:
You should never trigger JavaScript in the href attribute. It's a non-standard method that easily leads to errors, especially if you don't know what you are doing. Use onclick instead and put a valid URL in the href attribute for non-script users, or use href="#" if you don't don't care about non-script users.
<a id="h7217" class="expandingblocktemplate" title="" onclick="toggleBlock('7217');" href="noscript.html">
Try this:
HTML:
<a href="#" onclick="toggleBlock('7217')">
JavaScript:
function toggleBlock(pstrID) {
var block = document.getElementById('d' + pstrID),
img = document.getElementById('i' + pstrID);
if ( block && img ) {
if ( block.style.display === 'none' ) {
block.style.display = 'block';
img.src ='arrowdown.gif';
img.alt = 'Hide';
} else {
block.style.display = 'none';
img.src = 'arrowright.gif';
img.alt = 'Show';
}
if ( document.location.href.indexOf('mk:#') === 0 ) {
block.innerHTML = block.innerHTML;
}
}
return false;
}

JavaScript script doesn't work in Firefox

I have an old function which is missing lines for Mozilla/Firefox and thus JavaScript is not working properly in it. The function tracks mouse-coordinates, so that I can position windows.
How to make the code work in Firefox as well?
Xoffset = -60; // modify these values to ...
Yoffset = 20; // change the popup position.
var old, skn, iex = (document.all),
yyy = -1000;
var ns4 = document.layers
var ns6 = document.getElementById && !document.all
var ie4 = document.all
if (ns4) skn = document.dek
else if (ns6) skn = document.getElementById("dek").style
else if (ie4) skn = document.all.dek.style
if (ns4) document.captureEvents(Event.MOUSEMOVE);
else {
skn.visibility = "visible"
skn.display = "none"
}
document.onmousemove = get_mouse;
function popup(msg, bak) {
var content =
"<TABLE WIDTH=150 BORDER=1 BORDERCOLOR=black CELLPADDING=2" +
"CELLSPACING=0 " + "BGCOLOR=" + bak + "><TD ALIGN=center>" +
"<FONT COLOR=black SIZE=2>" + msg + "</FONT></TD></TABLE>";
yyy = Yoffset;
if (ns4) {
skn.document.write(content);
skn.document.close();
skn.visibility = "visible"
}
if (ns6) {
document.getElementById("dek").innerHTML = content;
skn.display = ''
}
if (ie4) {
document.all("dek").innerHTML = content;
skn.display = ''
}
}
function get_mouse(e) {
var x = (ns4 || ns6) ? event.pageX : event.x + document.body.scrollLeft;
skn.left = x + Xoffset;
var y = (ns4 || ns6) ? event.pageY : event.y + document.body.scrollTop;
if (document.documentElement && // IE6 +4.01 but no scrolling going on
!document.documentElement.scrollTop) {
y = event.y + document.documentElement.scrollTop;
}
else if (document.documentElement && // IE6 +4.01 and user has scrolled
document.documentElement.scrollTop) {
y = event.y + document.documentElement.scrollTop;
}
else if (document.body && document.body.scrollTop) { // IE5 or DTD 3.2
y = event.y + document.document.body.scrollTop;
}
skn.top = y + yyy;
}
function kill() {
yyy = -1000;
if (ns4) {
skn.visibility = "hidden";
}
else if (ns6 || ie4) skn.display = "none"
}
I am getting this error:
"event is not defined"
Works ok in IE.
I'm not going to post code on how to rewrite your code #Ivo Wetzel's is pretty much what you need, but let meg give you some advice.
The world is changing fast, so does the computer industry. And while sometimes it's not as fast as we want (IE 6 fading slowly) there is no need to support Netscape 4.
Consult with a site like StatCounter to find out what browsers are in use (in your country/region). Also consult with YUI graded browser support. Yahoo is one of the biggest players on the internet, their site has to work for almost everyone, so they know what they're talking about.
Find a good DOM reference. MDC is pretty much what you need, but it's good to have MSDN for IE quirks. Talking about quirks, don't forget to bookmark QuirksMode compatibility tables.
Never use things like ie4 = document.all, because a single feature won't identify a whole browser. It's like saying: "Hey you've got blonde hair, you must be Brad Pitt". Use feature detection. Read these two excellent articles: Browser Detection (and What to Do Instead) and Feature Detection: State of the Art Browser Scripting
Don't use document.write because it's synchronous I/O which is awful. It blocks your page rendering and leads to bad user experience. The Web is all about being asynchronous.
"Synchronous programming is disrespectful and should not be employed in applications which are used by people." - Douglas Crockford
Oh my god... this must be the worst code I've seen in years, well let's try to clean it up then:
Xoffset = -60; // modify these values to ...
Yoffset = 20; // change the popup position.
var old, skn = document.getElementById("dek").style, yyy = -1000;
function popup(msg, bak) {
var content =
"<TABLE WIDTH=150 BORDER=1 BORDERCOLOR=black CELLPADDING=2" +
"CELLSPACING=0 " + "BGCOLOR=" + bak + "><TD ALIGN=center>" +
"<FONT COLOR=black SIZE=2>" + msg + "</FONT></TD></TABLE>";
yyy = Yoffset;
document.getElementById("dek").innerHTML = content;
skn.display = '';
}
document.onmousemove = function(e) {
e = e || window.event;
var x = e.pageX !== undefined ? e.pageX : e.clientX + document.body.scrollLeft;
var y = e.pageY !== undefined ? e.pageY : e.clientY + document.body.scrollTop;
skn.left = x + Xoffset;
skn.top = y + yyy;
}
function kill() {
yyy = -1000;
skn.display = "none";
}
It's still broken beyond repair, but it should work... somehow.... Well, unless you post the rest of them HTML there's no way I can test this.
Please, I beg you... get rid of all that crap and use jQuery.
Instead of testing for browsers, I would test to see if the object / property exists. For example:
var x = e.pageX ? e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
I think there may be an easier way to do this, such as
var x = e.pageX || e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
but I'm not sure that will work. Test it out and see what you get. Also, for more detail, review: quirksmode.org/js/events_properties.html
Also note that I changed "event" to "e", since the parameter you're passing into the function is "e". If you want to still use event, rewrite the parameter to:
function get_mouse(event)
While I don't believe "event" is a reserved word for JS, a lot of browsers use it, so I would suggest sticking to "e".
Looks like you need to change all your instances of 'event' to 'e'.
Firefox includes document.documentElement and document.documentElement.scrollTop and document.body and document.body.scrollTop so you're entering regions that were meant for IE with Firefox.
You should also start your function with something like
function get_mouse(e) {
e = e || window.event;
Then use e instead of event in all the places you use event.
Add var event = e on the first line of function body, if you are afraid of hassles
function get_mouse(e) { var event = e;

Categories