drupal中如何设置JS一次执行

本文深入解析Drupal中的JavaScript API实现方式,包括核心文件drupal.js的内容介绍及Drupal.js对象的使用方法。文章阐述了如何通过Drupal.settings传递PHP到JavaScript的数据、Drupal.behaviors的应用场景及其在Drupal 6与Drupal 7中的不同实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5. The Drupal JavaScript API


Last updated October 27, 2015. Created on September 5, 2008.
Edited by milodescNickWildenod_digitaldonkeyLog in to edit this page.

See JavaScript API in Drupal 8 if developing for Drupal 8.

This page is a description of how JavaScript is implemented in Drupal, including an in-depth look at the drupal.js file and in particular the Drupal js object initialized therein.

Note: The following examples are lacking JSDoc, only for clarity.

The very first line of JavaScript code in Drupal core, in drupal.js, is an Object declaration:

var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} };

In this code, Drupal is an Object declared to be equal to itself, or, if not yet set, equal to { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} } which is an Object containing 4 properties (settingsbehaviorsthemes, and locale) each of which is itself an Object. This line of code is an Object Initializer. This Drupal object and its properties can then be used and extended by other modules. The best way to understand this is to look at the different properties one by one and the ways they are used by Drupal modules.

Jump to a section:
Drupal.settings
Drupal.behaviors
Drupal.theme
Drupal.locale

Drupal.settings

Drupal.settings is what enables us to pass information from our PHP code to our JavaScript code. This means you can change how your JavaScript behaves based on your module. For example, you may want to simply let JavaScript know what the base path is. In order to do this, you just create a PHP array of settings, as follows:

$my_settings = array(
  'basePath' => $base_path,
  'animationEffect' => variable_get('effect', 'none')
 );

Note: The array keys are set using CamelCasing according to the JavaScript coding standards.
@see: https://drupal.org/node/172169#camelcasing

Then call drupal_add_js() and pass in this array, with "setting" as your second parameter:

drupal_add_js(array('myModule' => $my_settings), 'setting');

(Drupal 8 deprecates drupal_add_js; refer to Attaching Configurable JavaScript in Drupal 8 for the D8 way to pass values from PHP to JavaScript.)

Note that it is further padded inside another array purely for namespacing purposes: another module might define the basePath setting as well. Now you can access these settings in your JavaScript code as follows:

var basePath = Drupal.settings.myModule.basePath;
var effect = Drupal.settings.myModule.animationEffect;

These are strings, but not string objects in JavaScript. The value of the array key you pass into drupal_add_js() will be concatenated to the end of this string separated by a comma.

NoteDrupal 7 passes the settings locally

Drupal.behaviors

When most of us learn jQuery for the first time, we learn to put all our code inside the $(document).ready() function, like this:

$(document).ready(function () {
  // Do some fancy stuff.
});

This ensures that our code will get run as soon as the DOM has loaded, manipulating elements and binding behaviors to events as per our instructions. However, as of Drupal 6, we don't need to include the $(document).ready() function in our jQuery code at all. Instead we put all our code inside a function that we assign as a property of Drupal.behaviors. The Drupal.behaviors object is itself a property of the Drupal object, as explained above, and when we want our module to add new jQuery behaviors, we simply extend this object. The entire jQuery code for your module could be structured like this:

Drupal 6.x:

Drupal.behaviors.myModuleBehavior = function (context) {
  //Do some fancy stuff
};

Drupal 7.x:

Drupal.behaviors.myModuleBehavior = {
  attach: function (context, settings) {
    $('input.myCustomBehavior', context).once('myCustomBehavior', function () {
      // Apply the myCustomBehaviour effect to the elements only once.
    });
  }
};

@see: https://www.drupal.org/update/modules/6/7#jquery_once

Any function defined as a property of Drupal.behaviors will get called when the DOM has loaded. drupal.js has a $(document).ready() function which calls theDrupal.attachBehaviors() function, which in turn cycles through the Drupal.behaviorsobject calling every one of its properties, these all being functions declared by various modules as above, and passing in the document as the context.

