I used to use the following function to load a video in the background (jquery 2.2.4):

function getVideo() {
    if ( $('video').length ) {
        $('video').each(function() {
            if (Modernizr.mq('(min-width: 1024px)') && $(this).children().attr('src') === undefined ) {
                var src =  $(this).children().attr("data-src");

After updating to 8.5.6, I must use jquery 3.2.1. So, I had to change the line $('video').load() to $('video').on('load', function(){});. However, the video is not loading anymore. I have tested the code, and each line gets executed until it comes to $('video').on('load', function(){});. I don't know why it is not loading. Is it because .on('load', function(){}) is only accessible by windowproperties? If so, then how can I load the video using document properties?

The markup in the theme of that specific block would be: $variables['video_markup'] = '<video autoplay loop muted id="bgvid"><source data-src="'.$video_link.'" type="video/mp4"></video>';

Which roughly translates to:

<video autoplay="" loop="" muted="" id="bgvid" data-video="0"><source data-src="https://somevideo" type="video/mp4"></video>

I have been targeting this video element here. ANy suggestions will be appreciated.

Also, is there any way to force Drupal 8.5 to use Jquery 2.x? I tried this How do I use a jQuery version different from the default one used by core?, but it didn't work for me.

1 Answer 1


With Drupal, you don't (need to) use $.on(). It is handled through a combination of Drupal.behaviors, $.once(), and Drupal.attachBehaviors().

First you create a function using $.once() that will add your handler the same as you would with $.on(), but use $.once() to ensure that the handler is only applied a single time:

function addVideoHandler(context) {
  $(context).find(".video").once("add-video-handler").each(function() {
    $(this).load(function() {
      alert("video loaded");

Next, this function is called in Drupal.behaviors:

Drupal.behaviors.someArbitraryButUniqueKey = {
  attach: function (context) {

This will be executed on page load, which will add the handler to all .video elements on the page. However, unlike other onload handlers (JS, jQuery), this is also called every time after an Ajax Call is executed, with any new loaded content passed as context. Therefore any newly loaded .video elements will have the handler applied to them - same as with $.on().

Generally, this is all you will need to do. However, if you are loading any content through Ajax in one of your own functions, you will need to pass the newly loaded content through Drupal.attachBehaviors():

  url: "http://example.com/callback",
  success: function (data) {
    var targetElement = $("some_div");
    // Insert the returned HTML into the DOM, casting it as HTML.
    // Finally pass the new content through Drupal.attachBehaviors().
    // Note - pass through the HTML, NOT a jQuery object. This can be done
    // by passing the [0]th element of the jQuery object.

This will call every Drupal.behaviors element, passing it the newly loaded content, which in turn will have the handlers attached. Using $.once() ensures that handlers are not accidentally applied multiple times, for example if someone calls Drupal.attachBehaviors() without passing a value, which in turn will pass the entire document.

  • Thanks for your answer. You are still using the .load() method in your addVideoHandler, which has been removed in Jquery3. I am not sure if it will work.
    – DarkMatter
    Commented Aug 20, 2018 at 17:07

Your Answer

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

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