I'm working on a gallery of sorts in Wordpress right now and I'm a bit stuck.
The idea is to change the post thumbnail on hover. The replacement image will be coming from a field generated by the Advanced Custom Fields plugin.
Now, I've managed to pull in both URLs and stored them in variables, but I still won't work. It works on a standalone CodePen, but not on the Wordpress site itself.
Wordpress code:
jQuery(document).ready(function() {
var firstthumb = '<?php echo the_post_thumbnail_url(); ?>';
var secondthumb = '<?php if( get_field('multiple_thumbs') ): ?><?php echo the_field('multiple_thumbs'); ?><?php endif; ?>';
jQuery('.member-thumbnail').hover(function() {
jQuery('.attachment-thumbnail').attr('src', secondthumb);
}, function() {
jQuery('.attachment-thumbnail').attr('src', firstthumb);
});
});
And it returns this:
jQuery(document).ready(function() {
var firstthumb = 'http://www.cozeh.com/wp2/wp-content/uploads/2016/01/pic2.png';
var secondthumb = 'http://www.cozeh.com/wp2/wp-content/uploads/2016/01/multiple2.png';
jQuery('.member-thumbnail').hover(function() {
jQuery('.attachment-thumbnail').attr("src", secondthumb);
}, function() {
jQuery('.attachment-thumbnail').attr("src", firstthumb);
});
});
Here's a link to the beta version.
And here's the codepen.
Would appreciate any explanation as to why this doesn't work or if you have any alternative solutions.
Edit: Updated code
The problem is that in the codepen you are not wrapping the img in an a tag, but you are doing it on the WordPress site. So to make it work in wordpress you need to remove the link that is wrapping the image or change you jQuery code, replacing this code:
jQuery('.member-thumbnail').hover(function() {
...
});
To this one:
jQuery('.member-thumbnail a').hover(function() {
...
});
Marking as solved.
Turns out it wasn't a script issue after all.
WP 4.4.+ was appending srcsetto the images as part of their move to make all images responsive. The img srcwas changing but not the srcsethence the problem.
Found a workaround to disabling the responsive images for now.
And I edited the code so it only affects one of the thumbnails, not every single one.
<?php if ( has_post_thumbnail() ) { ?>
<div class="member-<?php the_ID(); ?>-thumbnail">
<?php the_post_thumbnail('thumbnail'); ?>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
var firstthumb = '<?php the_post_thumbnail_url(); ?>';
var secondthumb = '<?php if( get_field('multiple_thumbs') ): ?><?php echo the_field('multiple_thumbs'); ?><?php endif; ?>';
jQuery('.member-<?php the_ID(); ?>-thumbnail').hover(function() {
jQuery('.member-<?php the_ID(); ?>-thumbnail .attachment-thumbnail').attr('src', secondthumb);
}, function() {
jQuery('.member-<?php the_ID(); ?>-thumbnail .attachment-thumbnail').attr('src', firstthumb);
});
});
</script>
Thanks for the input everybody.
Related
Can anyone help me. I’m trying to make jquery go to function while click on a div. Function works but it goes always on the same ID, first one.
Here is the code:
<?php do { ?>
<div class=“editNews”></div>
<script>
$(function() {
$(“.editNews”).on(“click touchstart”, function(e) {
Here I would like to execute jquery and than go to
window.location = “inserNews.php?id=<?php echo $row_rsNews[“NewsID”]; ?>;
});
e.stopPropagation()
});
});
</script>
<?php } while ($row_rsNews = mysqli_fetch_assoc($rsNews))?>
Thank you very much
I'm trying to wrap my head around how this actually works in wordpress on the admin back end for a widget I'm trying to create (similar to the custom HTML widget). I've read a few tutorials but the information seems to change and I feel I have just confused myself.
Everything works fine while initializing codemirror and it is applied to the textarea but the errors I'm having are:
When new html is entered into codemirror the save button for the widget doesn't activate.
If I change another field to activate the save button the data from codemirror is not sent or saved.
(function ($) {
$(document).ready( function(){
var editorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
editorSettings.codemirror = _.extend(
{},
editorSettings.codemirror,
{
lineNumbers: true,
mode: "text/html",
indentUnit: 2,
tabSize: 2,
autoRefresh:true,
}
);
var editor = wp.codeEditor.initialize( $('#<?php echo $textarea_id; ?>'), editorSettings );
});
})(jQuery);
</script>
I've also tried adding:
$(document).on('keyup', '.CodeMirror-code', function(){
editor.codemirror.save();
$('#<?php echo $textarea_id; ?>').html(editor.codemirror.getValue());
});
but editor.codemirror.getValue() return empty when I display through console.log
Code for Textarea
<p>
<label for="<?php echo $textarea_id; ?>"><?php _e( 'Locked Content:' ); ?></label>
<textarea id="<?php echo $textarea_id; ?>" name="<?php echo $this->get_field_name( 'locked-content' ); ?>" class="widefat"><?php echo esc_textarea( $instance['locked-content'] ); ?></textarea>
</p>
Any help (links to a proper tutorial, advice etc) would be much appreciated JS isn't my strongest language.
I believe this came down to me being an idiot lol I was calling this same block of code from another widget as I was trying to make both widgets textareas into codemirrors.
I changed the name of 2 variables to be more specific towards the widget eg:
var editorSettings
var editor
where changed to:
var cm_editorSettings
var cm_editor
This allowed me to us cm.editor.codemirror.getValue() and return the actual value. Still not sure if this is the correct way to implement it so please correct me if I am wrong but currently the working code to update the textarea and enable save button is as follows
<script type="text/javascript">
(function ($) {
$(document).ready( function(){
var cm_editorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
cm_editorSettings.codemirror = _.extend(
{},
cm_editorSettings.codemirror,
{
lineNumbers: true,
mode: "text/html",
indentUnit: 2,
tabSize: 2,
autoRefresh:true,
}
);
var cm_editor = wp.codeEditor.initialize($('#<?php echo $textarea_id; ?>') , cm_editorSettings );
$(document).on('keyup', '.CodeMirror-code', function(){
$('#<?php echo $textarea_id; ?>').html(cm_editor.codemirror.getValue());
$('#<?php echo $textarea_id; ?>').trigger('change');
});
});
})(jQuery);
I have this line of code
<script type="text/javascript">
document.title = "<?php include('pot1.php');?>"
</script>
My pot1.php gives me an echo with one random number, but that code does not seem to work and I don't know why the echo doesn't appear in my title. Is anything wrong with the code?
pot1.php code:
<?php
#include_once('link1.php');
$cg = fetchinfo("value","info","name","current_game");
$cb = fetchinfo("cost","games","id",$cg);
$cb=round($cb,2);
echo '$'.$cb;
?>
This echo is working and is giving me values because I can see them in one div.
You should just do it like this:
<?php include('pot1.php');?>
Now we know that there is a variable set. Echo that into the title tag.
<script type="text/javascript">
document.title = "<? echo $cb ?>"
</script>
The way you're doing it now... I don't think you can include an entire PHP page and expect to behave like a simple string, even if that's all it returns.
Put the value you want inside a variable in the pot1.php file and use it on the title
<?php include('pot1.php');?>
<script type="text/javascript">
document.title = "<?php echo $yourVar;?>"
</script>
Here is my site.
If you hover over one of the projects and click the plus icon, the Ajax call goes out and the response returns in 1-4 seconds on average. I'm not understanding why it's so slow compared to a similar site that also uses admin-ajax.php (try hovering/clicking on one of the projects on that site to compare). All of the images called by Ajax are optimized. I also optimized my database tables. I'm not sure what else I can do.
Here is a comparison of the response time of admin-ajax.php from both sites. As you can see, the other site takes 480ms while mine takes 2s:
Here is how I have my Ajax call set up. Sorry, I didn't simplify the code because I think maybe the reason for the delay can only be found in the full code. The actual Ajax call is about halfway down.
(function($) {
// Function to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {
var imgs = this.find('img[src!=""]');
// If there are no images, just return an already resolved promise
if (!imgs.length) {
return $.Deferred().resolve().promise();
}
// For each image, add a deferred object to the array which resolves when the image is loaded
var dfds = [];
imgs.each(function(){
var dfd = $.Deferred();
dfds.push(dfd);
var img = new Image();
img.onload = function(){dfd.resolve();};
img.src = this.src;
});
// Return a master promise object which will resolve when all the deferred objects have resolved
// IE - when all the images are loaded
return $.when.apply($, dfds);
};
// Function for additional styling
function projectStyles() {
// Check the first slide input
$('#slider input:first').attr('checked', 'checked');
$('#project-wrapper').addClass('activated');
// Make the articles grey again after activation
$('article.project').addClass('grayscale grayscale-fade').css('opacity', '0.4');
// CSS effects
$('.post-container').addClass('fadeInUp');
$('.close-button').addClass('fadeInDown');
// Remove pesky, sticky 'hover' class
$('article.project').removeClass('hover');
}
// Make the max-height of the container exact for a smoother transition
function matchContainerHeight() {
var heightHandler = function() {
var containerHeight = $('#project-container').outerHeight();
$('#project-wrapper.activated').css('max-height', containerHeight);
};
setTimeout(heightHandler, 100);
$(window).on('resize', heightHandler);
}
// Open the project container
function openProject() {
var post_id = $(this).data('id'), // data-id attribute for .post-link
ajaxURL = site.ajaxURL; // Ajax URL localized from functions.php
// Add a loading icon
$('<span class="loading-icon"></span>').insertBefore(this);
// Add the 'active' class to make sure the div stays dark while loading
$(this).closest('article.project').addClass('active hover-sticky');
// Make all the articles grey when an article is clicked
$('article.project').addClass('grayscale grayscale-fade grayscale-sticky').css('opacity', '0.4');
// No hover on images while a project is loading
$('article.project img').addClass('nohover');
// Remove all corner ribbons
$('article').removeClass('current');
$('.corner-ribbon').remove();
// Add a corner ribbon to note the current activated project
$(this).closest('article.project').removeClass('active').addClass('current');
$('<div class="corner-ribbon">Current</div>').prependTo('article.current');
// Call Ajax
$.ajax({
type: 'POST',
url: ajaxURL,
data: {'action': 'load-content', post_id: post_id },
success: function(response) {
// Wait until all images are loaded
$('#project-container').html(response).imagesLoaded().then(function() {
// Fire again to rearrange the slide in the DOM
resize();
// Remove all 'hover' classes
$('article.project').removeClass('hover-sticky grayscale-sticky');
$('article.project img').removeClass('nohover');
// Remove the loading icon
$('.loading-icon').remove();
// If the user has scrolled...
if ($(window).scrollTop() !== 0) {
// First scroll the page to the top
$('html, body').animate({
scrollTop : 0
},400, function() {
matchContainerHeight();
projectStyles();
});
// If the user has not scrolled...
} else {
matchContainerHeight();
projectStyles();
}
return false;
});
}
});
}
// User event
$('#content').on('click', '.post-link', function(e) {
e.preventDefault();
var projectTitle = $(this).data('title'), // data-title attribute for .post-link
projectSlug = $(this).data('slug'); // data-slug attribute for .post-link
// Calls openProject() in context of 'this' (.post-link)
openProject.call(this);
$('head').find('title').text(projectTitle + ' | Keebs');
});
})(jQuery);
Here is the Ajax response file. I'm using the ACF plugin, but I tried the response without any of the ACF fields and the wait time was the same. I also tried removing everything within the my_load_ajax_content() function but the wait time was still the same as well. So I'm guessing something else is causing the long wait time. I also tried GET instead of POST but the response time was around the same:
<?php
/**
* Ajax functions
*/
// Return the post content to the AJAX call
function my_load_ajax_content () {
$args = array(
'p' => $_POST['post_id'],
'post_type' => 'projects'
);
$post_query = new WP_Query( $args );
while( $post_query->have_posts() ) : $post_query->the_post(); ?>
<div class="post-container">
<div id="project-left-content">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
<?php the_content(); ?>
<?php if( get_field('client') ): ?>
<div class="client">
Client(s): <?php the_field('client'); ?>
</div>
<?php endif; ?>
<div class="project-cats">
<?php
$cat_names = wp_list_pluck( get_the_category(), 'cat_name');
echo join( ', ', $cat_names );
?>
</div>
<?php if( get_field('url') ): ?>
<div class="project-link">
<a class="first after" href="http://<?php the_field('url'); ?>" target="_blank"><?php the_field('url'); ?></a>
</div>
<?php endif; ?>
</div>
<div id="project-right-content">
<?php if( have_rows('slides') ): ?>
<div id="slider">
<!-- Slider Setup -->
<?php if( have_rows('slides') ):
$slideNumber = 0;
while ( have_rows('slides') ) : the_row();
$slideNumber++;
?>
<input type="radio" name="slider" id="slide<?php echo $slideNumber; ?>">
<?php endwhile;endif; ?>
<!-- Slide -->
<?php if( have_rows('slides') ): ?>
<div id="slides">
<div id="overflow">
<div class="inner">
<?php if( have_rows('slides') ):
while ( have_rows('slides') ) : the_row();
$slideImage = get_sub_field('slide_image');
?>
<article>
<img src="<?php echo $slideImage; ?>" alt="<?php the_title(); ?>">
</article>
<?php endwhile;endif; ?>
</div><!-- #inner -->
</div><!-- #overflow -->
</div><!-- #slides -->
<?php endif; ?>
<!-- Controls -->
<?php if( have_rows('slides') ):
$slideNumber = 0;
?>
<div id="active">
<?php while ( have_rows('slides') ) : the_row();
$slideNumber++;
?>
<label for="slide<?php echo $slideNumber; ?>"></label>
<?php endwhile; ?>
</div><!-- #active -->
<?php endif; ?>
</div><!-- #slider -->
<?php endif; ?>
</div><!-- #project-right-content -->
</div><!-- .post-container -->
<?php
endwhile;
wp_die();
}
add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' ); // when the user is logged in
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' ); // when the user is not logged in
Does anybody see something that I should be doing differently?
Looks like your site is hosted on dreamhost and most likely on shared hosting offering they have. The other website you mentioned looks like it is hosted on its own VPS. Shared hosting is often known for their slow database performance.
Your best option might be to use a caching solution like 'WP Super Cache' or 'W3 Total Cache' that saves the webpage to memory or disk on first request and serves from there on subsequent requests bypassing the database.
These are both wordpress plugin and can be easily installed from the admin plugins section.
https://wordpress.org/plugins/wp-super-cache/
https://wordpress.org/plugins/w3-total-cache/
Other option is trying to create indexes on the databse for faster searching. You could also look at using a small VPS (AmazonEC2 free tier or $5/month from digital ocean etc) if you know how to install Apache/mysql etc.
I would want to suggest you that rather then echoing HTML code from your php file you just return the main data(only raw information based on the click) as json response and then generate the html tags based on that and append it . Creating HTML from javascript is much faster than echoing HTML , specially during ajax call. I am sure if you do this you can get quite fast performance. Any big or large site they dont send HTML in ajax response. Majorly pure json response containing the key information is echoed. And on basis of that the divs are generated to load the section faster.
Can I make a suggestion?
Instead of defining your function like this:
(function($)
try something like this:
jQuery(document).ready(function($) {
$('selector').whatever();
})
I'm still learning Wordpress myself but I have found that defining the function as using jQuery can make a difference. I think this is because Wordpress is unsure of which library you want to use.
Easy question for a coder well-versed in JS.
I'm building a Wordpress site that uses jQuery AJAX methods, reloading either my entire content area when a top nav link is clicked or my main content area when a sidebar nav link is clicked. I want to be sure that the AJAX call is only issued if the user's browser supports JavaScript. I found some reference material here and on other sites that said by referencing my script externally, a browser unequipped with JavaScript would simply ignore all JS files. Is this accurate? I considered using php:
$my_arr = get_browser(null,true);if $my_arr['javascript'] == 1 {
echo '<script type="text/javascript" src="path/to/script"';
}
The UX I'm going for is if JS is enabled, then fire AJAX calls; if JS is disabled, just send the user to the page they've requested.
e.g.
<?php
/**
* The template for displaying all pages.
*
$ajxy = $_GET['ajxy'];
if(!is_null($ajxy)) {
$ajax_code = $ajxy;
}
if(!$ajxy) {
get_header();
}
?>
<?php if(!$ajax_code) { ?>
<div id="primary">
<div id="content" role="main">
<div class="container_12" id="contentWrapper">
<?php } ?>
<div id="contentContainer" <?php if($ajax_code) { echo 'class="ajxn"'; } ?>>
<?php while ( have_posts() ) : the_post(); ?>
<div class="grid_8" id="contentGrid">
<?php
get_template_part( 'content', 'page' );
?>
</div>
<?php get_sidebar(); ?>
<?php endwhile; // end of the loop. ?>
</div>
<?php if(!$ajax_code) { ?>
</div>
</div><!-- #content -->
</div><!-- #primary -->
<?php } ?>
<!---My Ajax Loading Script -->
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/js/ajxy.js"></script><!---My Ajax Loading Script -->
<?php
if(!$ajxy) {
get_footer();
}
?>
and the script:
function ajxnOff(list, ajxnCode, wrapper, container) {
jQuery(list).click(function(e) {
e.preventDefault();
var $lnkGoz = jQuery(this).attr("href");
var $lnkGozAjx = $lnkGoz + '?ajxy=' + ajxnCode;
var $ajxyContainer = wrapper;
var $ajxyCurThing = container;
$ajxyCurThing.fadeOut(400, function() {
$ajxyContainer.html('<div id="loaderA"></div>');
jQuery("div#loaderA").fadeIn(400);
jQuery.ajax({
url: $lnkGozAjx,
success: function(data) {
jQuery("div#loaderA").delay(2000).fadeOut(400, function() {
$ajxyContainer.html(data);
jQuery("div.ajxn").fadeIn(400);
jQuery.remove("div#loaderA");
});
}
});
});
});
}
jQuery(document).ready(function() {
ajxnOff(jQuery("ul#topNavList a"), 1, jQuery("div#contentWrapper"), jQuery("div#contentContainer"));
ajxnOff(jQuery("ul#sidebarNavList a"), 2, jQuery("div#contentGrid"), jQuery("div#contentPageContainer"))
});
I've been learning to code on my own for about 6 months and don't have any books on the subject, so any help from the experts around here is greatly appreciated.
Here is a simple pattern to do unobtrusive ajax navigation with fallback to non-ajax links.
In your HTML:
<a class="ajaxnav" href="page.html">Text</a>
In your script:
$(".ajaxnav").click(function(event) {
event.preventDefault();
// do ajax nav here;
// URL is in event.currentTarget.href, modify it however necessary
});
If javascript is not supported, the script is simply not run, and you're left with standard web anchors with valid HREFs. If javascript is supported, the script replaces all "ajaxnav" link handling with your ajax click handler. Easy as pie.
Yes, if the user's browser either doesn't support JS or has JS disabled, script tags are essentially ignored. It doesn't hurt to include them no matter what, you just have to plan your site for what happens when they're not utilized.
As far as AJAX versus page reload goes, you simply code your site as if there were no AJAX, i.e. all links should have appropriate href attributes point to where they should go. If JS is enabled, you attach your AJAX to the links via its onclick handler and prevent the default action by returning false from whatever function handles the click event.