The reason for doing it this way is that if your jQuery code makes AJAX calls which result in new DOM elements being added to the page, you might want your behaviors (e.g. hiding all h3 elements or whatever) to be attached to that new content as well. But since it didn't exist when the DOM was loaded and Drupal.attachBehaviors() ran, it doesn't have any behaviors attached. With the above set-up, though, all you need to do is call Drupal.behaviors.myModuleBehavior(newcontext), where newcontext would be the new, AJAX-delivered content, thus ensuring that the behaviors don't get attached to the whole document all over again. There are full instructions on how to use this code on theConverting 5.x modules to 6.x or Converting 6.x modules to 7.x page.

This usage is not in fact exclusive to Drupal 6: the jstools package in Drupal 5 used this exact pattern to control the behaviors of its modules: collapsiblock, tabs, jscalendar, etc.

Drupal.behaviors practical example

The following is a more practical example. Drupal Behaviors are fired whenever attachBehaviors is called. The context variable that is passed in can often give you a better idea of what DOM element is being processed, but it is not a sure way to know if you are processing something again. Passing the context variable as the second argument to the jQuery selector is a good practice because then only the given context is searched and not the entire document. This becomes more important when attaching behaviors after an AJAX request. The following is an example of a Drupal.behavior that ensures that processing only happens once per DOM object.

Drupal 6.x:

Drupal.behaviors.myModuleBehavior = function (context) {
  // This jQuery code ensures that this element
  // is only processed once.  It is basically saying:
  // 1) Find all elements with this class, that do not
  // have the processed class on it
  // 2) Iterate through them 
  // 3) Add the processed class (so that it will not
  // be processed again).
  $('.module-class-object:not(.module-class-processed)', context).each(function () {
    $(this).addClass('module-class-processed');
      // Do things.
  });
};

A real-live example is that in the OpenLayers module which uses this basic process to ensure that maps are only created once. It also utilizes Drupal behaviors to add parts and react to events.

Drupal 7.x:

Drupal.behaviors.myModuleBehavior = {
  attach: function (context, settings) {
    // This jQuery code ensures that this element
    // is only processed once.  It is basically saying:
    // 1) Find all elements with this class, that do not
    // have the processed class on it
    // 2) Iterate through them 
    // 3) Add the myCustomBehavior-processed class (so that it will not
    // be processed again).
    $('input.myCustomBehavior', context).once('myCustomBehavior', function () {
      // Apply the myCustomBehaviour effect to the elements only once.
    });
  }
};

Note: The above example of the Drupal 7 version is just a rewrite of the D6 example here presented and may not represent the current version of the OpenLayers module code.

Note: Your included JS file needs to have the function($) prototype definition which is not mentioned above! So my WHOLE file would look like

