JavaScript HTML Attribut zu Link hinzufügen

Coolzero82

Lt. Junior Grade
Registriert
Okt. 2011
Beiträge
308
Hallo,
ich habe eine Javascript Datei welche aus einer html Datei Werte übergeben bekommt, die dann zu einem Link zusammengeführt werden, das klappt auch soweit, nur jetzt würde ich gerne dem Link noch das HTML Video controls Attribut hinzufügen, aber da scheitere ich irgendwie.
Die Javascript Datei sieht so aus:

Javascript:
/* FTUI Plugin
* ...
*/

/* global ftui:true, Modul_widget:true */

"use strict";

var Modul_video = function () {

    function update_classes(state, elem) {
        //set colors according matches for values
        var states = elem.data('states');
        var classes = elem.data('classes');
        if (states && classes) {
            var idx = ftui.indexOfGeneric(states, state);
            var elemImg = elem.find('img');
            if (idx > -1) {
                for (var i = 0, len = classes.length; i < len; i++) {
                    elemImg.removeClass(classes[i]);
                }
                elemImg.addClass(classes[idx]);
            }
        }
    }


    function addurlparam(uri, key, value) {
        // http://stackoverflow.com/a/6021027
        var hash = uri.replace(/^.*#/, '#');
        if (hash != uri) {
            uri = uri.replace(hash, '');
        } else {
            hash = '';
        }
        var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
        var separator = uri.indexOf('?') !== -1 ? "&" : "?";

        if (uri.match(re)) {
            uri = uri.replace(re, '$1' + key + "=" + value + '$2');
        } else {
            uri = uri + separator + key + "=" + value;
        }
        uri += hash;
        ftui.log(1, 'widget_video url=' + uri);
        return uri;
    }

    function init_attr(elem) {
        elem.initData('state-get', '');
        elem.initData('opacity', 0.8);
        elem.initData('height', 'auto');
        elem.initData('width', '100%');
        elem.initData('size', '100%');
        elem.initData('part', -1);
        elem.initData('url', '');
        elem.initData('get', (elem.data('url') === '') ? 'STATE' : '');
        elem.initData('path', '');
        elem.initData('suffix', '');
        elem.initData('substitution', '');
        elem.initData('refresh', 15 * 60);
        elem.initData('controls', 'True');

        // if hide reading is defined, set defaults for comparison
        if (elem.isValidData('hide')) {
            elem.initData('hide-on', 'true|1|on');
        }
        elem.initData('hide', elem.data('get'));
        if (elem.isValidData('hide-on')) {
            elem.initData('hide-off', '!on');
        }
        me.addReading(elem, 'hide');

        me.addReading(elem, 'get');
        me.addReading(elem, 'state-get');
    }

    function init() {
        me.elements = $('div[data-type="' + me.widgetname + '"]:not([data-ready])', me.area);
        me.elements.each(function (index) {
            var elem = $(this);
            elem.attr("data-ready", "");

            me.init_attr(elem);
            $('video', elem).remove();
            var elemImg = $('<video/>', {
                alt: 'video',
            }).appendTo(elem);
            elemImg.css({
                'opacity': elem.data('opacity'),
                'height': elem.data('height'),
                'width': elem.data('width'),
                'max-width': elem.data('size'),
            });


            //3rd party source refresh
            if (elem.data('url')) {
                var url = elem.data('url');
                if (elem.data('nocache') || elem.hasClass('nocache')) {
                    url = addurlparam(url, '_', new Date().getTime());
                }
                elemImg.attr('src', url);

                var counter = 0;
                var refresh = elem.data('refresh');
                setInterval(function () {
                    var isVisible = (elem[0].offsetParent !== null);
                    counter++;
                    if (counter >= refresh) {
                        counter = 0;
                        if (isVisible) {
                            if (url.match(/_=\d+/)) {
                                url = addurlparam(url, '_', new Date().getTime());
                            }
                            ftui.log(2, 'Update video widget source. URL=' + url);
                            elemImg.attr('src', url);
                        }
                    }
                }, 1000);
            }
            // onClick events
            elem.on('click', function (e) {
                var cmd = elem.data('fhem-cmd');
                if (cmd)
                    ftui.setFhemStatus(cmd);
            });
        });
    }

    function update(dev, par) {

        me.elements.filterDeviceReading('get', dev, par)
            .each(function (index) {
                var elem = $(this);
                var value = elem.getReading('get').val;
                value = ftui.getPart(value, elem.data('part'));
                value = me.substitution(value, elem.data('substitution'));
                if (value) {
                    var src = [elem.data('path'), value, elem.data('suffix')].join('');
                    elem.find('video').attr('src', src);
                }
            });

        //extra reading for extra classes
        me.elements.filterDeviceReading('state-get', dev, par)
            .each(function (idx) {
                var elem = $(this);
                var state = elem.getReading('state-get').val;
                if (state) {
                    var part = elem.data('part');
                    var val = ftui.getPart(state, part);
                    update_classes(val, elem);
                }
            });

        //extra reading for hide
        me.update_hide(dev, par);
    }

    // public
    // inherit all public members from base class
    var me = $.extend(new Modul_widget(), {
        //override or own public members
        widgetname: 'video',
        addurlparam: addurlparam,
        init: init,
        init_attr: init_attr,
        update: update,
    });

    return me;
};

Die html Datei liefert folgende Daten

Code:
<div data-type="video"
                 data-device="Kameras"
                 data-get="videoFilename"
                 data-path="http://192.168.188.47:8085/fhem/tablet/BlinkCamera/Kameras/thumbnail/camera/"
                 data-width="400"
                 data-height="200"
                 class="nocache"></div>

Was mache ich da falsch?

Danke
 
Zuletzt bearbeitet:
Auf den ersten Blick passen die 2 Code Schnipsel nicht zusammen. Irgendwas fehlt da. Oder wo kommt "data-device" her?

Welches Skript hast du denn da verwendet?
 
Was meinst du genau? Weil in der JavaScript darein kein data-device Vorkommt? data-device ist ein globales Attribut, was in der JavaScript Datei nicht explizit abgefragt wird.

Das Skript an sich funktioniert, ich habe das Video wird angezeigt so wie es soll, einzig das „controls“ Tag bekomme ich nicht an das Ende des links abgefügt
 
Was hast Du denn schon versucht?

Eigentlich sollte es genügen, bei der Definition des VIDEO-Tags in Zeile 86 der JS-Datei das Attibut einfach hinzuzufügen:
Javascript:
var elemImg = $('<video/>',
{
  alt: 'video',
  controls: true
})
.appendTo(elem);

Aber nicht getestet, da ich grad keinen Client dafür bauen mag.

Wenn's so nicht tut, mußt Du mal schauen, ob es mit .prop oder mit .attr zu setzen geht. Das controls-Attribut ist wie alle blanken Attribute ein boolescher Wert, entsprechend kannst Du das mit controls = true bzw controls = false setzen oder auch entfernen. Andere Werte sind dafür nicht zulässig.


Dann wäre das natürlich statisch. Wenn Du die Controls-Eigenschaft irgendworaus ableiten oder übergeben willst, dann mußt Du natürlich den Parser anpassen.
 
RalphS schrieb:
Was hast Du denn schon versucht?

Eigentlich sollte es genügen, bei der Definition des VIDEO-Tags in Zeile 86 der JS-Datei das Attibut einfach hinzuzufügen:
Javascript:
var elemImg = $('<video/>',
{
  alt: 'video',
  controls: true
})
.appendTo(elem);

Aber nicht getestet, da ich grad keinen Client dafür bauen mag.
.

Also damit funktioniert es leider nicht, auch dann sind im Video keine controls aktiv. Der html link der daraus erzeugt wird sieht im Browser dann so aus.
HTML:
<video alt="video" src="http://192.168.188.47:8085/fhem/tablet/BlinkCamera/Kameras/thumbnail/camera/BlinkCamera_Kameras_video_104874385.mp4" style="opacity: 0.8; height: 200px; width: 400px; max-width: 100%;"></video>

Müsste aber ja so aussehen
HTML:
<video alt="video" src="http://192.168.188.47:8085/fhem/tablet/BlinkCamera/Kameras/thumbnail/camera/BlinkCamera_Kameras_video_104874385.mp4" style="opacity: 0.8; height: 200px; width: 400px; max-width: 100%;" controls></video>

RalphS schrieb:
Was hast Du denn schon versucht?

Wenn's so nicht tut, mußt Du mal schauen, ob es mit .prop oder mit .attr zu setzen geht. Das controls-Attribut ist wie alle blanken Attribute ein boolescher Wert, entsprechend kannst Du das mit controls = true bzw controls = false setzen oder auch entfernen. Andere Werte sind dafür nicht zulässig.


Dann wäre das natürlich statisch. Wenn Du die Controls-Eigenschaft irgendworaus ableiten oder übergeben willst, dann mußt Du natürlich den Parser anpassen.

Das ist leider ziemliches Neuland für mich, am liebsten wäre es mir es würde wie bei den anderen Attributen wie z.b. " data-path oder data-get" eine möglichkeit geben das in der .js abzufragen ob es in der html definiert ist und entsprechend dann in dem Link hinzuzufügen.



EDIT
Ich habe es grade hinbekommen, ich habe in der JS Datei folgenden Eintrag hinzugefügt
Code:
elem.initData('controls', '');
unter
Code:
function init_attr(elem) {
und dann in der html Datei eine neue Definition auf
Code:
data-controls="True"
und siehe da schon funktioniert es.

Vielen Dank für die Hilfe
 
Zuletzt bearbeitet:
Hallo,
ich muss das nochmal aufgreifen, ich würde jetzt gerne noch eine "Autoplay" funktion über ein attribut hinzufügen, allerdings bekomme ich es nicht hin, kann mir hier jemand auf die Sprünge helfen, hier der auszug aus der HTML Datei
Code:
<!-- ============== Kamera Alarm ================ -->
<!-- =======================================  -->
<li data-row="4" data-col="4" data-sizex="3" data-sizey="2">
        <header class="headerTransparent">Kamera</header>  
            <div data-type="video"
                 data-controls="true"
                 data-device="Kameras"
                 data-get="videoFilename"
                 data-path="http://192.168.188.47:8085/fhem/tablet/BlinkCamera/Kameras/thumbnail/camera/"
                 data-width="400"
                 data-height="200"
                 class="nocache"></div>

</li>

welche bei den data-controls neben true, false auch autplay anbieten soll.

Die JS Datei ist anbei

Danke
 

Anhänge

Zuletzt bearbeitet:
Was heißt "bekomme es nicht hin"?

Abgesehen davon funktioniert autoplay (offiziell) in Chrome nicht mehr.
Gibt natürlich Workarounds, googlen kannst du aber sicherlich selbst.
 
Hi,
also grundsätzlich funktioniert es schon nicht, ob ich in der .html
Code:
data-controls="true"
oder auch false setze macht keinen unterschied.

Ob die Controls angezeigt werden wird durch die Zeile 91 in der .js gesteuert, wenn ich die auskommentiere oder false setze werden keine Controls angezeigt, allerdings soll das ja nicht über den .js Code gesteuert werden, sondern über die .html konfiguriert werden können.

Zum Thema autoplay welche alternativen gibt es denn die man konfigurieren könnte, so das wenn gewünscht das Video direkt abgespielt wird?

Danke
 
Zum Thema Autoplay:

Grundsätzlich würde ich auf Autoplay einfach verzichten. Ansonsten wenn du es unbedingt haben willst muss du einige Bedinungen erfüllen: Das Video muss standardmässig gemutet sein. Also im Video Tag braucht es ein muted Tag.

Damit das ganze auf iOS auch noch suaber funktioniert muss noch ein playsinline Tag rein.

Also in etwa so:
HTML:
<video muted playsinline>
       {...}
</video>

Für Videos auf Webseiten nutze ich gerne die freie Bibliothekt "video.js" - gerade wenn du das Video noch mit JS steuern willst ist das sehr praktisch - da video.js für alles mögliche Funktionen anbietet und man auf sehr viel Code geschreibsel verzichten kann und so auch eher die Garantie hat das es auf allen Browsern funktioniert.

Link zu Video.js: https://videojs.com/
 
Ich befürchte dafür reichen meine kenntnisse dann nicht......
 
Zurück
Oben