I have a navigation menu that is built in PHP such that the current location has a different image so the user knows where they are.
In the function, I have these HTML attributes outputted:
To set the td id:
$menu_output .= '<tr><td id="nav_buttons">';
And to set the img id and user-defined img data-id:
$menu_output .= '" id="alt" data-id="yes';
The function also has this bit:
...
if ($current_page == $key) {
$menu_output .= $image_dir . $ds . $page_nav_alt[$key];
$menu_output .= '" id="alt" data-id="yes';
}
else {
$menu_output .= $image_dir . $ds . $page_nav[$key];
}
$menu_output .= '" border="0" height="19" width="129"></a></td>';
to set the current page to yes for tagging it.
I basically give it two arrays of links and images and the current page has a highlighted image. This menu seems to work fine and I've been using it for a while.
Recently I have wanted to change it so that in addition to this functionality, I get hover over effects with jQuery. My thinking was that how hard could it be? Well, it has been more difficult than I imagined. By no means am I an expert on JavaScript or jQuery, so I'm not surprised I'm screwing this up.
Here is the jQuery I'm working with that isn't giving the expected results:
$(document).ready(function() {
var test = $('#alt').attr('data-id');
if (test != 'yes'){
$('#nav_buttons img').hover(function() {
this.src = this.src.replace('_dark', '_light');
},
function() {
this.src = this.src.replace('_light', '_dark');
});
}
else {
$('#nav_buttons img').hover(function() {
this.src = this.src.replace('_light', '_dark');
},
function() {
this.src = this.src.replace('_dark', '_light');
});
}
});
This seems to work for the if part but the else branch doesn't do what I thought it should. It changes the link to light and then the hover changes it to dark on over and then light on out.
When I inspect the elements with Firefox, the classes ids and attributes are what I set, eg, the highlighted link is set to yes and the others not set. It seems everything is working except the else branch. What am I missing?
EDIT
I looked into the page source when the home page was current, thinking it would be "_dark" because it looks like the dark image, but yet the source says it's the "_light" image. But when I inspect the element with Firefox, it tells me it's the "_dark" image with the alt attributes. I believe that the PHP is writing the data to the page (server derived), as expected, and jQuery is acting on it (changing the DOM), as expected, but I cannot get them to play correctly. I think I need to somehow set the image with jQuery after the hover event so that it looks like it's supposed to. How do I get these to function like I want?
EDIT 2
I think I see why the .attr() and .data() jQuery methods aren't working. The docs say that these work with the first element in the collection. Or am I misunderstanding that? So basically, even though the PHP writes the element how I want it, in the right place and with the right value, when I inspect the element, I get different values. This seems to block the hover/replace from working correctly.
I tried this variation that is a bit simpler:
var test = $('img').data('id');
And I test for test to be equal to alt which I now tell PHP to place right after the img tag. But for some reason when I alert the test variable, Im still getting undefined. Presumably because the order of the img tag attributes.
How to PHP developers get around this and make PHP and jQuery play nice together? Seems like these kinds of conficts would be all over in PHP sites that use jQuery.
Custom HTML attributes only really came in with HTML5 so you might get a few extra problems with data-id attribute.
I'd suggest adding a class to the img addClass(). You can then test if an element has that class by using hasClass().
$menu_output .= '" id="alt" class="data-id-yes"';
And then you would do something like
$(document).ready(function() {
$('#nav_buttons img').hover(function() {
if($(this).hasClass('data-id-yes')
{
this.src = this.src.replace('_dark', '_light');
} else {
this.src = this.src.replace('_light', '_dark');
}
},
function() {
if($(this).hasClass('data-id-yes')
{
this.src = this.src.replace('_light', '_dark');
} else {
this.src = this.src.replace('_dark', '_light');
}
});
});
it sounds that there is a syntax error in the code. try to chnage this:
$menu_output .= '" id="alt" data-id="yes';
to:
$menu_output .= 'id="alt" data-id="yes"';
$('#nav_buttons img').hover(function() {
var test = $('#alt').data('id');
if (test != 'yes'){
this.src = this.src.replace('_dark', '_light');
} else {
this.src = this.src.replace('_light', '_dark');
}
}, function() {
if (test != 'yes'){
this.src = this.src.replace('_light', '_dark');
} else {
this.src = this.src.replace('_dark', '_light');
}
});
Related
My algorithm:
I get the DIV text from php/SQL ($.get( "read.php"...)
APPEND contenteditable div with loaded text by jQuery
check the div value, if there is errors in text I make div red (assign class, $(this).addClass("fill_red");)
on every change of text - check and assign/remove class if needed.
Problem is: with preloaded text - everything is working.
But when I append div using JS - check function don't works.
I searched the web, maybe on() method helps me.
But what event?
It should be something like onload, onchange..?
(yes, I could make div generated by php and solve the problem, but I dont want full refresh)
Thank you!
part of code:
//texts load
$(function() {
$.get( "read.php", function( data ) {
var ionka = data.split(' ');
ionka.forEach(function(item, i, arr) {
var app_text = "<div id=\"segm" + i + "\" contenteditable role=\"textbox\">" + item + "</div>";
$("#textarea").append(app_text);
});
});
//checks
var intRegex = new RegExp('^[0-9/\]{5}$');
$('#textarea div').each(function(i,elem) {
if(!intRegex.test($(this).text())) {
$(this).addClass("fill_red");
}else{
$(this).removeClass();
}
});
// edit on change. Blur because of contenteditable
var segm_array = [];
$('#textarea div').each(function(i,elem) {
$(this).blur(function() {
if (segm_array[i]!=$(this).text()){
segm_array[i] = $(this).text();
if(!intRegex.test(segm_array[i])) {
$(this).addClass("fill_red");
}else{
$(this).removeClass();
}
}
});
});
You dont show much code here, but my guess is that you are trying to add class before new data is loaded into dom
$.get( "read.php" ).done(function( data ) {
// addClass etc
});
I am not new to jQuery, however this should work and isnt:
html:
<a href='<?=$s['url'];?>' class='playbutton'><img src='http://i.domain.net/icons/play.png' width=20></a>
jquery $("a.playbutton").click():
$(this).find("img").attr("src","http://i.domain.net/icons/stop.png");
If I change the attr to addClass("jimbo") I get the class jimbo added to my image. So it is finding the img tag fine, but not changing the source. Can someone tell me why?
full jquery function is:
$("a.playbutton").click(function(e) {
var current = $("#jplayer").data().jPlayer.status.src
var playing = current.split("/");
var href = encodeURIComponent($(this).attr("href"));
if(playing[3] != href) {
$("#jplayer").jPlayer("setMedia", {mp3: "http://mp3.domain.net/" + href});
$("#jplayer").jPlayer("play");
$(this).find("img").attr("src","http://i.domain.net/icons/stop.png");
$("a.playbutton > img").each(function () {
$(this).attr("src","http://i.domain.net/icons/play.png");
});
} else {
$("#jplayer").jPlayer("stop");
$("#jplayer").jPlayer("clearMedia");
}
return false;
});
All works fine apart from $(this).find("img").attr.. line. Like i said, If i change attr to addClass, it adds the class fine. Meaning that it can find the correct <img> tag okay.
(URLs have been changed to domain.net)
use prop in place of attr
$(this).find("img").prop("src","url");
Maybe you've forgot to add the return false to the callback, check this out:
http://jsfiddle.net/YnT5L/1/
$("a.playbutton").click(function() {
$(this).find("img").attr("src","http://i.domain.net/icons/stop.png");
return false;
});
I am working on making a dynamically loaded website using some php code to swap out content from various other files. While on top of that I am using jquery to beautify this swap out.
Relevant PHP:
<?php
// Set the default name
$page = 'home';
// Specify some disallowed paths
$disallowed_paths = array('js.php','css.php','index.php');
if (!empty($_GET['page'])){
$tmp_page = basename($_GET['page']);
// If it's not a disallowed path, and if the file exists, update $page
if (!in_array($tmp_page, $disallowed_paths) && file_exists("{$tmp_page}.php"))
$page = $tmp_page;
}
// Include $page
if(!file_exists("$page.php")){
$page = 'home';
}
else{
include("$page.php");}
?>
Relevant jquery:
$(function (a) {
var $body = $('body'),
$dynamo = $('.dynamo'),
$guts = $('.guts');
$body.fadeIn('slow');
if (history.pushState) {
var everPushed = false;
$dynamo.on('click', 'a', function (b) {
var toLoad = $(this).attr('href');
history.pushState(null,'',toLoad);
everPushed = true;
loadContent(toLoad);
b.preventDefault();
});
$(window).bind('popstate', function () {
if (everPushed) {
$.getScript(location.href);
}
everPushed = true;
});
} // otherwise, history is not supported, so nothing fancy here.
function loadContent(href) {
$guts.hide('slow', function () {
$guts.load(href, function () {
$guts.show('slow');
});
});
}
a.preventDefault();
});
What is happening is when I link to a page using ?page=about it will work but it will instead of just swapping out the content it will load the entire page including the content inside the dynamically loaded div.
If I were to link straight to about.php it would work beautifully with no fault whatsoever, but anybody who wanted to share that link http://example.com/about.php would get just the content with no css styling.
If I were to change the jquery in "loadContent" to:
$guts.load(href + ' .guts', function () {
EDIT 1:
, ' .guts'
to
+ ' .guts'
It would then work but any script, java, jquery, or the like would not work because it gets stripped out upon content load.
check out http://kazenracing.com/st3
EDIT 2:
It also seems to be that the site does not work properly in the wild either.
No background and none of the icons show up, but it still gets the general problem across.
I can fix that myself, it will just take some time. For now my focus is on the recursion problem.
EDIT 3: Site no longer needs to be worked on, problem never solved but we are letting that project go. So the link no longer is a valid URL.
I have a script that pops up a div element when a anchor tag is clicked
echo '<h2>' . $row['placename'] . '</h2>';
It's echoed from a PHP script, and is working fine in FF and IE(9).
But chrome won't run it, atleast on ver. 18.0.1025.168 m
The popup(divid); event fires when I click it, but it doesent complete the function calling inside the script the function is in.
var width_ratio = 0.4; // If width of the element is 80%, this should be 0.2 so that the element can be centered
function toggle(div_id) {
var el = document.getElementById(div_id);
if ( el.style.display == 'none' ) { el.style.display = 'block';}
else {el.style.display = 'none';}
}
function blanket_size(popUpDivVar) {
alert(popUpDivVar);
if (typeof window.innerWidth != 'undefined') {
viewportheight = window.innerHeight;
} else {
viewportheight = document.documentElement.clientHeight;
}
if ((viewportheight > document.body.parentNode.scrollHeight) && (viewportheight > document.body.parentNode.clientHeight)) {
blanket_height = viewportheight;
} else {
if (document.body.parentNode.clientHeight > document.body.parentNode.scrollHeight) {
blanket_height = document.body.parentNode.clientHeight;
} else {
blanket_height = document.body.parentNode.scrollHeight;
}
}
var blanket = document.getElementById('blanket');
blanket.style.height = blanket_height + 'px';
var popUpDiv = document.getElementById(popUpDivVar);
popUpDiv_height=0;
popUpDiv.style.top = popUpDiv_height + 'px';
}
function window_pos(popUpDivVar) {
if (typeof window.innerWidth != 'undefined') {
viewportwidth = window.innerHeight;
} else {
viewportwidth = document.documentElement.clientHeight;
}
if ((viewportwidth > document.body.parentNode.scrollWidth) && (viewportwidth > document.body.parentNode.clientWidth)) {
window_width = viewportwidth;
} else {
if (document.body.parentNode.clientWidth > document.body.parentNode.scrollWidth) {
window_width = document.body.parentNode.clientWidth;
} else {
window_width = document.body.parentNode.scrollWidth;
}
}
var popUpDiv = document.getElementById(popUpDivVar);
window_width=window_width/2;
window_width = window_width * width_ratio;
popUpDiv.style.left = window_width + 'px';
}
function popup(windowname) {
alert(windowname); // THIS WORKS
blanket_size(windowname);
window_pos(windowname);
toggle('blanket');
toggle(windowname);
}
The last function in that script is the one that is called first. I put an alert box in it to verify that it was fired. BUT, I put an alert box in the next function that it calls (blanket_size), and it did not fire, as I had the alert box on the first line in the function. It did not fire.
I simply have no clue why. The weird thing is that this stuff works in other browsers, but not chrome. Any ideas?
Thanks!
Edit: And I also verified that the parameter value passed into the popup() function (the 'windowname' param) is valid/has a value. It contains the ID of a DIV that is in the HTML document, and it's not dynamically created.
Edit 2: Ok, I got the script running when and ONLY when I add an alert box with the parameter value in it (windowname) to the popup(windowname) function. But if I remove that box, it stops working again.
Edit 3:
Got no errors on the debugger at all. But now I'm even more confused. After a great deal of tries, it seems like it's working with the alert box at random! Sometimes works, and sometimes not.
Final Edit
Changed logic to jQuery. Should have done this long ago!
// Open property
$(".property-open-link", ".yme-propertyitem").live('click', function() {
$("#yme-property-pop").css({'display': 'block', 'z-index': '9999' });
$("#blanket").css({'display': 'block', 'height', getBlanketHeight(), 'z-index': '1000' });
loadproperties('open', $(this).closest(".yme-propertyitem").attr("id"));
});
// Close property button
$("#yme-property-close").live('click', function() {
$("#yme-property-pop").css('display', 'none');
$("#blanket").css('display', 'none');
});
Couple of things to clear up first:
It really helps if you create a way for us to interact with your
code, especially as you've pasted PHP code here, instead of plain
HTML
Is there a reason why you're not using a library to handle your DOM
interactions? It will make your code more concise and take away some
possible failure points when it comes to cross-browser code.
Right,
I'm a little unsure why your code isn't working in Chrome. I set up a demo in jsfiddle and it seems to work fine.
You'll notice I'm not attaching the events in onclick attributes on the <a/> element, and neither should you. This could be where the problem lies.
Currently, the code in the jsfiddle alerts as expected and only fails when it fails to find a relevent DOM node in toggle.
Note:
addEventListener in the example is not cross-browser, which is another reason to use a DOM library.
I am making a picture preview with jCarousel (http://sorgalla.com/projects/jcarousel/), but faced with one problem: I do not know how could I reload/refresh jCarousel dynamic list.
I have few categories of images. When I click on a picture in one of that, I need that the list would be created and preview start with that element. I have some code, but do not know how to make it re-create all list after clicking on other image that preview start with other image.
Here are my code:
$(document).ready(function(){
$("ul#stage li").live('click', function() {
var ul = $(this).parent();
var index = +(ul.children().index(this))+1;
var mycarousel_itemList = [ ];
$('li[data-id]').each(function () {
var $this = $(this);
mycarousel_itemList.push({
url : $this.attr("data-img"),
title : $this.attr("data-title")
});
});
function mycarousel_itemLoadCallback(carousel, state) {
for (var i = carousel.first; i <= carousel.last; i++) {
if (carousel.has(i)) {
continue;
}
if (i > mycarousel_itemList.length) {
break;
}
carousel.add(i, mycarousel_getItemHTML(mycarousel_itemList[i-1]));
}
};
function mycarousel_getItemHTML(item) {
return '<img src="' + item.url + '" width="800" height="600" alt="' + item.url + '" />';
};
alert(index);
jQuery('#mycarousel').jcarousel({
itemLoadCallback: {onBeforeAnimation: mycarousel_itemLoadCallback},
size: mycarousel_itemList.length,
scroll: 1,
start: index,
wrap: 'last',
animation: 'fast',
visible: 1
});
document.getElementById('popup-content').style.background='url('+$(this).attr("data-img")+') no-repeat center';
document.getElementById('fades').style.display='block';
document.getElementById("light").style.display = "block";
$("#light").fadeTo("slow", 1);
});
});
Everything is like that: there are images > I click on one of those > popup shows with jCarousel and one visible image and then I could scroll through all other images.
It is working good, but just a first time. When I click on other image (after closing popup), the view starts with that image which was opened last.
If something are not clear enough - please, ask. I will try to make it more precisely.
Thanks for your help!
You can recreate jCarousel, first use $('#mycarousel').remove(); and next init jCarousel again. I didn't really understand what you're trying to do, but this can help in most cases, of course jCarousel should have Destroy method but it hasn't.
And why you don't use jquery selectors in some cases?