创建自定义WordPress小部件并阻止js运行两次(一次在活动小部件中,一次在小部件选择器中)?

时间:2013-07-16 作者:vimes1984

好的,现在的问题是如何阻止js在小部件上运行两次。php页面?我正在与当前站点位于同一服务器上的域中创建一个加载了ajax的自定义图像选择器。我希望用户能够选择一幅图像,并在下面的字段中填充图像描述的href、图像的标题和图像的src,然后将结果发布在侧栏的前端。

我已经在我的函数中注册了一个自定义小部件。php,小部件内部有自定义js。代码如下:

/*
*
*Ajax loaded gallery for sidebar
*Note this will not work cross browser.
*
*
*/
/**
 * Plugin Name: A gallery Widget
 * Description: A widget that displays an ajax loaded gallery.
 * Version: 0.1
 */

add_action( \'widgets_init\', \'my_widget\' );

function my_widget() {
  register_widget( \'MY_Widget\' );
}

class MY_Widget extends WP_Widget {

  function MY_Widget() {
    $widget_ops = array( \'classname\' => \'example\', \'description\' => __(\'A widget that displays the chosen gallery images and link from lundhs \', \'example\') );

    $control_ops = array( \'width\' => 300, \'height\' => 350, \'id_base\' => \'example-widget\' );

    $this->WP_Widget( \'example-widget\', __(\'Reference Projects\', \'example\'), $widget_ops, $control_ops );
  }

  function widget( $args, $instance ) {
    extract( $args );

    //Our variables from the widget settings.
    $titlewidget = apply_filters(\'widget_title\', $instance[\'titlewidget\'] );
    $introtext = $instance[\'introtext\'];
    $title = $instance[\'title\'];
    $name = $instance[\'name\'];
    $img = $instance[\'img\'];
    $show_info = isset( $instance[\'show_info\'] ) ? $instance[\'show_info\'] : false;

    echo $before_widget;

?>
<?php
if($titlewidget)
  ?>

<h4 class="widget-title"><?php echo $titlewidget;?></h4>
<?php
if($introtext)
?>
<p> <?php echo $introtext; ?></p>
    <div class="row">
<?php
//display gallery img
if ( $img)
  ?>
<a class="columns four" href="<?php echo $name; ?>">
     <img class="imggallery" src="<?php echo $img; ?>">
   </a>
    <?php
  // Display the gallery name and link
    if ( $title )
      ?>
     <a class="columns eight imggallery_link" href="<?php echo $name; ?>"><?php echo $title; ?></a>

</div>

<?php
    echo $after_widget;
  }

  //Update the widget 

  function update( $new_instance, $old_instance ) {
    $instance = $old_instance;

    //Strip tags from title and name to remove HTML
    $instance[\'titlewidget\'] = strip_tags( $new_instance[\'titlewidget\'] );
    $instance[\'introtext\'] = strip_tags( $new_instance[\'introtext\'] );
    $instance[\'title\'] = strip_tags( $new_instance[\'title\'] );
    $instance[\'name\'] = strip_tags( $new_instance[\'name\'] );
    $instance[\'show_info\'] = $new_instance[\'show_info\'];
    $instance[\'img\'] = $new_instance[\'img\'];

    return $instance;
  }

  function form( $instance ) {

    //Set up some default widget settings.
    $defaults = array( \'title\' => __(\'Example\', \'example\'), \'introtext\' => __(\'introtext\', \'example\'), \'titlewidget\' => __(\'Reference Project\', \'example\'), \'img\' => __(\'img\', \'example\'), \'name\' => __(\'link goes here\', \'example\'), \'show_info\' => true );
    $instance = wp_parse_args( (array) $instance, $defaults ); ?>
<script type="text/javascript">
(function($) {

//load on page load
  $(".area").load("/galleries/ #projects > li a");

//load on widget title click
            $(\'.widget-top\').live("click", function() {
             $(".area").load("/galleries/ #projects > li a");
            });

//stop default href from working
            $(\'.area a\').unbind().live("click", function() {
                             event.preventDefault();
                             return;
             });
//load into input boxes
$(".area a").live("click", function() {
      var title = $(this).attr(\'title\');
      $(".title").val(title);
      var link = $(this).attr(\'href\');
      $(".link").val(link);
      var img = $("img", this).attr(\'src\');
      $(".img").val(img);
      var imgexample = $("img", this).attr(\'src\');
      $(".gallery_one").attr("src", imgexample);
    });
}(jQuery));
</script>
<style type="text/css">
.area img{
    max-width: 100px;
    max-height: 100px;
    display: inline-block;
}
.area a{
    max-width: 100px;
    max-height: 100px;
    display: inline-block;
}
.gallery_one_image_wrap{
  width: 100%;
height: 150px;
}
.gallery_one{
max-width: 80%;
max-height: 150px;
width: 80%;
margin: auto;
padding-left: 10%;
padding-right: 10%;
}
</style>
<script type="text/javascript">
(function($) {
        var addDiv = jQuery(\'.addinput\');
        var i = jQuery(\'.addinput p\').size() + 1;

    jQuery(\'.addNew\').live(\'click\', function() {
        jQuery.append(\'<p><input type="text" class="p_new\' + i +\'" size="40" name="p_new_\' + i +\'" value="" placeholder="I am New" /><a href="#" class="remNew">Remove</a> </p>\');
        i + 1;

        return false;
    });

    jQuery(\'.remNew\').live(\'click\', function() {
          if( i > 1 ) {
          jQuery(this).parents(\'p\').remove();
          i - 1;
          }
    return false;
    });
}(jQuery));

</script>
   <h3>Gallery selector for Lundhs</h3>
    <p>
    <label for="<?php echo $this->get_field_id( \'titlewidget\' ); ?>"><?php _e(\'Widget Title:\', \'example\'); ?></label>
      <input type="text" class="titlewidget" name="<?php echo $this->get_field_name( \'titlewidget\' ); ?>" value="<?php echo $instance[\'titlewidget\']; ?>" style="width:100%;" />
    </p>
    <p>
    <label for="<?php echo $this->get_field_id( \'introtext\' ); ?>"><?php _e(\'Intro text:\', \'example\'); ?></label>
      <input type="text" class="introtext" name="<?php echo $this->get_field_name( \'introtext\' ); ?>" value="<?php echo $instance[\'introtext\']; ?>" style="width:100%;" />
    </p>
      <h4 style="text-align: center;">First Pick your images</a>
    <div class="area"></div>

<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
    <h3>Your current front end projects</h3>
    <h4>Reference project one</h4>
    <div class="gallery_one_image_wrap">
    <img class="gallery_one" src="<?php echo $instance[\'img\']; ?>" /><br/>
    </div>
    <p>
      <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e(\'Title:\', \'example\'); ?></label>
      <input type="text" class="title" name="<?php echo $this->get_field_name( \'title\' ); ?>" value="<?php echo $instance[\'title\']; ?>" style="width:100%;" />
    </p>
    <p>
      <label for="<?php echo $this->get_field_id( \'name\' ); ?>"><?php _e(\'The link:\', \'example\'); ?></label>
      <input type="text" class="link" id="<?php echo $this->get_field_id( \'name\' ); ?>" name="<?php echo $this->get_field_name( \'name\' ); ?>" value="<?php echo $instance[\'name\']; ?>" style="width:100%;" />
    </p>

    //img Input.
    <p>
      <label for="<?php echo $this->get_field_id( \'img\' ); ?>"><?php _e(\'The Link to the image:\', \'example\'); ?></label>
      <input type="text" class="img" id="<?php echo $this->get_field_id( \'img\' ); ?>" name="<?php echo $this->get_field_name( \'img\' ); ?>" value="<?php echo $instance[\'img\']; ?>" style="width:100%;" />
    </p>
<div class="addinput">
<p>
<a href="#" class="addNew">Add new project</a>
</p>
</div>
  <?php
  }
}
出现问题的原因是,这个js运行了两次,在\'when\'时添加了两次额外的输入框。单击addNew。

    (function($) {
        var addDiv = jQuery(\'.addinput\');
        var i = jQuery(\'.addinput p\').size() + 1;

    jQuery(\'.addNew\').live(\'click\', function() {
        jQuery.append(\'<p><input type="text" class="p_new\' + i +\'" size="40" name="p_new_\' + i +\'" value="" placeholder="I am New" /><a href="#" class="remNew">Remove</a> </p>\');
        i + 1;

        return false;
    });

    jQuery(\'.remNew\').live(\'click\', function() {
          if( i > 1 ) {
          jQuery(this).parents(\'p\').remove();
          i - 1;
          }
    return false;
    });
}(jQuery));
后一段代码运行两次,一次在左侧的非活动小部件中,一次在侧栏的活动小部件中。如何强制JS只在当前活动的小部件中运行。将js移动到单独的。js文件和enqueing对我来说真的不是一个选项,因为我必须在php中使用php值来填充和检索这个构建的下一步中的值。非常感谢您的帮助。克里斯//UPDATE//对,我想我要找的功能是is_active_widget() (codex) 但我似乎无法让它工作,即使我将$skip\\u inactive设置为true,它仍会运行js两次
到目前为止,我已经尝试过:

    //start gallery widget

add_action( \'widgets_init\', \'my_widget\' );

function my_widget() {
  register_widget( \'MY_Widget\' );
}

class MY_Widget extends WP_Widget {

  function MY_Widget() {

    $widget_ops = array( \'classname\' => \'example\', \'description\' => __(\'A widget that displays the chosen gallery images and link from lundhs \', \'example\') );
    
    $control_ops = array( \'width\' => 300, \'height\' => 350, \'id_base\' => \'example-widget\' );
    
    $this->WP_Widget( \'example-widget\', __(\'Reference Projects\', \'example\'), $widget_ops, $control_ops );
  }


  function widget( $args, $instance ) {

    extract( $args );

    //Our variables from the widget settings.
    $titlewidget = apply_filters(\'widget_title\', $instance[\'titlewidget\'] );
    $introtext = $instance[\'introtext\'];
    $title = $instance[\'title\'];
    $name = $instance[\'name\'];
    $img = $instance[\'img\'];
    $show_info = isset( $instance[\'show_info\'] ) ? $instance[\'show_info\'] : false;

    echo $before_widget;

?>
<?php 
if($titlewidget)
  ?>


<h4 class="widget-title"><?php echo $titlewidget;?></h4>
<?php 
if($introtext)
?>
<p> <?php echo $introtext; ?></p>
    <div class="row">
<?php 
//display gallery img
if ( $img)
  ?>
<a class="columns four" href="<?php echo $name; ?>">
     <img class="imggallery" src="<?php echo $img; ?>">
   </a>
    <?php
  // Display the gallery name and link 
    if ( $title )
      ?>
     <a class="columns eight imggallery_link" href="<?php echo $name; ?>"><?php echo $title; ?></a>

</div>

<?php    
    echo $after_widget;
  }

  //Update the widget 
   
  function update( $new_instance, $old_instance ) {
    $instance = $old_instance;

    //Strip tags from title and name to remove HTML 
    $instance[\'titlewidget\'] = strip_tags( $new_instance[\'titlewidget\'] );
    $instance[\'introtext\'] = strip_tags( $new_instance[\'introtext\'] );
    $instance[\'title\'] = strip_tags( $new_instance[\'title\'] );
    $instance[\'name\'] = strip_tags( $new_instance[\'name\'] );
    $instance[\'show_info\'] = $new_instance[\'show_info\'];
    $instance[\'img\'] = $new_instance[\'img\'];


    return $instance;
  }

  
  function form( $instance ) {
 if ( is_active_widget( false, false, $this->id_base, true ) ) {?>
<script type="text/javascript">
    jQuery(document).ready(function($) {
//load on page load
 alert(\'this is the if!\');
});
    </script>


  <?php
} 

  else { 
    ?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
});
    </script>

<?php  
}

    //Set up some default widget settings.
    $defaults = array( \'title\' => __(\'Example\', \'example\'), \'introtext\' => __(\'introtext\', \'example\'), \'titlewidget\' => __(\'Reference Project\', \'example\'), \'img\' => __(\'img\', \'example\'), \'name\' => __(\'link goes here\', \'example\'), \'show_info\' => true );
    $instance = wp_parse_args( (array) $instance, $defaults ); 
    wp_localize_script( \'some_handle\', \'object_name\', $instance );
    ?>
   <h3>Gallery selector for Lundhs</h3>
    <p>
    <label for="<?php echo $this->get_field_id( \'titlewidget\' ); ?>"><?php _e(\'Widget Title:\', \'example\'); ?></label>
      <input type="text" class="titlewidget" name="<?php echo $this->get_field_name( \'titlewidget\' ); ?>" value="<?php echo $instance[\'titlewidget\']; ?>" style="width:100%;" />
    </p>
    <p>
    <label for="<?php echo $this->get_field_id( \'introtext\' ); ?>"><?php _e(\'Intro text:\', \'example\'); ?></label>
      <input type="text" class="introtext" name="<?php echo $this->get_field_name( \'introtext\' ); ?>" value="<?php echo $instance[\'introtext\']; ?>" style="width:100%;" />
    </p>
      <h4 style="text-align: center;">First Pick your images</a>
    <div class="area"></div>

<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
    <h3>Your current front end projects</h3>
    <h4>Reference project 1</h4>
    <div class="gallery_one_image_wrap">
    <img class="gallery_one" src="<?php echo $instance[\'img\']; ?>" /><br/>
    </div>
    <p>
      <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e(\'Title:\', \'example\'); ?></label>
      <input type="text" class="title" name="<?php echo $this->get_field_name( \'title\' ); ?>" value="<?php echo $instance[\'title\']; ?>" style="width:100%;" />
    </p>
    <p>
      <label for="<?php echo $this->get_field_id( \'name\' ); ?>"><?php _e(\'The link:\', \'example\'); ?></label>
      <input type="text" class="link" id="<?php echo $this->get_field_id( \'name\' ); ?>" name="<?php echo $this->get_field_name( \'name\' ); ?>" value="<?php echo $instance[\'name\']; ?>" style="width:100%;" />
    </p>
    
    //img Input.
    <p>
      <label for="<?php echo $this->get_field_id( \'img\' ); ?>"><?php _e(\'The Link to the image:\', \'example\'); ?></label>
      <input type="text" class="img" id="<?php echo $this->get_field_id( \'img\' ); ?>" name="<?php echo $this->get_field_name( \'img\' ); ?>" value="<?php echo $instance[\'img\']; ?>" style="width:100%;" />
    </p>
<div class="addinput">
<p>
<a href="#" class="addNew">Add new project</a>
</p>
</div>
  <?php
  }
}
我也试着把它移到class MY_Widget extends WP_Widget { } 然后添加add_action.像这样:

    class MY_Widget extends WP_Widget {

  function MY_Widget() {
    $widget_ops = array( \'classname\' => \'example\', \'description\' => __(\'A widget that displays the chosen gallery images and link from lundhs \', \'example\') );
    
    $control_ops = array( \'width\' => 300, \'height\' => 350, \'id_base\' => \'example-widget\' );
    
    $this->WP_Widget( \'example-widget\', __(\'Reference Projects\', \'example\'), $widget_ops, $control_ops );
  }
  add_action(\'widgets_init\', \'jsadd\');
  function jsadd(){

 if ( is_active_widget( false, false, \'MY_Widget\', true ) ) {?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
  alert("we made it this far and this is the If!!");
});
    </script>


  <?php
} 

  else { 
    ?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
  alert("we made it this far!!");
});
    </script>

<?php  
}

  }
但还是没有运气。有人知道我做错了什么吗?

1 个回复
最合适的回答,由SO网友:Eric Holmes 整理而成

使用wp_enqueue_script. 在排队时为js文件指定一个名称,它将阻止文件多次排队。现在你的JS已经足够简单了,但随着它变得越来越复杂,最好让它在外面,在里面。js文件。

add_action( \'wp_enqueue_scripts\', \'add_my_js\' );
function add_my_js() {
    wp_enqueue_script( \'my-script\', get_stylesheet_directory_uri() . \'/js/my-script.js\' );
}
要向JS文件添加变量,请查看wp_localize_script. 这允许您指向相同的JS句柄(在本例中,my-script, 并通过单个对象将变量附加到它们上。示例:

 add_action( \'wp_enqueue_scripts\', \'add_my_js\' );
    function add_my_js() {
        wp_enqueue_script( \'my-script\', get_stylesheet_directory_uri() . \'/js/my-script.js\' );
       wp_localize_script( \'my-script\', \'myData\', array( \'var1\' => $variable1, \'var2\' => $something_else ) );
    }
然后,在JS文件中,可以调用myData.var1myData.var2 在对象表示法中。

这里需要记住的一点是,这些变量需要在wp_enqueue_scripts 操作被调用,因此最好在调用之前进行声明,如果尚未设置,则在函数中进行声明。

结束