Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

PHPで出力するDOMをJSで自動オブジェクト化

More than 5 years have passed since last update.

PHP, JS, HTML の連携

PHPとJSを行き来するのめんどくさい…となっていた時に試してみた方法をメモ。

index.php
<script type="text/javascript">
/**
 * DOMと紐付けるオブジェクト。
 * @param[in] name 紐付けに使う名前。ID、クラス名で使用される。
 */
Object = function(name) {
        this._name = name;
        this._root = document.getElementById(name);

        this._root.getElementsByTagName('p')[0].textContent = name;
};

Object.prototype.getName = function() {
        return this._name;
};
</script>

<?php
/**
 * DOMを出力し、JSとの紐付けを行う。
 * @param[in] $name 紐付けに使う名前。
 */
function render_object($name) {
?>
<div id="<?php echo $name; ?>" class="<?php echo $name; ?>">
        <p>content</p>
</div>
<script type="text/javascript">
/// JSをインライン展開して紐付けを行う。
(function() {
        var obj = new Object('<?php echo $name; ?>');
        console.log(obj.getName());
}());
</script>
<?php
}

/// 開発者が再利用するコード。
$number = 0;
render_object("object_" . $number++);
render_object("object_" . $number++);

?>

結果のHTML.

result
<script type="text/javascript">
Object = function(name) {
    this._name = name;
    this._root = document.getElementById(name);

    this._root.getElementsByTagName('p')[0].textContent = name;
};

Object.prototype.getName = function() {
    return this._name;
};
</script>

<div id="object_0" class="object_0">
    <p>content</p>
</div>
<script type="text/javascript">
(function() {
    var obj = new Object('object_0');
    console.log(obj.getName());
}());
</script>
<div id="object_1" class="object_1">
    <p>content</p>
</div>
<script type="text/javascript">
(function() {
    var obj = new Object('object_1');
    console.log(obj.getName());
}());
</script>

結果のJSコンソール.

result
"object_0" index.php:20:1
"object_1" index.php:29:1

クラス化してカウンターを作る

UI.php に関してはクラス化する必要があるのかまだ謎。
関数で足りる気もする。サーバー/クライアントサイドでオブジェクト分 new してる。
あと名前の共有も両サイドで必要。PHPに関しては名前の管理者も必要。
それから JS で getElementById() 使ってるから走査する分時間もかかってそう。

index.php
<script type="text/javascript" src="ui.js"></script>

<?php
require_once(dirname(__FILE__) . '/UI.php');


/// TODO: You should be created Class for name
$prefix_name = 'counter_widget';
$suffix_number = 0;


$counter_0 = new UI\Counter($prefix_name . '_' . $suffix_number++);
$counter_1 = new UI\Counter($prefix_name . '_' . $suffix_number++);

$counter_0->render();
$counter_1->render();


?>

UI.php
<?php
namespace UI;


/**
 * UI\Counter
 * @see ui.js
 */
class Counter {
        private $_name;

        function __construct($name) {
                $this->_name = $name;
        }

        /**
         * render html and associate by inline JS
         */
        public function render() {
        ?>
                <div id="<?php echo $this->_name; ?>" class="<?php echo $this->_name; ?>">
                        <div class="display">display</div>
                        <input class="button" type="button" value="click me" />
                </div>

                <script type="text/javascript">
                (function() {
                        var counter = new UI.Counter('<?php echo $this->_name; ?>');
                        counter.build();
                }());
                </script>
        <?php
        }
}


?>

ui.js
/// namespace
UI = {};

/**
 * UI.Counter
 *
 * @param[in] name widget name string
 */
UI.Counter = function(name) {
        this._name = name;
        this._root = document.getElementById(name);
        if (this._root == null) {
                console.error('not found name "' + name + '"');
                return;
        }
        this._counter = 0;
};

/**
 * build logic with root node
 */
UI.Counter.prototype.build = function() {
        var self = this;  /// alias for this

        var display = self._root.getElementsByClassName('display')[0];
        var button = self._root.getElementsByClassName('button')[0];

        button.addEventListener('click', function() {
                display.textContent = self._counter++;
        });
};

result
sample.gif

narupo
個人Web開発者。C, Python3, JavaScript, Django などが好き。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away