0

I am attempting to add some javascripts to my "Page Not Found' PHP page, but no matter how many different ways that I try to do it, it breaks something.

Here is an example page for this code: http://www.miamirealestateguy.com/miami-property-for-sale-details/9401-COLLINS-AVE-807-SURFSIDE-FL-33154/A10077417/39/

My current page is using the below code, and everything LOOKS correct in a browser, but the scripts on the page break my navigation at the top of the page, so the dropdown menu doesn't work. When I remove the scripts, the navigation works again.

enter image description here

<?php
/**
 * @package Serene
 * @since Serene 1.0
 */
?>

<h1>
  <?php esc_html_e( 'No Results Found', 'Serene' ); ?>
</h1>
<?php if ( is_home() && current_user_can( 'publish_posts' ) ) : ?>
<p><?php printf( __( 'Ready to publish your first post? <a href="%1$s">Get started here</a>.', 'Serene' ), esc_url( admin_url( 'post-new.php' ) ) ); ?></p>
<?php elseif ( is_search() ) : ?>
<p>
  <?php _e( 'Sorry, but nothing matched your search terms. Please try again with some different keywords.', 'Serene' ); ?>
</p>
<?php get_search_form(); ?>
<?php else : ?>
<p>
  <?php _e( '<p><strong>If you arrived on this page by clicking a link to a real estate listing in a search engine, the property has now been sold or is no longer available.</strong></p><br /><p><strong>You can start a new search for currently available real estate listings below.</strong></p>', 'Serene' ); ?>
<br /><h2><strong>Search by Criteria:</strong></h2><div class="grey-box"><script type='text/javascript' src='http://www.idxhome.com/site/listing/search/widget/91928?style=horizontal'></script></div><br /><h2><strong>Search by Street Address:</strong></h2><div class="grey-box"><script type='text/javascript' src='http://www.idxhome.com/site/listing/searchByAddress/widget/91928'></script></div><br /><h2><strong>Search by MLS ID:</strong></h2><div class="grey-box"><script type='text/javascript' src='http://www.idxhome.com/site/listing/searchByListingId/widget/91928'></script></div><br /><h2><strong>Search by Map:</strong></h2><div class="grey-box"><script type='text/javascript' src='http://www.idxhome.com/site/map/search/widget/91928'></script></div>
</p>
<?php endif; ?>

I've tried moving the scripts inside this tag where the basic HTML for the text on the page goes, but doing that that breaks the whole page and nothing on it works:

<?php _e( '<p><strong>If you arrived on this page by clicking a link to a real estate listing in a search engine, the property has now been sold or is no longer available.</strong></p><br /><p><strong>You can start a new search for currently available real estate listings below.</strong></p>', 'Serene' ); ?>

Can someone assist me with the correct way to implement the scripts into this page so that it doesn't break my top navigation? I've tried everything I can think of via trial and error and can't figure it out, and I don't understand PHP at all!

Thank you!

0

1 Answer 1

3

Problem

The Short Version

The problem isn't how you're using those scripts or where you're placing them - it's how the authors of those scripts wrote them.

The Long Version

Your "superfish" script which controls the functionality of your navigation menu is throwing errors because $.browser is undefined. While $.browser was deprecated more than 3 years ago, WordPress loads the "jQuery Migrate Plugin" by default, which should alleviate the issue by providing functionality for deprecated code - unless one of 49 scripts loaded between jQuery Migrate and Superfish is over-writing $.browser for some reason: and here we get to the meat of the problem.

The "widget scripts" described in your answer all load even more scripts and libraries on top of the 68 others on the page, including different versions of the jQuery and jQuery UI components that your site has already loaded. Your site itself loads jQuery v1.12.4 while the "widget scripts" load v1.9.1. Using your browser's JavaScript console, you can check the version in memory at the end of page load by executing jQuery.fn.jquery or $.fn.jquery - which on your site produces 1.9.1.

This reveals a problematic issue - the "widget scripts" from "idxhome" are not properly encapsulated, nor do they load jQuery in compatibility mode. The result is that they're completely overwriting the window.jQuery and window.$ variables, which includes erasing the $.browser variable - thus causing the superfish error and breaking your navigation. The other massive side-effect is that it's incredibly difficult to determine which code on your page is executing with which version of jQuery, which has a high potential to produce all manner of bizarre bugs - especially since the version that the idx widgets are injecting is almost 4 years older than the one your site loads.

Normally, you could use jQuery's jQuery.noConflict() function to restore the jQuery and $ global variables as they existed before something else clobbered them (in this case, the other jQuery library loaded by the widget scripts) - however since each idx widget loads it's own jQuery library, even the "backup copies" of these variables point to the wrong jQuery code after two or more widgets are loaded.

On a side note regarding the code you posted, it's worth a comment that there's usually no good reason to place non-text-related HTML (things other than elements like <span>, <strong>, and <em>) inside of the WordPress translation functions such as _e(), as it is most commonly desirable for the markup to remain the same regardless of the active language.


Solutions

If you have no intention of learning WordPress and web development, you might consider hiring a developer to optimize your site (combining scripts and stylesheets, removing unnecessary and redundant ones, performing version updates where beneficial, etc.). It's a great looking site - but it could use some technical love!

In any scenario, one of the most worthwhile solutions is probably to contact the authors of the IDX scripts regarding this issue - I feel they should update their scripts to be more courteous to the environments which they are loaded into (say, improving encapsulation and using noConflict() where necessary). Even if they don't, they may be able to provide a solution if this problem is something that comes up frequently.

Otherwise, one solution I would look into are implementing the widgets yourself (ideally, check out the JavaScript and HTML in the remote files and create WordPress shortcodes to print more compatible versions) instead of loading those "widget scripts" such that you can control which libraries are loaded and how they do so.

Hacks

I believe all of the easy solutions are "hacks" that add duct-tape on top of duct-tape, and ideally should be avoided on a production site. Among them:

  • Manually imitate jQuery.noConflict() by saving the global jQuery variables before the idx widget scripts, and restoring them afterwards. However, if the jQuery libraries inserted by the idx scripts are loaded asynchronously, there's a chance that the restoration would occur too early and the idx jQuery library could still overwrite the site's instance:

    Before:

    <script type="text/javascript">
      window._wpse232741_jQuery = window.jQuery;
    </script>
    

    After:

    <script type="text/javascript">
      window.jQuery = window.$ = window._wpse232741_jQuery;
    </script>
    
  • As $.browser was deprecated 3+ years ago, it seems likely that your site is using an outdated version of superfish. Updating it to one which does not rely on $.browser should remove the error (though the problem of competing jQuery libraries would remain).

  • Execute the jQuery Migrate script (again) responsible for setting jQuery.browser after the widget scripts (though, again, the competing library versions issue still remains - and there's still the chance that if the IDX scripts loading jQuery asynchronously could break this):

    After:

    <script type="text/javascript" src="/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.4.1"></script>
    
  • You should be able to maintain the proper version of jQuery by applying jQuery.noConflict() where IDX failed to - yet, once again, if the IDX jQuery is loaded asynchronously this might not work.

    After Each IDX <script> Element:

    <script type="text/javascript">jQuery.noConflict(true);</script>
    
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.