I have been working on a small slideshow / public display for a client that uses HTML5 Rock's Slideshow code. I have run into a DOM Exception 12 - a syntax error that is supposedly related to CSS selectors - while monkeying around with it... but I can't trace it back to any changes I made in the code. I am thinking it might be something that was uncovered as I added features.
I have traced it down to this object (live version here):
var SlideShow = function(slides) {
this._slides = (slides || []).map(function(el, idx) {
return new Slide(el, idx);
});
var h = window.location.hash;
try {
this.current = h;
} catch (e) { /* squeltch */ }
this.current = (!this.current) ? "landing-slide" : this.current.replace('#', '');
if (!query('#' + this.current)) {
// if this happens is very likely that someone is coming from
// a link with the old permalink format, i.e. #slide24
alert('The format of the permalinks have recently changed. If you are coming ' +
'here from an old external link it\'s very likely you will land to the wrong slide');
this.current = "landing-slide";
}
var _t = this;
doc.addEventListener('keydown',
function(e) { _t.handleKeys(e); }, false);
doc.addEventListener('touchstart',
function(e) { _t.handleTouchStart(e); }, false);
doc.addEventListener('touchend',
function(e) { _t.handleTouchEnd(e); }, false);
window.addEventListener('popstate',
function(e) { if (e.state) { _t.go(e.state, true); } }, false);
};
Instantiation of SlideShow() (line 521 in main.js):
var slideshow = new SlideShow(queryAll('.slide'));
Calling queryAll('.slide') returns an array of all the slides with an class of .slide. However, when passing queryAll('.slide') as a parameter for instantiating SlideShow(), it returns a DOM Exception 12 error.
Has anybody seen this before?
You are using illegal id-attributes(illegal before HTML5) inside the document, e.g. 2-slide . Fix them.
To explain:
to solve the known misbehaviour of element.querySelectorAll() the selector .slide will be internally rewritten(by using the id of the element). This will result in something like that:
#2-slide .moreselectors
...and forces the error, because an ID may not start with a Number.
See the fiddle: http://jsfiddle.net/doktormolle/FGWhk/
If you are coming here after searching for this error in HTML5 rocks slides:
For some reason they remove the class 'to-build' with the following:
toBuild[0].classList.remove('to-build', '');
That breaks all slide decks the use build, even the Google demo right now is broken
Just change line 220 of default.js to
toBuild[0].classList.remove('to-build');
all is well!
In my case it was using self.postMessage(e.data); in the main thread while using web workers.
I know it's not related to the OP's issue, but it's an odd error so I'm leaving this here in hope it helps others.
Same problem to me but in my case a try to get elements from their attribute
document.querySelectorAll('input[name="path"]')
and SYNTAX_ERR: DOM Exception 12 occurred only on Safari. So i've change it to get the element directly from class and now work fine.
You can escape the quotes like in applescript then no issue on safari
do JavaScript "document.querySelector('span[" & attrName & "=\"" & attrValue & "\"]').click();"
Related
I updated a website I am working on to the latest WordPress last week. None of the custom JS is working anymore and I can't work out why.
Even if I remove it in sections to try and isolate the issue, I always get 'Uncaught TypeError: $ is not a function'.
I cannot work out what has caused this to happen.
As far as I can see, all the scripts load as expected.
Unfortunately all the JS in my custom file has been acquired either from Stack Overflow or other online resources - I did not write it myself (only amended) and thus am struggling to diagnose the issue.
Any help would be appreciated
// apply effect to pages
var $headereffect = $('.hero-effect');
$headereffect.waypoint(function (direction) {
if (direction == 'down') {
$headereffect.addClass('hero-effect-animation');
} else {
$headereffect.removeClass('hero-effect-animation');
}
}, { offset:'1px' });
// apply effect to default page headers
var $headereffect = $('#page-header');
$headereffect.waypoint(function (direction) {
if (direction == 'down') {
$headereffect.addClass('hero-effect');
} else {
$headereffect.removeClass('hero-effect');
}
}, { offset:'1px' });
My wild guess is to use jQuery instead of the $ as sometimes the latter is used by other scripting libraries and this causes issues and conflicts.
So
var $headereffect = $('.hero-effect');
becomes
var $headereffect = jQuery('.hero-effect');
This will fix the current issue but others also may be raised on a later stage. Inspect your code and make sure you use a consistent jQuery reference.
Options to handle the $ issue the jQuery way can be found here. From a practical point of view, you can put jQuery into "no conflict" mode by using shortcut for jQuery. In this case "$j" instead of the default "$":
var $j = jQuery.noConflict();
$j(function(){
$j("#sidebar li a").hover(function(){
$j(this).stop().animate({
paddingLeft: "20px&"
}, 400);
}, function() {
$j(this).stop().animate({
paddingLeft: 0
}, 400);
});
});
A best practice as Wordpress suggest is to wrap your code in immediately invoked function expression, pass jQuery to it and use the $ internally like this:
( function( $ ) {
// Your code goes here
} )( jQuery );
I am using a plugin that allows me to display an ad in video-js.
https://github.com/dirkjanm/videojs-preroll/blob/master/lib/videojs.ads.js
This worked perfect until version 5 but now that I have wanted to migrate to version 6, this plugin no longer works, the log throws me the following error:
TypeError: videojs.getComponent(...) is undefined videojs.ads.js:386
It seems that everything lies in this section of the plugin (line 386):
(function() {
var
videoEvents = videojs.getComponent('Html5').Events,
i,
returnTrue = function() { return true; },
triggerEvent = function(type, event) {
// pretend we called stopImmediatePropagation because we want the native
// element events to continue propagating
event.isImmediatePropagationStopped = returnTrue;
event.cancelBubble = true;
event.isPropagationStopped = returnTrue;
player.trigger({
type: type + event.type,
state: player.ads.state,
originalEvent: event
});
},
The plugin has not been updated since a while ago so I also gave some alarms on how to register the plugin but that yes I could solve it, I'm not very understanding of javascript so I do not know how I could solve that.
Ok comrades, I have been reading the manual of videojs 6 and apparently to solve that problem only had to change a line:
videojs.getComponent -to- videojs.getTech
I leave it here in case someone has the same problem.
Of course, I am not a Javascript specialist so I honestly would not know how to give an explanation about this.
I am doing a pretty standard drag and drop feature in HTML5. However, for some reason e.target.dataTransfer showing up as undefined. I am new to javascript. Any help will be appreciated.
This is the java script.
<script src="jquery-2.1.4.min.js"></script>
<script>
$(document)
.ready(
function() {
jQuery.event.props.push('dataTransfer');
if (!!window.FileReader) {
// Browser suppports FILE API.
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
$('#drag-and-drop-zone').bind('dragover',
function(e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass('drag-over');
return false;
});
$('#drag-and-drop-zone').bind('dragleave',
function(e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass('drag-over');
return false;
});
$('#drag-and-drop-zone')
.bind(
'drop',
function(e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass(
'drag-over');
alert(this.id);
alert('This shows up as 0. Why? . '
+ e.dataTransfer.files.length);
return false;
});
}
} else {
// Browser does not support FILE API.
$('#drag-and-drop-zone')
.html(
'Upgrade your browser. Find something that can handle HTML5.');
}
});
</script>
And this is the HTML
<body>
<div id="drag-and-drop-zone">Drag and drop the organization data
file on this area.</div>
</body>
When I run this - somehow the file drop is registered, as in the correct events are triggered. But somehow the number of files show up as 0. Please help.
Very interesting!
Add the following lines to the drop function you have - in front of your alert messages.
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
console.log('f: ', f);
}
You'll notice your alert no longer says 0. When I dragged a single file, it showed 1 (as expected). It also showed the proper count when I dragged multiple files.
I'm no expert of the internals, but when I looked at the FireBug console, I noticed the FileList was not presented as a regular type of object. I suspect that the File API relies on "Just In Time" delivery of content. It makes sense, why carry around the overhead of all the data when the drop container may not properly handle it.
Once the data is requested (with the for loop), the File API populates the appropriate internal data structures for use by the calling code.
Notice that the for loop doesn't loop through a count - it actually requests a file at the given index. The File API returns false if the file is not available. That is what actually causes the file to get loaded for use by your code - as well as cancel the for loop when there are no more files.
While I can't specifically answer your question of "why", at least this can get you moving along. Once you've looped through the available files, you can make use of the FileList length (and any other data that you need).
I hope this helps.
Good Luck!
Ok. Got it. The issue was with the version of Firefox I was using. I tried with IE11 and it is working fine now. I have failed to check for the support of FileApi.
I seem to be having issues with programmatic opening and closing of a JQM 1.3 Panel.
EDIT: This is for JQM 1.3.x not 1.4+
It is somewhat hard to explain, so I just made a fiddle :)
There is a lot going on in the fiddle, but it is just a sample of a much larger app and conveys the issue.
How to replicate:
Go to Fiddle
On Fiddle open the Panel and go to Page Two
On Page Two open Panel and go to Page One
Try to Open the Panel now on page one, it does nothing.
Browsers Affected:
EDIT: This seems to be fixed in Chrome 30.0.1599.101 m
Chrome 28.0.1500.95 m
IE 10.0.9200.16635
Safari // Latest Ver
Android WebView (4.2.2)
Browsers NOT Affected:
Firefox 23
Opera 12.16
Link to Fiddle:
http://jsfiddle.net/q2YH3/
Link to Other Posts
https://github.com/jquery/jquery-mobile/issues/6308
http://forum.jquery.com/topic/panel-not-responding-after-page-change
EDIT: So Firefox gives me an error that neither Chrome or IE do.
When I click to go back to page one, I get:
Type Error: elem is undefined
The error is thrown by JQ 1.9.1, I trace it back to this:
A method for determining if a DOM node can handle the data expando
acceptData: function( elem ) {
// Do not set data on non-element because it will not be cleared (#8335).
if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
return false;
}
var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
// nodes accept data unless otherwise specified; rejection can be conditional
return !noData || noData !== true && elem.getAttribute("classid") === noData;
}
`
Note the :
Do not set data on non-element because it will not be cleared (#8335).
Github Issue Link:
https://github.com/jquery/jquery/pull/1232
OG Code:
$('.showMenu').on('click', function(){
$.mobile.loading('hide');
$.mobile.activePage.find('#'+$.mobile.activePage.attr('id')+'P').panel("toggle");
});
$('.btnMenuItem').on('click', function(event){
myPgActions.nav(event, function(target){
$.mobile.changePage(target);
}, false);
});
var myPgActions = {};
myPgActions = {
nav: function(event, callback, manualHash){
var PID = $.mobile.activePage.attr('id'),
target = (!!event) ? event.target.name : manualHash;
$("#"+PID+"P").panel( "close" );
if(PID != 'loading') $("#"+PID+"Iframe").hide();
if(PID == target){
$("#"+PID+"Iframe").hide('fast', function(){
$("#"+PID+"Iframe").attr('src', "");
myPgActions.update(PID, target, 'refresh', function(target){
callback(target)
});
});
}else{
this.update(PID, target, 'change', function(target){
callback(target);
});
}
},// end get
update: function(PID, target, type, updateCallback){
var ifReady = $.Deferred();
if(type == 'refresh'){
this.buildUrl(PID, function(url){
$('#'+PID+'Iframe').attr( 'src', url);
ifReady.resolve();
$.when(ifReady).then(function(){
updateCallback('#'+PID+'Iframe')
});
});
}else if(type == 'change'){
this.buildUrl(target, function(url){
$('#'+target+'Iframe').attr( 'src', url);
ifReady.resolve();
});
$.when(ifReady).then(function(){
updateCallback('#'+target);
});
}
}, // end set
buildUrl: function(page, buildCallback){
switch(page){
case 'dash':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},25);
break;
case 'local':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},25);
break;
}// End Switch
}
}// End Obj
Had the same problem, panel not showing after page changes.
Two small changes can fix that:
what I did was to change the panel from id="myPanel" to class="myPanel", then changed the call to the panel to open: $('.myPanel:visible').panel('open'); - that's it!
The problem is that the panel has to be inside of a jQuery "page", and after the transition, if you have the panel set in the target page, you actually have two (or more) panels with the same id which is wrong or same class which is fine. So you just change the id to a class and call the visible one.
Took me too long, Hope it saves time to someone else.
I played around with your code a bit. I noticed that If I put an alert inside your update function, that it fixes everything. So I researched why an alert would make a program work, and found this page.
http://ubuntuforums.org/archive/index.php/t-930002.html
"You should probably know that JavaScript evaluation is of the 'look ahead' type: the script already runs when it is still being evaluated (and while the page itself is still being evaluated). Now that is why it is recommended to dump all references to scripts in the section of your page, as it will cause the JavaScript to be fully evaluated before you (usually) can call a function (event handlers), and hence avoid silly 'undefined' errors.
Now the alert(); call has 2 effects: (1) it pops up the message box (so far, so good);.but (2) it halts the thread the JavaScript is using! However the browser's other threads will still continue to go on (HTML rendering...). So it may be one of those cases that you would benefit from a more elegant halting method, which is to only execute this (part of the) script when the document has been fully loaded;"
The solution they suggest is putting your script inside of the . Or using "stateChanged() function of the ajax http request".
Well I upvoted #A.sharif 's post, as he got the gears in my head spinning.
The problem lies in the fact that the callback of the "BuildUrl" function was executing before the URL variable was built.
I thought I had allowed ample time with 25ms but it was not. I bumped the time before the callback is executed up to 600 ms and it works fine now.
I am sure there is a more elegant solution, but this is what I got ;)
New Fiddle:
http://jsfiddle.net/t8zyQ/
What was changed was the value of 25 in the setTimeout() to 600.
Changed Code:
buildUrl: function(page, buildCallback){
switch(page){
case 'dash':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},600);
break;
case 'local':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},600);
break;
}// End Switch
Here is a link to my page: http://myweb.students.wwu.edu/~tuckerb2/cs202/peanuts/project/open.html. I'm having trouble with all browsers, though it works in Firefox and Chrome, but not IE. I need to fix this parsing error that shows up in Firefox and IE so that it will a) not show an error in Fox and b) actually work in IE. Please help! Thank you!
There are a couple of things going on that you should have a look at
Firsly, in IE (6,7,8) window.innerHeight doesn't exist, instead you could use the below which will:
var h = (document.documentElement.clientHeight/2)-17;
The other issue is that once the letters match up in the center of the screen you do not stop the timers you have started. This means they will keep running and generate errors as the variables topLetters and bottomLetters are now larger than the size of the arrays topPos and bottomPos.
The function setInterval returns a reference to its timer, so you could then use the following code
var topTimer, bottomTimer;
function startSnowing() {
topTimer = setInterval("topFall()",10);
bottomTimer = setInterval("bottomRise()",10);
}
and change your topFall() and bottomRise() methods to something like
function bottomRise() {
if (bottomLetters < bottomPos.length) {
document.getElementById("bottomLetters").style.bottom = bottomPos[bottomLetters] + "px";
bottomLetters++;
}
else {
clearInterval(bottomTimer);
}
}
Hope this helps!