Scratch的Elementor自定义小部件

时间:2019-11-20 12:53:45

标签: php wordpress widget custom-wordpress-pages elementor

在一个项目中,我必须在Elementor中创建一个轮播,该轮播应如下图所示:

轮播设计

enter image description here

使用Elementor中的小部件,我无法创建这样的轮播,因此我尝试使用Easy-Responsive-jQuery-Carousel创建自己的轮播:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<title>jQuery FilmRoll  Examples</title>
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width">
	<link rel="stylesheet" href="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/css/bootstrap.min.css">
	<link rel="stylesheet" href="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/css/bootstrap-responsive.min.css">
	<style type="text/css">
		body {
    padding-top: 0;
    padding-bottom: 40px;
}
.hero-unit {
  text-align: center;
  border-radius: 0;
  margin: 150px 0 0 0;
  background: #1e5799; /* Old browsers */
  background: -moz-linear-gradient(top,  #1e5799 0%, #338cd6 59%, #ffffff 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(59%,#338cd6), color-stop(100%,#ffffff)); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top,  #1e5799 0%,#338cd6 59%,#ffffff 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top,  #1e5799 0%,#338cd6 59%,#ffffff 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(top,  #1e5799 0%,#338cd6 59%,#ffffff 100%); /* IE10+ */
  background: linear-gradient(to bottom,  #1e5799 0%,#338cd6 59%,#ffffff 100%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
}
.hero-unit h1, .hero-unit p.white { color: white; }
.hero-unit h1 img { vertical-align: bottom; }
.hero-unit p { margin-top: 30px; }
.film_roll_wrapper img {
  border: 10px solid white;
  box-shadow: 7px 7px 15px #777;
  margin-left: 5px;
  margin-right: 5px;
  transition: all 1s ease;
}
.film_roll_wrapper .active img {
  border: 10px solid yellow;
  height: 600px;
}
.film_roll_container {
  position: relative;
}
.film_roll_child.active {
    padding-top: 70px;
}

@media (max-width: 979px) {
  body {
    padding-top: 0px;
  }
  .navbar-fixed-top {
    margin-bottom: 0;
  }
}

@media (max-width: 767px) {
  .hero-unit {
    margin-left: -20px;
    margin-right: -20px;
  }
}
	</style>
</head>
<body>
    <div id='film_roll_1'>
		<div><a href='#'><img src="https://placehold.it/800x530"></a></div>
		<div><a href='#'><img src="https://placehold.it/800x530"></a></div>
		<div><a href='#'><img src="https://placehold.it/800x530"></a></div>
		<div><a href='#'><img src="https://placehold.it/800x530"></a></div>
		<div><a href='#'><img src="https://placehold.it/800x530"></a></div>
	</div>

	<script src="https://code.jquery.com/jquery-latest.min.js"></script>
	<script src="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/js/bootstrap.min.js"></script> 
	<!--<script src="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/js/jquery.film_roll.js"></script>--> 
	<script type="text/javascript">
(function() {
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  this.FilmRoll = (function() {
    function FilmRoll(options) {
      this.options = options != null ? options : {};
      this.rotateRight = __bind(this.rotateRight, this);
      this.rotateLeft = __bind(this.rotateLeft, this);
      this.moveRight = __bind(this.moveRight, this);
      this.moveLeft = __bind(this.moveLeft, this);
      this.clearScroll = __bind(this.clearScroll, this);
      this.configureScroll = __bind(this.configureScroll, this);
      this.configureWidths = __bind(this.configureWidths, this);
      this.configureHover = __bind(this.configureHover, this);
      if (this.options.container) {
        this.div = jQuery(this.options.container);
        if (this.div.length) {
          this.configure();
        }
      }
    }

    FilmRoll.prototype.configure = function() {
      var first_child, shuttle_width,
        _this = this;
      this.children = this.div.children();
      this.children.wrapAll('<div class="film_roll_wrapper"></div>');
      this.children.wrapAll('<div class="film_roll_shuttle"></div>');
      this.wrapper = this.div.find('.film_roll_wrapper');
      this.shuttle = this.div.find('.film_roll_shuttle');
      this.rotation = [];
      shuttle_width = this.options.shuttle_width ? parseInt(this.options.shuttle_width, 10) : 10000;
      this.shuttle.width(shuttle_width);
      this.height = this.options.height ? parseInt(this.options.height, 10) : 0;
      this.wrapper.height(this.height);
      this.shuttle.height(this.height);
      if (!(this.options.no_css === true || document.film_roll_styles_added)) {
        jQuery("<style type='text/css'>        .film_roll_wrapper {display: block; text-align: center; float: none; position: relative; top: auto; right: auto; bottom: auto; left: auto; z-index: auto; width: 100%; margin: 0 !important; padding: 0 !important; overflow: hidden; width: 100%}        .film_roll_shuttle {text-align: left; float: none; position: absolute; top: 0; left:0; right: auto; bottom: auto; margin: 0 !important; padding: 0 !important; z-index: auto}        .film_roll_prev, .film_roll_next {position:absolute; top:48%; left:15px; width:40px; height:40px; margin:-20px 0 0 0; padding:0; font-size:60px; font-weight:100; line-height:30px; color:white; text-align: center; background: #222; border: 3px solid white; border-radius:23px; opacity:0.5}        .film_roll_prev:hover, .film_roll_next:hover {color:white; text-decoration:none; opacity:0.9}        .film_roll_next {left:auto; right:15px}        .film_roll_pager {text-align:center}        .film_roll_pager a {width:5px; height:5px; border:2px solid #333; border-radius:5px; display:inline-block; margin:0 5px 0 0; transition: all 1s ease}        .film_roll_pager a:hover {background: #666}        .film_roll_pager a.active {background: #333;}        .film_roll_pager span {display:none} .film_roll_child .active{padding-top: 70px!important;}     </style>").appendTo('head');
        document.film_roll_styles_added = true;
      }
      if (this.options.pager !== false) {
        this.pager = jQuery('<div class="film_roll_pager">');
        this.div.append(this.pager);
        this.children.each(function(i, e) {
          var link;
          link = jQuery("<a href='#' data-id='" + e.id + "'><span>" + (i + 1) + "</span></a>");
          _this.pager.append(link);
          return link.click(function() {
            var direction, rotation_index;
            _this.index = i;
            rotation_index = jQuery.inArray(_this.children[i], _this.rotation);
            direction = rotation_index < (_this.children.length / 2) ? 'right' : 'left';
            _this.moveToIndex(_this.index, direction, true);
            return false;
          });
        });
      }
      this.pager_links = this.div.find('.film_roll_pager a');
      this.mouse_catcher = jQuery('<div style="position:absolute; top:0; left: 0; height: 100%; width: 100%;" class="film_roll_mouse_catcher"></div>');
      this.mouse_catcher.appendTo(this.wrapper).mousemove(function(event) {
        _this.clearScroll();
        return _this.mouse_catcher.remove();
      });
      first_child = null;
      this.children.each(function(i, e) {
        var $el;
        $el = jQuery(e);
        $el.attr('style', 'position:relative; display:inline-block; vertical-align:middle');
        $el.attr('data-film-roll-child-id', i);
        $el.addClass("film_roll_child");
        return _this.rotation.push(e);
      });
      if (this.options.prev && this.options.next) {
        this.prev = jQuery(this.options.prev);
        this.next = jQuery(this.options.next);
      } else {
        this.wrapper.append('<a class="film_roll_prev" href="#">&lsaquo;</a>');
        this.wrapper.append('<a class="film_roll_next" href="#">&rsaquo;</a>');
        this.prev = this.div.find('.film_roll_prev');
        this.next = this.div.find('.film_roll_next');
      }
      this.prev.click(function() {
        _this.clearScroll();
        return _this.moveRight();
      });
      this.next.click(function() {
        _this.clearScroll();
        return _this.moveLeft();
      });
      this.index = this.options.start_index || 0;
      this.interval = this.options.interval || 4000;
      this.animation = this.options.animation || this.interval / 4;
      jQuery(window).resize(function() {
        return _this.resize();
      });
      jQuery(window).load(function() {
        _this.configureWidths();
        _this.moveToIndex(_this.index, 'right', true);
        if (_this.options.scroll !== false) {
          _this.configureScroll();
          return _this.configureHover();
        }
      });
      this.div.trigger(jQuery.Event("film_roll:dom_ready"));
      return this;
    };

    FilmRoll.prototype.configureHover = function() {
      this.div.hover(this.clearScroll, this.configureScroll);
      if (this.options.prev && this.options.next) {
        this.prev.hover(this.clearScroll, this.configureScroll);
        return this.next.hover(this.clearScroll, this.configureScroll);
      }
    };

    FilmRoll.prototype.configureWidths = function() {
      var max_el_height,
        _this = this;
      this.div.trigger(jQuery.Event("film_roll:before_loaded"));
      this.width = max_el_height = 0;
      this.children.each(function(i, e) {
        var $el, el_height;
        $el = jQuery(e);
        _this.width += $el.outerWidth(true);
        el_height = $el.outerHeight(true);
        if (el_height > max_el_height) {
          return max_el_height = el_height;
        }
      });
      if (!this.options.height) {
        this.height = max_el_height;
      }
      this.wrapper.height(this.height);
      this.shuttle.height(this.height);
      this.real_width = this.width;
      this.shuttle.width(this.real_width * 2);
      return this;
    };

    FilmRoll.prototype.configureScroll = function() {
      var _this = this;
      if (this.scrolled !== true) {
        this.timer = setInterval(function() {
          return _this.moveLeft();
        }, this.interval);
        this.scrolled = true;
      }
      return this;
    };

    FilmRoll.prototype.clearScroll = function() {
      if (this.scrolled !== false) {
        clearInterval(this.timer);
        this.scrolled = false;
      }
      return this;
    };

    FilmRoll.prototype.marginLeft = function(rotation_index, offset) {
      var child, i, margin, _i, _len, _ref;
      if (offset == null) {
        offset = 0;
      }
      margin = 0;
      _ref = this.rotation;
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        child = _ref[i];
        if (i < rotation_index && i >= offset) {
          margin += jQuery(child).outerWidth(true);
        }
      }
      return margin;
    };

    FilmRoll.prototype.marginRight = function(rotation_index, offset) {
      var child, i, margin, _i, _len, _ref;
      if (offset == null) {
        offset = 0;
      }
      offset = this.rotation.length - offset - 1;
      margin = 0;
      _ref = this.rotation;
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        child = _ref[i];
        if (i > rotation_index && i <= offset) {
          margin += jQuery(child).outerWidth(true);
        }
      }
      return margin;
    };

    FilmRoll.prototype.moveLeft = function() {
      this.index = (this.index + 1) % this.children.length;
      this.moveToIndex(this.index, 'left', true);
      return false;
    };

    FilmRoll.prototype.moveRight = function() {
      this.index -= 1;
      if (this.index < 0) {
        this.index = this.children.length - 1;
      }
      this.moveToIndex(this.index, 'right', true);
      return false;
    };

    FilmRoll.prototype.moveToIndex = function(index, direction, animate) {
      var child, new_left_margin, rotation_index, visible_margin, wrapper_width,
        _this = this;
      if (animate == null) {
        animate = true;
      }
      child = this.children[index];
      rotation_index = jQuery.inArray(child, this.rotation);
      this.children.removeClass('active');
      jQuery(child).addClass('active').trigger(jQuery.Event("film_roll:activate"));
      this.pager_links.removeClass('active');
      jQuery(this.pager_links[index]).addClass('active');
      wrapper_width = this.wrapper.width();
      if (wrapper_width < this.real_width) {
        visible_margin = (wrapper_width - jQuery(child).outerWidth(true)) / 2;
        if (direction === 'right') {
          while (rotation_index === 0 || this.marginLeft(rotation_index) < visible_margin) {
            this.rotateRight();
            rotation_index = jQuery.inArray(child, this.rotation);
          }
        } else {
          while (rotation_index === this.children.length - 1 || this.marginRight(rotation_index) < visible_margin) {
            this.rotateLeft();
            rotation_index = jQuery.inArray(child, this.rotation);
          }
        }
        new_left_margin = -1 * (this.marginLeft(rotation_index) - visible_margin);
        if (animate) {
          this.shuttle.stop().animate({
            'left': new_left_margin
          }, this.animation, 'swing', function() {
            return _this.div.trigger(jQuery.Event("film_roll:moved"));
          });
        } else {
          this.shuttle.css('left', new_left_margin);
          this.div.trigger(jQuery.Event("film_roll:moved"));
        }
      } else {
        this.shuttle.css('left', (wrapper_width - this.width) / 2);
      }
      return this;
    };

    FilmRoll.prototype.resize = function() {
      var _this = this;
      this.clearScroll();
      clearTimeout(this.resize_timer);
      this.resize_timer = setTimeout(function() {
        _this.configureScroll();
        _this.moveToIndex(_this.index, 'left');
        return _this.div.trigger(jQuery.Event("film_roll:resized"));
      }, 200);
      return this;
    };

    FilmRoll.prototype.rotateLeft = function() {
      var _css_left, _first_child, _shuttle_left;
      _css_left = this.shuttle.css('left');
      _shuttle_left = _css_left ? parseInt(_css_left, 10) : 0;
      _first_child = this.rotation.shift();
      this.rotation.push(_first_child);
      this.shuttle.css('left', _shuttle_left + jQuery(_first_child).outerWidth(true));
      return this.shuttle.append(this.shuttle.children().first().detach());
    };

    FilmRoll.prototype.rotateRight = function() {
      var _css_left, _last_child, _shuttle_left;
      _css_left = this.shuttle.css('left');
      _shuttle_left = _css_left ? parseInt(_css_left, 10) : 0;
      _last_child = this.rotation.pop();
      this.rotation.unshift(_last_child);
      this.shuttle.css('left', _shuttle_left - jQuery(_last_child).outerWidth(true));
      return this.shuttle.prepend(this.shuttle.children().last().detach());
    };

    return FilmRoll;

  })();

}).call(this);
	</script>

	<script type="text/javascript">