(function ($) {
  Drupal.behaviors.myModuleBehavior = {
    attach: function (context, settings) {
     $('input.myCustomBehavior', context).once('myCustomBehavior', function () {
      // Apply the myCustomBehaviour effect to the elements only once.
    });
    }
  };
})(jQuery);
(function ($) {
  Drupal.behaviors.sample_barcode_print = {
    attach: function (context, settings) {
	$('input#edit-print',context).once('edit-print',function(){
		
		
		document.getElementById('edit-print').οnclick=function(){
			
			if (!!window.ActiveXObject || "ActiveXObject" in window){
			
				var data=Drupal.settings.sample_barcode_print.testdata;
				barcode=new Object();
				barcode.X=16;
				barcode.samplenoY=28;
				barcode.stylenoY=60;
				barcode.typeY=84;
				barcode.seasonY=108;
				barcode.customY=132;
				barcode.divisionY=156;
				barcode.colorY=180;
				barcode.sizeY=204;
				barcode.dateY=228;
				barcode.barcodeX=40;
				barcode.barcodeY=264;
				barcode.smapleno="样板单号:";
				barcode.styleno="款 号 : ";
				barcode.type="类 型 : ";
				barcode.season="季 度 : ";
				barcode.custom="客 户 : ";
				barcode.division="Division:";
				barcode.color="颜 色 : ";
				barcode.size="尺 寸 : ";
				barcode.date="日 期 : ";
				barcode.barcode="00000000000";
				barcode.smapleno1="样板单号:";
				barcode.styleno1="款 号 : ";
				barcode.type1="类 型 : ";
				barcode.season1="季 度 : ";
				barcode.custom1="客 户 : ";
				barcode.division1="Division:";
				barcode.color1="颜 色 : ";
				barcode.size1="尺 寸 : ";
				barcode.date1="日 期 : ";
				barcode.barcode1="00000000000";
		
				postionx=85;
			
				for(var key in data){
			
					if ( key % 2 ==0)
					{
				
						barcode.smapleno+=data[key][0];
						barcode.styleno+=data[key][1];
						barcode.type+=data[key][2];
						barcode.season+=data[key][4];
						barcode.custom+=data[key][5];
						barcode.division+=data[key][6];
						barcode.color+=data[key][7];
						barcode.size+=data[key][8];
						barcode.date+=data[key][3];
						barcode.barcode=data[key][9];
						if (key==data.length) {samplebarcodeprint(barcode,postionx);}
					}
					else{
				
						barcode.smapleno1+=data[key][0];
						barcode.styleno1+=data[key][1];
						barcode.type1+=data[key][2];
						barcode.season1+=data[key][4];
						barcode.custom1+=data[key][5];
						barcode.division1+=data[key][6];
						barcode.color1+=data[key][7];
						barcode.size1+=data[key][8];
						barcode.date1+=data[key][3];
						barcode.barcode1=data[key][9];
				
						samplebarcodeprint(barcode,postionx);
				
						barcode.smapleno="样板单号:";
						barcode.styleno="款 号 : ";
						barcode.type="类 型 : ";
						barcode.season="季 度 : ";
						barcode.custom="客 户 : ";
						barcode.division="Division:";
						barcode.color="颜 色 : ";
						barcode.size="尺 寸 : ";
						barcode.date="日 期 : ";
						barcode.barcode="00000000000";
						barcode.smapleno1="样板单号:";
						barcode.styleno1="款 号 : ";
						barcode.type1="类 型 : ";
						barcode.season1="季 度 : ";
						barcode.custom1="客 户 : ";
						barcode.division1="Division:";
						barcode.color1="颜 色 : ";
						barcode.size1="尺 寸 : ";
						barcode.date1="日 期 : ";
						barcode.barcode1="00000000000";
								
					}	//单双页结束
				}//for end		
		
			} //if IE end 
			else{
				alert('Support IE Only');
			}
		document.getElementById('edit-print').disabled=true;
			
		}
		function samplebarcodeprint(mybarcode,postionX){
			OpenPrinter();	
			PSKPrn.PTKSetCoordinateOrigin(5,5);
			PSKPrn.PTKPcxGraphicsDel("*")
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.samplenoY, 24, 0, "宋体", 1, 560, false, false, false, "A1", mybarcode.smapleno);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.stylenoY, 24, 0, "宋体", 1, 560, false, false, false, "A2", mybarcode.styleno);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.typeY, 22, 0, "宋体", 1, 500, false, false, false, "A3", mybarcode.type);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.seasonY, 22, 0, "宋体", 1, 500, false, false, false, "A4", mybarcode.season);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.customY, 22, 0, "宋体", 1, 500, false, false, false, "A5", mybarcode.custom);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.divisionY, 22, 0, "宋体", 1, 500, false, false, false, "A6", mybarcode.division);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.colorY, 22, 0, "宋体", 1, 500, false, false, false, "A7", mybarcode.color);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.sizeY, 22, 0, "宋体", 1, 500, false, false, false, "A8", mybarcode.size);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.dateY, 22, 0, "宋体", 1, 500, false, false, false, "A9", mybarcode.date);
			PSKPrn.PTKDrawBarcode(mybarcode.barcodeX+postionX, mybarcode.barcodeY, 0, '1', 2, 2, 90, 66, mybarcode.barcode);	//N的ASCII码是78,B的ASCII码是66
			postionX+=360;
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.samplenoY, 24, 0, "宋体", 1, 560, false, false, false, "A10", mybarcode.smapleno1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.stylenoY, 24, 0, "宋体", 1, 560, false, false, false, "A11", mybarcode.styleno1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.typeY, 22, 0, "宋体", 1, 500, false, false, false, "A12", mybarcode.type1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.seasonY, 22, 0, "宋体", 1, 500, false, false, false, "A13", mybarcode.season1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.customY, 22, 0, "宋体", 1, 500, false, false, false, "A14", mybarcode.custom1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.divisionY, 22, 0, "宋体", 1, 500, false, false, false, "A15", mybarcode.division1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.colorY, 22, 0, "宋体", 1, 500, false, false, false, "A16", mybarcode.color1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.sizeY, 22, 0, "宋体", 1, 500, false, false, false, "A17", mybarcode.size1);
			PSKPrn.PTKDrawTextTrueTypeW(mybarcode.X+postionX, mybarcode.dateY, 22, 0, "宋体", 1, 500, false, false, false, "A18", mybarcode.date1);
			PSKPrn.PTKDrawBarcode(mybarcode.barcodeX+postionX, mybarcode.barcodeY, 0, '1', 2, 2, 90, 66, mybarcode.barcode1);
			PSKPrn.PTKPrintLabel(1, 1);
			ClosePrinter();
		}
	
		function OpenPrinter()
		{
			//这里可以调用控件的已知方法
			PSKPrn.OpenPort("POSTEK C168/200s");
			PSKPrn.PTKClearBuffer();
			PSKPrn.PTKSetPrintSpeed(4);
			PSKPrn.PTKSetDarkness(10);
			PSKPrn.PTKSetLabelHeight(400, 16, 0, 0);
			PSKPrn.PTKSetLabelWidth(720);
			PSKPrn.PTKSetDirection(84);	
		}
		function ClosePrinter()
		{
			PSKPrn.ClosePort();
		}
		});
	}
  };

}(jQuery));

