Closed nnnswordfish closed 5 years ago
I'm using 'elementor/frontend/before_register_scripts' to register Isotope library and addAction( 'frontend/element_ready/' + widget, callback );
js hook to run isotope after the widget is initialized.
@nnnswordfish
We can't really tell without seeing the widget PHP code and JS handler.
Thanks for the prompt reply!
The script is registered like this:
public function register_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_script(
'isotope',
WPR_ADDONS_URL . 'assets/lib/isotope/isotope' . $suffix . '.js',
[
'jquery',
],
'3.0.6',
true
);
}
add_action( 'elementor/frontend/before_register_scripts', [ $this, 'register_scripts' ], 998 );
Then, in the widget code:
public function get_script_depends() { return [ 'isotope' ]; }
This way I enqueue script to handle all widgets:
public function enqueue_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_script(
'wpr-addons-js',
WPR_ADDONS_URL . 'assets/js/frontend' . $suffix . '.js',
[
'jquery',
],
Plugin::instance()->get_version(),
true
);
}
add_action( 'elementor/frontend/before_enqueue_scripts', [ $this, 'enqueue_scripts' ], 998 );
And the JS inside this file looks like this:
( function( $, elementor ) {
"use strict";
var WprElements = {
init: function() {
var widgets = {
'wpr-grid.default' : WprElements.widgetGrid,
};
$.each( widgets, function( widget, callback ) {
window.elementorFrontend.hooks.addAction( 'frontend/element_ready/' + widget, callback );
});
},
widgetNavMenu: function( $s
widgetGrid: function( $scope ) {
var bodyWidth = $( 'body' ).width(),
viewport = window.innerWidth,
grid = $scope.find( '.wpr-grid' ),
item = grid.find( '.grid-item' ),
columns = 3,
gutter = 10,
contWidth = grid.width() + gutter - 0.3;
item.outerWidth( Math.floor( contWidth / columns - gutter ) );
grid.isotope({
itemSelector: '.grid-item',
layoutMode: 'masonry',
masonry: {
comlumnWidth: contWidth / columns,
gutter: gutter
}
});
}, // End widgetNavMenu
} // End WprElements
$( window ).on( 'elementor/frontend/init', WprElements.init );
}( jQuery, window.elementorFrontend ) );
The grid itself is a standard WordPress loop:
<section class="wpr-grid">
<article class="grid-item"> ....
Hope now it makes sense. Please note: It works fine until I tweak any option which refreshes the widget in an editor.
I think you just need to add element_ready hook.
$(window).on('elementor/frontend/init', function () {
WprElements.init();
elementorFrontend.hooks.addAction('frontend/element_ready/YourWidget.default', WprElements.init );
}
I think you just need to add element_ready hook.
$(window).on('elementor/frontend/init', function () { WprElements.init(); elementorFrontend.hooks.addAction('frontend/element_ready/YourWidget.default', WprElements.init ); }
Thanks but I already have that hook, please read the above code carefully.
Sorry, didnt seen this line. You could try to rename your widget from wpr-grid to wpr_grid or wprGrid. A year ago i have had some issues with hyphens in widget-names, so i use always underscores.
Or check in widgetGrid() if $scope exists.
Thanks for the reply, unfortunately, that does not help. Yes, $scope exits as I told you it works on load but it is being destroyed after any control refreshes this widget.
@bainternet, Still looking for an answer...
Is WprElements.widgetGrid() called only onload, or after any control refresh? It should be called after any refresh.
If it is called like it should, than possibly an other plugin destroy your isotope. You could try a setTimeout as a workaround.
@crazypsycho Thanks for the reply!
I've already tried timeouts with different combinations but unfortunately, it does not make any sense. BTW how could I call it after any control refresh?
Normally the frontend/element_ready/ hook triggers automatically always when the widget is refreshed.
But in the fist line of your js-code is ( function( $, elementor ) { You could try to change it to ( function( $, elementorFront ) {
cause Elementor set itself the variable elementor. This could possibly be a problem.
Other idea is, that elementor can´t find WprElements.widgetGrid. You could move widgetGrid out of WprElements and define window.widgetGrid.
@crazypsycho Thanks again, appreciate your effort!
I've tried everything but unfortunately, even that does not make any sense.
Than i´m sorry, but i have currently no ideas anymore. Your code looks good and should work. Maybe somebody will see something we don´t see.
@crazypsycho
Possibly I've found the issue source. After refresh isotope can't find an itemSelector: '.grid-item'
, because I can't pass an object, isotope only accepts a string parameter. I need to somehow pass $scope.find( '.wpr-grid .grid-item' )
and it will probably work. Any ideas?
Now I can confirm that the only solution is to pass an object selector instead of the string to get it working.
P.S. I've changed a piece of code in iSotope plugin file and managed to get it working but It's not a correct way to do it.
Oh yes it seems to be an isotope-issue. Isotope seems to have a problem if its an iframe (like in elementor) There are already issues reported about this: https://github.com/metafizzy/isotope/issues/1456 https://github.com/metafizzy/flickity/issues/861
But i dont know if they will fix this.
@crazypsycho Thanks mate, you are very welcome!
Glad you guys figured it out.
Hi. Author of Isotope and Flickity here. I've received a PR that may fix this issue. See metafizzy/flickity#900
The problem is that I check for valid HTML elements like so:
function getIsElement( elem ) {
return elem instanceof HTMLElement
}
But, within Elementor, HTMLElement
doesn't exist. The proposed fix adds several element-like checks:
function getIsElement( elem ) {
if ( typeof HTMLElement == 'object' ) {
return elem instanceof HTMLElement;
}
return elem && typeof elem == 'object' && elem.nodeType == 1 &&
typeof elem.nodeName == 'string';
}
I'm curious if there's a more elegant solution for this Elementor-specific problem.
@desandro
Not sure why you say that HTMLElement
doesn't exist in elementor, HTMLElement
is a native browser function which identify HTML elements and Elementor works with and around HTML elements.
as for your question, I would do something like this:
function getIsElement( elem ) {
//Using W3 DOM2 (works for FF, Opera and Chrome)
if ( 'HTMLElement' in window ) {
return ( elem && elem instanceof HTMLElement );
}
// SVG Element support
if ( 'Element' in window ) {
return ( elem && elem instanceof Element );
}
return !! ( elem && 'object' === typeof elem && 1 === elem.nodeType && 'string' === typeof elem.nodeName );
}
thanks
Thanks for that. Sorry, I don't a test case on hand to reproduce this issue, so I'm not sure where the disconnect is. From my side, @wayheming is proposing not using HTMLElement
, which solves their problem using Flickity with Elementor, related to iframe
usage.
Hello @desandro and @bainternet thank you for your time. I tried to recreate the problem in as much detail as possible.
I created a plugin to recreate the problem, here are the source code for the plugin. https://drive.google.com/file/d/12h7BGh1sOMAw86RrxV6vLCZnUyvh5FsJ/view?usp=sharing
This is the page where the problem is recreated. http://mamkinhacker.fun/wordpress/elementor-5
Here is the admin access http://mamkinhacker.fun/wordpress/wp-admin admin admin
I created a test element Carousel http://prntscr.com/mk3ijv
Here are the results of a simple check. http://prntscr.com/mk3j16
http://prntscr.com/mk3jgx http://prntscr.com/mk3jmb http://prntscr.com/mk3k2q
If you need additional materials or anything else let me know. Thanks.
My sites were infected with a virus after I posted the accesses here which was stupid on my part 😥 if someone will consider this problem contact me and I will create a test site again 🤣
Hello everybody, I have faced the same problem. Do you have fixed it? Please help me, thanks so much!
Hi @bainternet, do you have any solutions for the problem, please help me.
I've created a portfolio grid widget with isotope. It works fine on Frontend and in an Editor as well, but once I tweak an option which refreshes the widget, it stops working. Any ideas?
P.S. I'm a PRO user and support redirected me here.