(function() {
  jQuery(function() {
    this.film_rolls || (this.film_rolls = []);
    this.film_rolls['film_roll_1'] = new FilmRoll({
      container: '#film_roll_1',
      height: 750
    });
    //return true;
  });

}).call(this);
	</script>
</body>
</html>

客户希望不从Custom FIeld修改轮播,而更容易做到,而是直接从Elementor修改。因此,我尝试为此创建自己的小部件。 在youtube上学习完教程并使用Elementor官方文档中的信息之后 网站和我创建了以下文件。 在我以boostrap4-child主题在文件夹custom_widget_elementor中创建此php文件后,填充框位于boostrap4-child的文件夹中,名称为custom_widget_elementor。

//my-widgets.php
<?php
class My_Elementor_Widgets {

	protected static $instance = null;

	public static function get_instance() {
		if ( ! isset( static::$instance ) ) {
			static::$instance = new static;
		}

		return static::$instance;
	}

	protected function __construct() {
		require_once('widget1.php');
		add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_widgets' ] );
	}

	public function register_widgets() {
		\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Elementor\My_Widget_1() );
	}

}

add_action( 'init', 'my_elementor_init' );
function my_elementor_init() {
	My_Elementor_Widgets::get_instance();
}
?>

//widget1.php
<?php
namespace Elementor;

