Greasy Fork

html-utils

utils for DOM manipulation and fetching info of a webpage

目前为 2016-05-31 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/20131/128687/html-utils.js

/**
 * Factory that creates customized html-elements
 */
var HtmlFactory = function() {
    /**
     * Adds a HTML child node to a HTML parent node.
     * @param {HtmlElement} elParent - The html parent node
     * @param {HtmlElement} elChild - The html child Element to be connected to the parent node
     * @param {boolean} [asFirstChild] - <code>true</code> to have the child be added as the first child before any other child
     */
    var connectParentChild = function (elParent, elChild, asFirstChild) {
        if (asFirstChild && elParent.hasChildNodes()) {
            elParent.insertBefore(elChild, elParent.firstChild);
        } else {
            elParent.appendChild(elChild);
        }
    };
    /**
     * Removes a HTML child element from a HTML parent node.
     * @param {HTMLElement} elParent - The parent node
     * @param {HTMLElement} elChild - The child node to be removed of the parent element
     */
    var disconnectParentChild = function (elParent, elChild) {
        elParent.removeChild(elChild);
    };
    /**
     * Removes all HTML children from a parent node.
     * @param {HTMLElement} elParent - The HTML parent node
     */
    var removeAllChildren = function (elParent) {
        while (elParent.hasChildNodes()) {
            elParent.removeChild(elParent.firstChild);
        }
    };

    /**
     * @name ElType
     * @type HtmlElement
     * @property {function} addAsLastChild
     * @property {function} addAsFirstChild
     * @property {function} addAsOnlyChild
     */

    /**
     * Creates any type of HTML element.
     * @param {string} elType - The type of element to be created
     * @param {string} [id] - The value for the <code>id</code> attribute
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @returns {ElType} The HTML element
     */
    var createEl = function(elType, id, className) {
        var _el = document.createElement(elType);
        // add params to html Element properties
        var args = { elType:elType, id:id, className:className };
        Object.keys(args).forEach(function(prop){
            if (args[prop] !== undefined) { _el[prop] = args[prop]; }
        });
        /**
         * Adds this HTML element to a parent node HTML element.
         * It will be added as the last child of the node.
         * @this createEl
         * @param {HTMLElement} elParent - The parent HTML node element
         */
        _el.addAsLastChild = function(elParent) { connectParentChild(elParent,_el, false); };
        /**
         * Adds this HTML element to a parent node HTML element.
         * It will be added as the first child of the node.
         * @this createEl
         * @param {HTMLElement} elParent - The parent HTML node element
         */
        _el.addAsFirstChild = function(elParent) { connectParentChild(elParent,_el, true); };
        /**
         * Adds this HTML element to a parent node HTML element.
         * All children elements will be removed and replaced with this node.
         * @this createEl
         * @param {HTMLElement} elParent - The parent HTML node element
         */
        _el.addAsOnlyChild = function(elParent) {
            removeAllChildren(elParent);
            connectParentChild(elParent, _el);
        };
        /**
         * Appends Html node elements to this node as their last children.
         * @param {...HTMLElement} elements - Html elements to be added as children.
         */
        _el.appendChildren = function(elements) {
            for (var i = 0; i <= arguments.length - 1; i++) {
                _el.appendChild(arguments[i]);
            }
        };
        /**
         * Adds Html node Elements to this node as their new children.
         * All current children elements will be removed and replaced with the new children.
         * @param {...HTMLElement} [elements] Html elements to be added as children
         *         No argument will only remove all children.
         */
        _el.setChildren = function(elements) {
            removeAllChildren(_el);
            for (var i = 0; i <= arguments.length - 1; i++) {
                connectParentChild(_el, arguments[i]);
            }
        };
        return _el;
    };
    /**
     * Creates a 'Button' HTML element.
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {function} [callback] - The callback function for the <code>onClick<code> event
     * @param {string} [text] - The content text of the element (text shown on the button)
     * @param {string} [id] - The value for the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'button' HTML element
     */
    var createButton = function(className, callback, text, id) {
        var elButton = createEl('BUTTON', id, className);
        if (typeof callback === 'function') {
            elButton.addEventListener('click', callback);
        }
        if (text !== undefined) {
            elButton.appendChild(document.createTextNode(text));
        }
        return elButton;
    };
    /**
     * Creates a 'div' HTML element.
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {string} [id] - The value for the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'div' HTML element
     */
    var createDiv = function(className, id) {
        return createEl('div', id, className);
    };
    /**
     * Creates an 'input' HTML element as a field for text.
     * @param {number|string} [maxlength] - The maximum number of characters
     * @param {string} [text] - The value of the <code>text</code> attribute (content initially shown in the field)
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {string} [id] - The value for the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'input' HTML element
     */
    var createInput = function(maxlength, text, className, id) {
        var elInputText = createEl('INPUT', id, className);
        if (maxlength !== undefined) { elInputText.maxlength=maxlength; }
        if (text !== undefined) { elInputText.value = text; }
        return elInputText;
    };
    /**
     * Creates a 'label' HTML element.
     * @param {string} htmlFor - The value of the <code>for</code> attribute. The id value of another element to bind the label to that element.
     * @param {string} [text] - The content text of the element (text shown on the label)
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {string} [id] - The value for the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'label' HTML element
     */
    var createLabel = function (htmlFor, text, className, id) {
        var elLabel = createEl('LABEL', id, className);
        if (text !== undefined) {
            elLabel.appendChild(document.createTextNode(text));
        }
        if (htmlFor !== undefined) { elLabel.htmlFor = htmlFor; }
        return elLabel;
    };
    /**
     * Creates a 'TextArea' Html element.
     * @param {number|string} [cols] - The number of columns
     * @param {number|string} [maxlength] The maximum number of characters
     * @param {string} [text] - The value of the <code>text</code> attribute (content initially shown in the field)
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {string} [id] - The value of the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'textarea' HTML element
     */
    var createTextArea = function(cols, maxlength, text, className, id) {
        var elTextArea = createEl('TEXTAREA', id, className);
        if (cols != undefined) { elTextArea.cols = cols; }
        if (maxlength !== undefined) { elTextArea.maxlength = maxlength; }
        if (text !== undefined) { elTextArea.value = text; }
        return elTextArea;
    };
    /**
     * Sorts options of a html 'select' element by a certain property of the option (e.g. text or value).
     * @param {HTMLElement} elSelect - The Select Element to be sorted
     * @param {string} [propertyName=text] - The Name of the property by wich the option should be compared like <code>value</code> or <code>text</code>.
     * @param {boolean} [isOrderDescending] - <code>true</code> to reverse the sort order.
     */
    var sortSelectBy = function (elSelect, propertyName, isOrderDescending) {
        propertyName = propertyName || 'text';
        var sortOptions = [];
        // options to array
        for (var i = 0; i <= elSelect.length - 1; i++) {
            var option = elSelect[i];
            sortOptions.push({
                value:option.value,
                text:option.text,
                selected:option.selected
            });
        }
        // sort array
        sortOptions.sort(function (a, b) {
            if (a[propertyName] < b[propertyName]) { return  isOrderDescending ? 1 : -1; }
            if (a[propertyName] > b[propertyName]) { return isOrderDescending ? -1 : 1; }
            return 0;
        });
        // array to options
        sortOptions.forEach(function (opt, i) {
            elSelect[i].text = opt.text;
            elSelect[i].value = opt.value;
            elSelect[i].selected = opt.selected;
        });
    };
    /**
     * Creates an 'Option' HTML element which can be added to a HTML select element.
     * @param text The value of the <code>text</code> attribute shown in the select dropdown
     * @param value THe value of the <code>value</code> attribute
     * @returns {HTMLOptionElement}
     */
    var createOption = function (text, value) {
        var elOption = document.createElement('OPTION');
        elOption.text = text;
        elOption.value = value;
        return elOption;
    };
    /**
     * Creates a 'Select' Html element without options.
     * @param {string} [className] - The value for the <code>class</code> attribute
     * @param {string} [id] - The value of the <code>id</code> attribute
     * @returns {ElType|HTMLElement} The 'Select' HTML element
     */
    var createSelect = function (className, id) {
        var elSelect = new createEl('SELECT', id, className);
        elSelect.addNewOption = function(text, value) {
            var elOption = document.createElement('OPTION');
            elOption.text = text;
            elOption.value = value;
            elSelect.add(elOption);
            return elOption;
        };
        /**
         * Sorts options of this select alphabetically by the values of their <code>text</code> attribute.
         * @param {boolean} [isOrderDesc] - <code>true</code> to sort options by descending order
         */
        elSelect.sortOptionsByText = function (isOrderDesc) {
            sortSelectBy(elSelect, 'text', isOrderDesc);
        };
        /**
         * Sorts options of this select alphabetically by the values of their <code>value</code> attribute.
         * @param {boolean} [isOrderDesc] - <code>true</code> to sort options by descending order
         */
        elSelect.sortOptionsByValue = function (isOrderDesc) {
            sortSelectBy(elSelect, 'value', isOrderDesc);
        };
        return elSelect;
    };
    return {
        newEl : createEl,
        newDiv : createDiv,
        newButton : createButton,
        newInput : createInput,
        newLabel : createLabel,
        newTextArea : createTextArea,
        newOption : createOption,
        newSelect : createSelect
    }
}();


var Page = function() {
    /**
     * Returns the value of a query parameter of the URI.
     * @param {string} paramName - The key (name) to identify the query parameter
     * @returns {string|null} The value of the paremeter or <code>null</code> if the uri doesn't define that parameter.
     */
    var getUriQueryParamValue = function(paramName) {
        return decodeURIComponent((new RegExp('[?|&]' + paramName + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null;
    };

    /**
     * Sets or updates a query parameter in the URI. The Page will be reloaded with the new uri.
     * @param {string} paramName - The key (name) to identify the query parameter
     * @param {string} paramValue - The new or updated value of the query parameter
     */
    var setUriQueryParam = function(paramName, paramValue) {
        var uri = window.location.href;
        var re = new RegExp("([?&])" + paramName + "=.*?(&|$)", "i");
        var separator = uri.indexOf('?') !== -1 ? "&" : "?";
        if (uri.match(re)) {
            uri = uri.replace(re, '$1' + paramName + "=" + paramValue + '$2');
        }
        else {
            uri = uri + separator + paramName + "=" + paramValue;
        }
        window.location.href = uri;
    };
    return {
        uri : {
            getQueryParamValue : getUriQueryParamValue,
            setQueryParamValue : setUriQueryParam
        }
    };
}();