function sample_barcode_printing($form,&$form_state){
		$views=views_get_view("view_sample_tracert");
		$views->preview("block_2");
		$results=$views->result;
		//dpm($views);		
		$data=array();		
		$row=0;
		
		foreach($results as $key){
					$node=node_load($key->nid);				
					$data[$row][0]=$key->node_field_data_field_sampletracert_title;
					$data[$row][1]=$key->field_field_warehousestyleno[0]['raw']['value'];
					$data[$row][2]=$key->field_field_sample_type[0]['raw']['value'];
					$data[$row][3]=$key->field_field_datetime[0]['raw']['value'];
					$data[$row][4]=$key->field_field_season[0]['raw']['value'];
					$data[$row][5]=$key->field_field_brand[0]['rendered']['#markup'];
					$data[$row][6]=$key->field_field_division[0]['raw']['value'];
					$data[$row][7]=$key->field_field_color[0]['raw']['value'];
					$data[$row][8]=$key->field_field_size[0]['raw']['value'];
					$data[$row][9]=$key->field_field_barcode_code[0]['raw']['value'];				
					$node->field_printtag['und'][0]['value']='1';
					$row++;
					node_save($node);	
			}		
		$views=null;
		$results=null;
		$views=views_get_view("view_sample_tracert");
		$views->preview("block_3");
		$results=$views->result;
		$barcodenum='0';
		foreach ($results as $key)
		{
			$barcodenum=$key->nid;
		}				
		//$data 已准备好传向打印控件。		
		drupal_add_js(array('sample_barcode_print'=>array('testdata'=>$data),),'setting');
		
		
		
		
	return $form['showexcel'];		
 }
function sample_barcode_print_init()
{
	$forie = array(
			'#type' => 'markup',
			'#markup' => '
							<object id="PSKPrn" classid="clsid:81C07687-3353-4ABA-B108-94BCE81E5CBA" codebase="PSKPrn.ocx" width="0"  height="0" ></object>
							<script language="javascript" for="PSKPrn" event="ocxEvent()"></script>
							
							',
		);
		drupal_add_html_head($forie, 'sample_barcode_print');
		drupal_add_js(drupal_get_path('module','sample_barcode_print').'/sample_barcode_print.js','file');
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值