class My_Widget_1 extends Widget_Base {
	
	public function get_name() {
		return 'title-subtitle';
	}
	
	public function get_title() {
		return 'title & sub-title';
	}
	
	public function get_icon() {
		return 'fa fa-font';
	}
	
	public function get_categories() {
		return [ 'basic' ];
	}
	
	protected function _register_controls() {

		$this->start_controls_section(
			'section_title',
			[
				'label' => __( 'Content', 'elementor' ),
			]
		);
		
		$this->add_control(
			'title',
			[
				'label' => __( 'Title', 'elementor' ),
				'label_block' => true,
				'type' => Controls_Manager::TEXT,
				'placeholder' => __( 'Enter your title', 'elementor' ),
			]
		);

		$this->add_control(
			'subtitle',
			[
				'label' => __( 'Sub-title', 'elementor' ),
				'label_block' => true,
				'type' => Controls_Manager::TEXT,
                'placeholder' => __( 'Enter your sub-title', 'elementor' ),
			]
		);

		$this->add_control(
			'link',
			[
				'label' => __( 'Link', 'elementor' ),
				'type' => Controls_Manager::URL,
				'placeholder' => __( 'https://your-link.com', 'elementor' ),
				'default' => [
					'url' => '',
				]
			]
		);

		$this->end_controls_section();
	}
	
	protected function render() {

        $settings = $this->get_settings_for_display();
        $url = $settings['link']['url'];
		echo  "<a href='$url'><div class='title'>$settings[title]</div> <div class='subtitle'>$settings[subtitle]</div></a>";
		 

	}
	
	protected function _content_template() {

    }
	
	
}
?>

在function.php的子主题中,例如我所写的。

//Function.php
require_once('elementor_custom_catousel/widget1.php');

但是,尽管我已经尝试了很多官方文档中的示例,但这还是行不通的。也就是说,当我保存时,元素的基本类别中没有任何内容,或者如果我想解决这个问题来构建轮播,我只需要制作html模板。

1 个答案:

答案 0 :(得分:1)

Official Documentation上很清楚地提到。

首先,您需要使用功能注册“ elementor / widgets / widgets_registered”挂钩。对于主题适用,您可以采用这种方式-

viewDidLoad()

创建目录名称“ widgets”,放置所有小部件文件。在此目录中,所有插件都将被注册。